Files
Documentation/content/world/entities/inventory/transactions.fr.md
2026-01-20 20:33:59 +01:00

13 KiB

title, type, weight
title type weight
Transactions docs 3

Les transactions suivent les résultats des opérations d'inventaire dans Hytale. Chaque modification d'un ItemContainer retourne un objet Transaction qui décrit ce qui s'est passé.

Interface Transaction

Toutes les transactions implémentent l'interface de base Transaction :

public interface Transaction {
    // L'opération a-t-elle réussi ?
    boolean succeeded();

    // Un slot spécifique a-t-il été modifié ?
    boolean wasSlotModified(short slot);
}

Types de Transactions

SlotTransaction

Suit les changements d'un seul slot :

SlotTransaction transaction = container.removeItemStackFromSlot((short) 0);

if (transaction.succeeded()) {
    // Ce qui était dans le slot avant
    ItemStack before = transaction.getSlotBefore();

    // Ce qui est dans le slot maintenant
    ItemStack after = transaction.getSlotAfter();

    // L'objet qui a été retiré/sorti
    ItemStack output = transaction.getOutput();

    // Quel slot a été affecté
    short slot = transaction.getSlot();

    // Quel type d'action (ADD, REMOVE, REPLACE)
    ActionType action = transaction.getAction();
}

ItemStackSlotTransaction

Transaction de slot étendue avec des détails supplémentaires :

ItemStackSlotTransaction transaction = container.setItemStackForSlot(
    (short) 0,
    new ItemStack("iron_sword", 1)
);

if (transaction.succeeded()) {
    short slot = transaction.getSlot();
    ItemStack before = transaction.getSlotBefore();
    ItemStack after = transaction.getSlotAfter();

    // Vérifier les options utilisées
    boolean wasFiltered = transaction.isFilter();
    boolean wasAllOrNothing = transaction.isAllOrNothing();
}

ItemStackTransaction

Suit les opérations qui peuvent affecter plusieurs slots :

ItemStack toAdd = new ItemStack("stone", 128);
ItemStackTransaction transaction = container.addItemStack(toAdd);

if (transaction.succeeded()) {
    // Objets qui n'ont pas pu rentrer (null si tous ont rentré)
    ItemStack remainder = transaction.getRemainder();

    // Objet original qu'on a essayé d'ajouter
    ItemStack query = transaction.getQuery();

    // Liste de toutes les transactions de slot qui ont eu lieu
    List<ItemStackSlotTransaction> slotTransactions = transaction.getSlotTransactions();

    for (ItemStackSlotTransaction slotTx : slotTransactions) {
        getLogger().at(Level.INFO).log("Slot modifié " + slotTx.getSlot());
    }
}

MoveTransaction

Suit le déplacement d'objets entre conteneurs :

MoveTransaction<SlotTransaction> transaction = storage.moveItemStackFromSlotToSlot(
    (short) 0,
    32,
    hotbar,
    (short) 0
);

if (transaction.succeeded()) {
    // Transaction pour le retrait de la source
    SlotTransaction removeTransaction = transaction.getRemoveTransaction();

    // Transaction pour l'ajout à la destination
    SlotTransaction addTransaction = transaction.getAddTransaction();

    // Le conteneur de destination
    ItemContainer destination = transaction.getOtherContainer();

    // Direction du déplacement
    MoveType moveType = transaction.getMoveType();
}

ListTransaction

Encapsule plusieurs transactions :

List<ItemStack> items = List.of(
    new ItemStack("stone", 64),
    new ItemStack("wood", 64)
);

ListTransaction<ItemStackTransaction> transaction = container.addItemStacks(items);

if (transaction.succeeded()) {
    List<ItemStackTransaction> results = transaction.getList();

    for (ItemStackTransaction result : results) {
        if (result.succeeded()) {
            ItemStack remainder = result.getRemainder();
            // ...
        }
    }
}

ActionType

Les opérations sont catégorisées par type d'action :

public enum ActionType {
    SET,      // Objets définis (add=true, remove=false, destroy=true)
    ADD,      // Objets ajoutés au slot (add=true, remove=false, destroy=false)
    REMOVE,   // Objets retirés du slot (add=false, remove=true, destroy=false)
    REPLACE   // Contenu du slot remplacé (add=true, remove=true, destroy=false)
}

