Init
This commit is contained in:
430
content/world/entities/inventory/transactions.fr.md
Normal file
430
content/world/entities/inventory/transactions.fr.md
Normal file
@@ -0,0 +1,430 @@
|
||||
---
|
||||
title: Transactions
|
||||
type: docs
|
||||
weight: 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` :
|
||||
|
||||
```java
|
||||
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 :
|
||||
|
||||
```java
|
||||
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 :
|
||||
|
||||
```java
|
||||
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 :
|
||||
|
||||
```java
|
||||
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 :
|
||||
|
||||
```java
|
||||
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 :
|
||||
|
||||
```java
|
||||
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 :
|
||||
|
||||
```java
|
||||
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 :
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
```java
|
||||
// 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
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
```java
|
||||
// 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
|
||||
|
||||
```java
|
||||
// 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` |
|
||||
|
||||
```java
|
||||
// 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 >}}
|
||||
|
||||
```java
|
||||
// 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<T extends Transaction>
|
||||
|
||||
| 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<T extends Transaction>
|
||||
|
||||
| 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 |
|
||||
Reference in New Issue
Block a user