--- title: ItemStacks type: docs weight: 1 --- ItemStack représente une pile d'objets dans Hytale avec quantité, durabilité et métadonnées. ## Créer des ItemStacks Les ItemStacks sont créés en utilisant des constructeurs avec un ID d'objet : ```java // Créer par ID d'objet ItemStack sword = new ItemStack("iron_sword"); // Créer avec quantité ItemStack materials = new ItemStack("wood_plank", 64); // Créer avec quantité et métadonnées BsonDocument metadata = new BsonDocument(); ItemStack customItem = new ItemStack("iron_sword", 1, metadata); // Créer avec tous les paramètres (durabilité) ItemStack damagedSword = new ItemStack("iron_sword", 1, 50.0, 100.0, null); // Paramètres: itemId, quantity, durability, maxDurability, metadata ``` ## Propriétés d'ItemStack ```java ItemStack stack = new ItemStack("iron_sword", 1); // Obtenir l'ID de l'objet String itemId = stack.getItemId(); // "iron_sword" // Obtenir l'asset Item Item item = stack.getItem(); // Obtenir la quantité (PAS getCount!) int quantity = stack.getQuantity(); // Vérifier si vide boolean empty = stack.isEmpty(); // Vérifier la validité boolean valid = stack.isValid(); // Durabilité double durability = stack.getDurability(); double maxDurability = stack.getMaxDurability(); boolean unbreakable = stack.isUnbreakable(); // true si maxDurability <= 0 boolean broken = stack.isBroken(); // true si durability == 0 ``` ## Modifier les ItemStacks ItemStack utilise un pattern `with*` qui retourne de NOUVELLES instances : ```java ItemStack stack = new ItemStack("iron_sword", 1); // Changer la quantité - retourne un NOUVEL ItemStack ou null si quantité est 0 ItemStack moreItems = stack.withQuantity(32); // Changer la durabilité ItemStack damaged = stack.withDurability(50.0); // Augmenter la durabilité ItemStack repaired = stack.withIncreasedDurability(25.0); // Restaurer la durabilité complète ItemStack fullyRepaired = stack.withRestoredDurability(100.0); // Changer la durabilité max ItemStack stronger = stack.withMaxDurability(200.0); // Changer l'état (pour les objets avec états) ItemStack newState = stack.withState("activated"); // Ajouter/modifier les métadonnées ItemStack withMeta = stack.withMetadata(metadataDocument); // Ajouter une valeur de métadonnée spécifique ItemStack tagged = stack.withMetadata("CustomKey", Codec.STRING, "CustomValue"); ``` {{< callout type="warning" >}} **Important :** `withQuantity(0)` retourne `null`, pas un ItemStack vide. Vérifiez toujours null quand vous diminuez la quantité ! {{< /callout >}} ## La Constante EMPTY Utilisez `ItemStack.EMPTY` pour les piles vides : ```java // Instance vide statique (singleton) ItemStack empty = ItemStack.EMPTY; // Vérifier si vide if (stack.isEmpty()) { // La pile est vide } // Méthode helper statique if (ItemStack.isEmpty(stack)) { // Gère les piles null et vides } ``` ## Comparer les ItemStacks ```java ItemStack a = new ItemStack("iron_sword", 1); ItemStack b = new ItemStack("iron_sword", 5); ItemStack c = new ItemStack("diamond_sword", 1); // Vérifier si empilables (même itemId, durability, maxDurability ET metadata) // Note: Des quantités différentes peuvent s'empiler, mais les durabilités doivent correspondre exactement boolean canStack = a.isStackableWith(b); // Vérifier type équivalent (même itemId et metadata, ignore les durabilités) boolean sameType = a.isEquivalentType(b); // Vérifier même type d'objet seulement (juste itemId) boolean sameItem = ItemStack.isSameItemType(a, c); // false // Helpers statiques (gèrent les nulls en sécurité) ItemStack.isStackableWith(a, b); ItemStack.isEquivalentType(a, b); ``` ## Travailler avec les Métadonnées ItemStack supporte les métadonnées BSON pour les données personnalisées : ```java // Créer un codec de métadonnée KeyedCodec OWNER_KEY = new KeyedCodec<>("Owner", Codec.STRING); // Ajouter des métadonnées ItemStack withOwner = stack.withMetadata(OWNER_KEY, "PlayerName"); // Lire les métadonnées String owner = stack.getFromMetadataOrNull(OWNER_KEY); // Lire avec clé et codec Integer level = stack.getFromMetadataOrNull("Level", Codec.INTEGER); // Lire avec défaut depuis BuilderCodec MyData data = stack.getFromMetadataOrDefault("Data", MyData.CODEC); ``` ## Objets de Bloc Vérifier si un objet peut être placé comme bloc : ```java ItemStack stack = new ItemStack("stone", 1); // Obtenir la clé de bloc associée (null si pas un objet de bloc) String blockKey = stack.getBlockKey(); if (blockKey != null) { // Cet objet peut être placé comme bloc } // Vérifier via l'asset Item Item item = stack.getItem(); if (item.hasBlockType()) { String blockId = item.getBlockId(); } ``` ## Patterns Courants ### Consommer des Objets ```java public ItemStack consumeOne(ItemStack stack) { if (stack == null || stack.isEmpty()) { return null; } int newQuantity = stack.getQuantity() - 1; // withQuantity retourne null si quantité est 0 return stack.withQuantity(newQuantity); } // Utilisation avec conteneur public void useItem(ItemContainer container, short slot) { ItemStack current = container.getItemStack(slot); ItemStack remaining = consumeOne(current); // remaining peut être null si la pile est épuisée container.setItemStackForSlot(slot, remaining); } ``` ### Vérifier le Type d'Objet ```java public boolean isHoldingSword(ItemStack hand) { if (hand == null || hand.isEmpty()) { return false; } // Vérifier le type d'objet par ID return hand.getItemId().contains("sword"); // Ou vérifier via l'asset Item // return hand.getItem().getCategory().equals("weapon"); } ``` ### Diviser des Piles ```java 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 }; } // Créer deux piles ItemStack remaining = stack.withQuantity(currentQuantity - splitAmount); ItemStack split = stack.withQuantity(splitAmount); return new ItemStack[] { remaining, split }; } ``` ### Fusionner des Piles ```java public ItemStack[] mergeStacks(ItemStack target, ItemStack source) { if (!target.isStackableWith(source)) { return new ItemStack[] { target, source }; // Ne peut pas fusionner } int maxStack = target.getItem().getMaxStack(); int totalQuantity = target.getQuantity() + source.getQuantity(); if (totalQuantity <= maxStack) { // Fusion complète return new ItemStack[] { target.withQuantity(totalQuantity), null }; } // Fusion partielle return new ItemStack[] { target.withQuantity(maxStack), source.withQuantity(totalQuantity - maxStack) }; } ``` ## Bonnes Pratiques {{< callout type="info" >}} **Rappelez-vous :** - Utilisez `getQuantity()` pas `getCount()` - Hytale utilise "quantity" - `withQuantity(0)` retourne `null` - vérifiez cela ! - Utilisez `ItemStack.isEmpty(stack)` pour gérer null et vide - Les ItemStacks sont principalement immuables - les méthodes `with*` retournent de nouvelles instances - Utilisez `isStackableWith()` avant de tenter de fusionner des piles - `ResourceType.Id` ne doit pas être null lors de la création d'objets via codecs {{< /callout >}} ```java // Bon : Gérer null de withQuantity ItemStack result = stack.withQuantity(newQuantity); if (result == null) { // Pile épuisée, gérer appropriément } // Bon : Vérification vide sécurisée if (ItemStack.isEmpty(stack)) { // Gère à la fois null et ItemStack.EMPTY vide } // Mauvais : Ignorer la valeur retournée stack.withQuantity(10); // Retourne nouvelle pile, original inchangé ! ``` ## Référence API ItemStack ### Méthodes d'Instance | Méthode | Retour | Description | |--------|---------|-------------| | `getItemId()` | `String` | L'identifiant du type d'objet | | `getItem()` | `Item` | L'asset Item (retourne `Item.UNKNOWN` si non trouvé) | | `getQuantity()` | `int` | Taille de la pile | | `getDurability()` | `double` | Durabilité actuelle | | `getMaxDurability()` | `double` | Durabilité maximum | | `isEmpty()` | `boolean` | True si itemId égale "Empty" | | `isUnbreakable()` | `boolean` | True si maxDurability <= 0 | | `isBroken()` | `boolean` | True si PAS incassable ET durability == 0 | | `isValid()` | `boolean` | True si vide OU l'asset existe | | `isStackableWith(ItemStack)` | `boolean` | Même itemId, durability, maxDurability, metadata | | `isEquivalentType(ItemStack)` | `boolean` | Même itemId et metadata (ignore durabilité) | | `getBlockKey()` | `String?` | ID bloc si plaçable, null sinon | | `getOverrideDroppedItemAnimation()` | `boolean` | Flag d'override animation | | `getMetadata()` | `BsonDocument?` | **Déprécié** - Retourne metadata clonée | | `getFromMetadataOrNull(KeyedCodec)` | `T?` | Obtenir valeur metadata typée | | `getFromMetadataOrNull(String, Codec)` | `T?` | Obtenir metadata par clé | | `getFromMetadataOrDefault(String, BuilderCodec)` | `T` | Obtenir metadata avec défaut | ### Méthodes de Modification (retournent nouveau ItemStack) | Méthode | Retour | Description | |--------|---------|-------------| | `withQuantity(int)` | `ItemStack?` | **Retourne null si quantité est 0** | | `withDurability(double)` | `ItemStack` | Borné à [0, maxDurability] | | `withMaxDurability(double)` | `ItemStack` | Borne aussi la durabilité actuelle | | `withIncreasedDurability(double)` | `ItemStack` | Ajoute à la durabilité | | `withRestoredDurability(double)` | `ItemStack` | Définit durabilité et max | | `withState(String)` | `ItemStack` | Change l'état de l'objet | | `withMetadata(BsonDocument)` | `ItemStack` | Remplace toutes les metadata | | `withMetadata(KeyedCodec, T)` | `ItemStack` | Définit metadata typée | | `withMetadata(String, Codec, T)` | `ItemStack` | Définit metadata par clé | | `withMetadata(String, BsonValue)` | `ItemStack` | Définit valeur BSON brute | | `setOverrideDroppedItemAnimation(boolean)` | `void` | **Mute en place** | ### Champs Statiques | Champ | Type | Description | |-------|------|-------------| | `EMPTY` | `ItemStack` | Pile vide singleton (itemId = "Empty") | | `EMPTY_ARRAY` | `ItemStack[]` | Constante tableau vide | | `CODEC` | `BuilderCodec` | Codec de sérialisation | ### Méthodes Statiques | Méthode | Retour | Description | |--------|---------|-------------| | `isEmpty(ItemStack)` | `boolean` | Vérification vide null-safe | | `isStackableWith(ItemStack, ItemStack)` | `boolean` | Vérification empilable null-safe | | `isEquivalentType(ItemStack, ItemStack)` | `boolean` | Vérification type null-safe | | `isSameItemType(ItemStack, ItemStack)` | `boolean` | Compare itemId seulement | | `fromPacket(ItemQuantity)` | `ItemStack?` | Créer depuis paquet réseau | ### Classes Imbriquées | Classe | Description | |-------|-------------| | `ItemStack.Metadata` | Contient constante `BLOCK_STATE` pour clé metadata état bloc |