// Vérifier les caractéristiques de l'action
if (action.isAdd()) { /* opération ajoute des objets */ }
if (action.isRemove()) { /* opération retire des objets */ }
if (action.isDestroy()) { /* opération détruit le contenu du slot */ }

MoveType

Direction des opérations de déplacement :

public enum MoveType {
    MOVE_TO_SELF,   // Objets déplacés VERS ce conteneur
    MOVE_FROM_SELF  // Objets déplacés DEPUIS ce conteneur
}

Patterns Courants

Vérifier Avant de Modifier

// Pattern sûr : vérifier d'abord, puis exécuter
public boolean safeTransfer(ItemContainer from, ItemContainer to, String itemId, int amount) {
    ItemStack toRemove = new ItemStack(itemId, amount);

    // Vérifier que les deux opérations peuvent réussir
    if (!from.canRemoveItemStack(toRemove)) {
        return false;  // Pas assez d'objets
    }

    if (!to.canAddItemStack(toRemove)) {
        return false;  // Pas de place
    }

    // Exécuter le retrait
    ItemStackTransaction removeResult = from.removeItemStack(toRemove);
    if (!removeResult.succeeded()) {
        return false;
    }

    // Exécuter l'ajout
    ItemStack removed = removeResult.getQuery();
    ItemStackTransaction addResult = to.addItemStack(removed);

    // Gérer les restes éventuels
    ItemStack remainder = addResult.getRemainder();
    if (!ItemStack.isEmpty(remainder)) {
        // Remettre les restes
        from.addItemStack(remainder);
    }

    return true;
}

Gérer les Restes

public void giveItemSafe(Player player, String itemId, int quantity) {
    ItemContainer storage = player.getInventory().getStorage();
    ItemStack item = new ItemStack(itemId, quantity);

    ItemStackTransaction result = storage.addItemStack(item);

    if (!result.succeeded()) {
        player.sendMessage(Message.raw("Inventaire plein !"));
        return;
    }

    ItemStack remainder = result.getRemainder();
    if (!ItemStack.isEmpty(remainder)) {
        player.sendMessage(Message.raw(
            "Seulement reçu " + (quantity - remainder.getQuantity()) + " objets, " +
            "inventaire plein !"
        ));
    }
}

Opérations Atomiques

// allOrNothing=true garantit que les opérations partielles ne se produisent pas
public boolean buyItem(Player player, String itemId, int price, int quantity) {
    Inventory inv = player.getInventory();
    ItemContainer storage = inv.getStorage();

    ItemStack currency = new ItemStack("gold_coin", price);
    ItemStack item = new ItemStack(itemId, quantity);

    // Vérifier que les deux opérations peuvent réussir complètement
    if (!storage.canRemoveItemStack(currency)) {
        player.sendMessage(Message.raw("Pas assez d'or !"));
        return false;
    }

    if (!storage.canAddItemStack(item)) {
        player.sendMessage(Message.raw("Inventaire plein !"));
        return false;
    }

    // Retirer la monnaie avec allOrNothing=true
    ItemStackTransaction removeResult = storage.removeItemStack(currency, true, true);
    if (!removeResult.succeeded()) {
        return false;
    }

    // Ajouter l'objet
    ItemStackTransaction addResult = storage.addItemStack(item, true, false, true);
    if (!addResult.succeeded()) {
        // Annuler : rendre la monnaie
        storage.addItemStack(currency);
        return false;
    }

    return true;
}

Suivre les Changements

// Utiliser wasSlotModified pour vérifier des slots spécifiques
public void onContainerChange(ItemContainer.ItemContainerChangeEvent event) {
    Transaction transaction = event.transaction();

    // Vérifier si le slot 0 de la hotbar a été affecté
    if (transaction.wasSlotModified((short) 0)) {
        getLogger().at(Level.INFO).log("Premier slot modifié !");
    }

    // Vérifier tous les slots de la hotbar
    for (short i = 0; i < 9; i++) {
        if (transaction.wasSlotModified(i)) {
            getLogger().at(Level.INFO).log("Slot hotbar " + i + " modifié");
        }
    }
}

Options de Transaction

De nombreuses opérations acceptent des paramètres optionnels :

