MFF

    Minecraft Forge France
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes
    • Forge Events
      • Automatique
      • Foncé
      • Clair
    • S'inscrire
    • Se connecter

    La fonction Container#transfertStackInSlot

    Planifier Épinglé Verrouillé Déplacé Les interfaces (GUI) et les container
    1.11.x
    1 Messages 1 Publieurs 1.3k Vues 1 Watching
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • BrokenSwingB Hors-ligne
      BrokenSwing Moddeurs confirmés Rédacteurs
      dernière édition par robin4002

      Sommaire

      • Introduction
      • Pré-requis
      • Code
        • La fonction mergeItemStack
        • La fonction transferStackInSlot
      • Crédits

      Introduction

      Aujourd’hui nous allons nous intéresser à la fonction Container#transferStackInSlot(EntityPlayer, int). Cette fonction est appelée lorsque le joueur effectue un shift-clic sur un slot, et c’est dans cette fonction que l’on doit déplacer le contenu du slot vers le slot que l’on juge approprié. C’est grâce à cette fonction que vous pouvez facilement déplacer vos objets de votre inventaire vers un coffre par exemple. Cependant l’implémentation de base de cette fonction n’a aucun effet, le shift-click est “désactivé”.

      Pré-requis

      • Connaitre le fonctionnement d’un ItemStack
      • Connaitre le fonctionnement d’un Container
      • Connaitre le fonctionnement d’un Slot

      Code

      La fonction mergeItemStack

      Avons de commencer nous allons voir le fonctionnement de la fonction Container#mergeItemStack que nous allons utiliser pour déplacer les ItemStack dans les Slot que l’on veut. Je vais seulement expliquer ce qu’elle fait (vous pouvez toujours regarder les sources si vous voulez), cette fonction essaie de déplacer un ItemStack dans les slots spécifiés (on les indiques grâce à l’ID avec lequel ils ont été ajouté) et nous retourne ensuite vrai si l’ItemStack a été complètement ou partiellement déplacé.
      Intéressons-nous à son prototype :

          boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection)
      

      L’ItemStack est celui que nous voulons déplacer, startIndex est l’Id du premier slot Slot, endIndex est l’Id du dernier Slot et reverseDirection permet d’inverser la direction, vous allez comprendre de suite ce tout cela veux dire. Imaginons que j’ai un ItemStack que je veuille déplacer dans un autre inventaire, et que cet inventaire a 3 Slots, si j’invoque :

          this.mergeItemStack(stack, 0, 3, false);
      

      Alors la fonction va tenté de mettre stack dans le slot 0, si il a réussi il renvoie vrai sinon il passe au slot 1, de la même façon si il a réussi il renvoie vrai sinon il passe au slot 2, si là il n’a toujours pas réussi alors il renvoie faux. Vous avez sûrement remarqué que lorsque que l’on indique startIndex et endIndex, startIndex est inclu tandis que endIndex est exclu. On a donc [ startIndex ; endIndex [. Si on met reverseDirection à vrai alors il tentera de mettre l’ItemStack dans le slot 2 puis 1 puis 0.
      Attention, si la fonction renvoie faux, cela veux dire que l’ItemStack n’a pas du tout été déplacé.
      Note : cette fonction va en priorité fusionner les ItemStacks.

      La fonction transferStackInSlot

      Comme vous l’aurez compris lorsque le joueur va shift-click sur un Slot, en fonction de son Id nous allons répartir le contenue du Slot entre tels ou tels Slots. Voyons le prototype de la fonction :

      ItemStack transferStackInSlot(EntityPlayer player, int index)
      

      On a donc le joueur et l’index du Slot, on peux récupéré l’instance du Slot grâce à son Id :

          @Override
          public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
              Slot slot = this.inventorySlots.get(index);
          }
      

      Puis on va vérifier qu’il y a bien quelque chose dans le Slot sinon ça ne sert à rien de continuer (on vérifie aussi si il n’est pas null car l’index donné peut être mauvais) :

          @Override
          public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
              Slot slot = this.inventorySlots.get(index);
              if(slot != null && slot.getHasStack()) {
      
              }
          }
      

      Avant de continuer je vais vous parler de la valeur de retour, vous devez retourner un ItemStack, si vous retournez un ItemStack vide cela veux dire que rien n’a changé, que l’ItemStack se trouvant dans le slot shift-cliqué n’a pas été modifié, sinon il faut retourner le contenu du slot tel qu’il était AVANT le shift-click.

      Nous allons donc préparer notre valeur de retour :

          @Override
          public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
              ItemStack stackToReturn = ItemStack.EMPTY;
              Slot slot = this.inventorySlots.get(index);
      
              if (slot != null && slot.getHasStack()) {
                  ItemStack stack = slot.getStack();
                  stackToReturn = stack.copy();
              }
      
              return stackToReturn;
          }
      

      On utilise ItemStack#copy car lors de l’utilisation de Container#mergeItemStack notre ItemStack va être modifié et nous voulons pouvoir retourner l’ItemStack tel qu’il était avant modification. Pour la suite le même schéma va se répéter, suivant l’index donné on va essayer de placer l’ItemStack à un certain endroit, si Container#mergeItemStack renvoie faux, alors rien n’a changé et on retourne ItemStack#EMPTY. Imaginons un coffre qui a 10 slots et nous voulons faire passer l’ItemStack du l’inventaire du coffre à celui du joueur. Je vais condidérer que les slots du coffre ont les ids [[ 0 ; 9 ]] et ceux de l’inventaire du joueur ont les ids [[ 10 ; 45 ]]. Ainsi :
      Note : je rappelle que l’index de fin est exclu.

      
          @Override
          public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
              ItemStack stackToReturn = ItemStack.EMPTY;
              Slot slot = this.inventorySlots.get(index);
      
              if (slot != null && slot.getHasStack()) {
                  ItemStack stack = slot.getStack();
                  stackToReturn = stack.copy();
      
                  if (index < 10) {
                      // On inverse pour remplir la hotbar en premier
                      if (!this.mergeItemStack(stack, 10, 46, true)) {
                          return ItemStack.EMPTY;
                      }
                  }
      
              }
      
              return stackToReturn;
          }
      

      On met bien de 10 à 46 car les ids des Slots de l’inventaire du joueur vont de 10 à 45, et on inverse pour que la fonction essai d’abord de remplir la hotbar. Mais le code n’est pas terminé, que ce passe-t-il actuellement si l’ItemStack a été déplacé ? On renvoie sa valeur de départ, donc c’est bon mais il faut quand même dire au slot que son contenu a changé et si l’ItemStack a complètement été déplacé il faut mettre ItemStack#EMPTY dans le slot. Ainsi :

      
          @Override
          public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
              ItemStack stackToReturn = ItemStack.EMPTY;
              Slot slot = this.inventorySlots.get(index);
      
              if (slot != null && slot.getHasStack()) {
                  ItemStack stack = slot.getStack();
                  stackToReturn = stack.copy();
      
                  if (index < 10) {
                      if (!this.mergeItemStack(stack, 10, 46, true)) {
                          return ItemStack.EMPTY;
                      }
                  }
      
                  // Si il a été complètement déplacé on met ItemStack#EMPTY dans le
                  // slot
                  if (stack.isEmpty()) {
                      slot.putStack(ItemStack.EMPTY);
                  }
                  // Sinon on signale que le contenu a changé.
                  // Slot#putStack appelle Slot#onSlotChanged c'est pourquoi on ne le
                  // fait pas ci-dessus
                  else {
                      slot.onSlotChanged();
                  }
      
              }
      
              return stackToReturn;
          }
      

      Et voilà, on va juste finir on rajoutant le chemin inverse, c’est à dire de l’inventaire du joueur vers le coffre :

      
          @Override
          public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
              ItemStack stackToReturn = ItemStack.EMPTY;
              Slot slot = this.inventorySlots.get(index);
      
              if (slot != null && slot.getHasStack()) {
                  ItemStack stack = slot.getStack();
                  stackToReturn = stack.copy();
      
                  if (index < 10) {
                      if (!this.mergeItemStack(stack, 10, 46, true)) {
                          return ItemStack.EMPTY;
                      }
                  } else if (!this.mergeItemStack(stack, 0, 10, false)) {
                      return ItemStack.EMPTY;
                  }
      
                  if (stack.isEmpty()) {
                      slot.putStack(ItemStack.EMPTY);
                  } else {
                      slot.onSlotChanged();
                  }
      
              }
              return stackToReturn;
          }
      

      Vous savez maintenant créer une fonction qui gère le shift-click et qui fonctionne. Il vous suffit de bien réfléchir quel comportement l’ItemStack doit avoir lors du shift-click et coder on conséquence.

      Crédits

      Rédaction :

      • BrokenSwing

      Ce tutoriel de BrokenSwing publié sur Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

      Retour vers le sommaire des tutoriels

      1 réponse Dernière réponse Répondre Citer 0
      • 1 / 1
      • Premier message
        Dernier message
      Design by Woryk
      ContactMentions Légales

      MINECRAFT FORGE FRANCE © 2024

      Powered by NodeBB