Paramètre Description Par défaut
allOrNothing Si vrai, l'opération échoue si tous les objets ne peuvent pas être traités false
fullStacks Si vrai, ajoute seulement aux slots vides (pas aux piles partielles) false
exactAmount Si vrai, doit retirer exactement la quantité demandée true
filter Si vrai, respecte les filtres de slot true
// Comportement par défaut
container.addItemStack(item);

// Avec options
container.addItemStack(item, true, false, true);  // allOrNothing, fullStacks, filter
container.removeItemStack(item, true, true);       // allOrNothing, filter

Bonnes Pratiques

{{< callout type="info" >}} Conseils pour les Transactions :

  • Toujours vérifier succeeded() avant d'accéder aux résultats
  • Gérer les restes lors de l'ajout d'objets
  • Utiliser canAddItemStack()/canRemoveItemStack() pour la pré-validation
  • Utiliser allOrNothing=true pour les opérations critiques
  • Vérifier wasSlotModified() pour suivre les changements de slots spécifiques {{< /callout >}}
// Bon : Vérifier le succès et gérer les restes
ItemStackTransaction tx = container.addItemStack(item);
if (tx.succeeded()) {
    ItemStack remainder = tx.getRemainder();
    if (!ItemStack.isEmpty(remainder)) {
        // Gérer les objets restants
    }
}

// Mauvais : Supposer le succès
container.addItemStack(item);  // Pourrait échouer silencieusement !

Référence API Transaction

Interface Transaction

Méthode Retour Description
succeeded() boolean True si l'opération a réussi
wasSlotModified(short) boolean True si le slot spécifique a été modifié

SlotTransaction

Méthode Retour Description
getSlot() short Index du slot affecté
getAction() ActionType Type d'action effectuée
getSlotBefore() ItemStack? Contenu avant l'opération
getSlotAfter() ItemStack? Contenu après l'opération
getOutput() ItemStack? Objets retirés/sortis
isAllOrNothing() boolean Paramètre allOrNothing utilisé
isExactAmount() boolean Paramètre exactAmount utilisé
isFilter() boolean Paramètre filter utilisé
Statique Type Description
FAILED_ADD SlotTransaction Transaction d'ajout échouée pré-construite

ItemStackSlotTransaction (étend SlotTransaction)

Méthode Retour Description
isAddToExistingSlot() boolean True si ajouté à une pile existante
getQuery() ItemStack? Objet original demandé
getRemainder() ItemStack? Objets qui n'ont pas pu rentrer

ItemStackTransaction

Méthode Retour Description
getAction() ActionType? Type d'action effectuée
getQuery() ItemStack? Objet original demandé
getRemainder() ItemStack? Objets qui n'ont pas pu rentrer
isAllOrNothing() boolean Paramètre allOrNothing utilisé
isFilter() boolean Paramètre filter utilisé
getSlotTransactions() List<ItemStackSlotTransaction> Toutes les transactions de slot
Statique Type Description
FAILED_ADD ItemStackTransaction Transaction d'ajout échouée pré-construite

MoveTransaction

Méthode Retour Description
getRemoveTransaction() SlotTransaction Transaction de retrait
getMoveType() MoveType Direction du déplacement
getOtherContainer() ItemContainer L'autre conteneur impliqué
getAddTransaction() T Transaction d'ajout
toInverted(ItemContainer) MoveTransaction<T> Créer vue inversée pour l'autre conteneur

ListTransaction

Méthode Retour Description
getList() List<T> Toutes les transactions de la liste
size() int Nombre de transactions
Statique Type Description
EMPTY_SUCCESSFUL_TRANSACTION ListTransaction<?> Succès vide pré-construit
EMPTY_FAILED_TRANSACTION ListTransaction<?> Échec vide pré-construit
getEmptyTransaction(boolean) ListTransaction<T> Obtenir succès/échec vide

Enum ActionType

Valeur isAdd isRemove isDestroy Description
SET true false true Définir le contenu du slot
ADD true false false Ajouter des objets au slot
REMOVE false true false Retirer des objets du slot
REPLACE true true false Remplacer le contenu du slot

Enum MoveType

Valeur Description
MOVE_TO_SELF Objets déplacés vers ce conteneur
MOVE_FROM_SELF Objets déplacés depuis ce conteneur