• S'inscrire
    • Se connecter
    • Recherche
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes

    Créer une structure multiblocks

    Les blocs
    1.8
    6
    7
    4525
    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.
    • BrokenSwing
      BrokenSwing Moddeurs confirmés Rédacteurs dernière édition par robin4002

      Sommaire

      • Introduction
      • Pré-requis
      • Code
        • La classe principale
        • La classe du bloc
        • La classe du TileEntity
      • Bonus
      • Résultat

      Introduction

      Nous allons voir comment créer une structure multi-block.
      Tout d’abord qu’est ce qu’une structure multi-block ? C’est un ensemble de bloc qui une fois disposés
      correctement, forment un ensemble.

      Pré-requis

      • Créer un bloc basique
      • Ajouter un TileEntity au bloc

      Code

      La classe principale :

      Déclarez votre bloc dans votre classe principale, pour ce tutoriel il s’appellera multiBlockTuto

          public static Block multiBlockTuto;
      

      Puis instanciez-le et enregistrez-le dans la fonction preInit

          multiBlockTuto = new BlockMultiBlockTuto();
          GameRegistry.registerBlock(multiBlockTuto, "multiblocktuto");
      

      Créez la classe BlockMultiBlockTuto.

      La classe du bloc :

      La classe du bloc devrait être extends Block, si ce n’est pas le cas, faites-le.
      Implémentez ensuite l’interface ITileEntityProvider

          public class BlockMultiBlockTuto extends Block implements ITileEntityProvider
      

      Définissez le constructeur comme pour un bloc normal.

      On ajoute maintenant la fonction permettant de créer le TileEntity

          @Override
          public TileEntity createNewTileEntity(World worldIn, int meta) {
              return new TileEntityMultiBlockTuto();
          }
      

      Créez la classe TileEntityMultiBlockTuto.

      La classe du TileEntity

      La structure que nous allons créer est une structure de 1 de hauteur, 3 de largeur, 3 de longueur,
      ce qui nous fait une structure composée de 331 = 9 blocs.

      Le concept sera le suivant, dans toute la structure il y aura un bloc qui sera,
      dit ‘master’ et les autres ne feront que vérifier que ce block existe. C’est dans ce master
      que toute les informations que vous voudrez enregistrer dans la structure devront se trouver.

      Chaque bloc, quelqu’il soit, aura 5 variables qui définira sont état :

      • Est-t-il oui ou non master (1 variable)
      • As-t-il oui ou non un master (1 variable)
      • Quels sont les coordonnées du master (3 variables x, y, z)
        Ainsi on déclare chaque variable et on les enregistres dans les NBT
          private boolean hasMaster = false;
          private boolean isMaster = false;
          private int masterX = 0;
          private int masterY = 0;
          private int masterZ = 0;
      
          @Override
          public void readFromNBT(NBTTagCompound compound)
          {
              super.readFromNBT(compound);
              this.hasMaster = compound.getBoolean("HasMaster");
              this.isMaster = compound.getBoolean("IsMaster");
              this.masterX = compound.getInteger("MasterX");
              this.masterY = compound.getInteger("MasterY");
              this.masterZ = compound.getInteger("MasterZ");
          }
      
          @Override
          public void writeToNBT(NBTTagCompound compound)
          {
              super.writeToNBT(compound);
              compound.setBoolean("HasMaster", hasMaster);
              compound.setBoolean("IsMaster", isMaster);
              compound.setInteger("MasterX", masterX);
              compound.setInteger("MasterY", masterY);
              compound.setInteger("MasterZ", masterZ);
          }
      

      Suite à ça ajoutons directement les getter et setter

          public boolean hasMaster()
          {
              return this.hasMaster;
          }
      
          public boolean isMaster()
          {
              return this.isMaster;
          }
      
          public int getMasterX()
          {
              return this.masterX;
          }
      
          public int getMasterY()
          {
              return this.masterY;
          }
      
          public int getMasterZ()
          {
              return this.masterZ;
          }
      
          public void setMaster(int x, int y, int z)
          {
              this.hasMaster = true;
              this.masterX = x;
              this.masterY = y;
              this.masterZ = z;
          }
      

      Nous allons maintenant créer une fonction afin de vérifier la présense
      d’une structure, chaque bloc va essayer de créer une structure dans il est
      master tant qu’il ne sera ou n’aura pas de master.
      Pour vérifier la structure on va se baser sur le bloc du milieux de notre
      carré de 3 par 3.

      private boolean checkStructure()
      {
          int n = 0;
          for(int x = this.pos.getX() - 1; x < this.pos.getX() + 2; x++)
          {
              for(int z = this.pos.getZ() - 1; z < this.pos.getZ() + 2; z++)
              {
                  BlockPos position = new BlockPos(x, this.pos.getY(), z);
                  TileEntity tile = worldObj.getTileEntity(position);
                  if(tile != null && tile instanceof TileEntityMultiBlockTuto)
                  {
                      TileEntityMultiBlockTuto t = (TileEntityMultiBlockTuto)tile;
                      if(t.hasMaster)
                      {
                          if(this.pos.getX() == t.getMasterX() && this.pos.getY() == t.getMasterY() && this.pos.getZ() == t.getMasterZ())
                          {
                              n++;
                          }
                      }
                      else
                      {
                          n++;
                      }
                  }
              }
          }
      
          if(n == 9)
          {
              return true;
          }
          return false;
      }
      

      On compte le nombre de bloc qui n’ont pas de master ou qui ont pour master le bloc qui check.
      Si il est égal à 9, le nombre de bloc dans la structure alors c’est bon, dans ce cas on met
      en place la structure en indiquant à chaque bloc la place du master et le fait qu’il ai un master.

      private void setupStructure()
      {
          for(int x = this.pos.getX() - 1; x < this.pos.getX() + 2; x++)
          {
              for(int z = this.pos.getZ() - 1; z < this.pos.getZ() + 2; z++)
              {
                  BlockPos position = new BlockPos(x, this.pos.getY(), z);
                  TileEntity tile = worldObj.getTileEntity(position);
                  if(tile != null && tile instanceof TileEntityMultiBlockTuto)
                  {
                      TileEntityMultiBlockTuto t = (TileEntityMultiBlockTuto)tile;
                      t.setMaster(this.pos.getX(), this.pos.getY(), this.pos.getZ());
                      this.isMaster = true;
                  }
              }
          }
      }
      

      Vous verrez que une fois la structure faite nous allons re-vérifier son intégrité, dans le cas
      où elle n’est plus correcte, il va falloir indiquer à chaque bloc que c’est fini, il n’y a plus
      de structure.
      Il faut donc une fonction qui reset la structure, qui sera exécutée par le master et une qui reset
      juste le bloc qui sera appelée dans la boucle pour reset la structure.

      private void resetStructure()
      {
          for(int x = this.pos.getX() - 1; x < this.pos.getX() + 2; x++)
          {
              for(int z = this.pos.getZ() - 1; z < this.pos.getZ() + 2; z++)
              {
                  BlockPos position = new BlockPos(x, this.pos.getY(), z);
                  TileEntity tile = worldObj.getTileEntity(position);
                  if(tile != null && tile instanceof TileEntityMultiBlockTuto)
                  {
                      TileEntityMultiBlockTuto t = (TileEntityMultiBlockTuto)tile;
                      t.reset();
                  }
              }
          }
      }
      
      public void reset()
      {
          this.isMaster = false;
          this.hasMaster = false;
          this.masterX = 0;
          this.masterY = 0;
          this.masterZ = 0;
      }
      

      Dans le cas où le master est détruit, il ne pourra pas reset la structure, il faut alors que chaque
      bloc vérifie si le master existe encore

      private boolean checkForMaster()
      {
          BlockPos position = new BlockPos(masterX, masterY, masterZ);
          TileEntity tile = worldObj.getTileEntity(position);
          if(tile != null && tile instanceof TileEntityMultiBlockTuto)
          {
              TileEntityMultiBlockTuto t = (TileEntityMultiBlockTuto)tile;
              if(t.isMaster())
              {
                  return true;
              }
          }
          return false;
      }
      

      Les deux fonctions concernant les packets

      @Override
      public Packet getDescriptionPacket()
      {
          NBTTagCompound nbttagcompound = new NBTTagCompound();
          this.writeToNBT(nbttagcompound);
          return new S35PacketUpdateTileEntity(this.getPos(), this.getBlockMetadata(), nbttagcompound);
      }
      
      @Override
      public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt)
      {
          this.readFromNBT(pkt.getNbtCompound());
          this.worldObj.markBlockRangeForRenderUpdate(this.pos, this.pos);
      }
      

      Implémentez la classe de l’interface IUpdatePlayerListBox
      La fonction update est appellée à chaque update du bloc, on y appeler nos fonctions,
      mais réfléchissons à la façon dont nous allons nous y prendre.

      public void update() {}
      

      Tout d’abord si le bloc est un master il va devoir vérifier la structure,
      si elle n’est plus correcte alors on la reset

      if(this.isMaster)
          {
              if(!this.checkStructure())
              {
                  this.resetStructure();
              }
          }
      

      Sinon si il a un master, on doit vérifier si sont master est encore là,
      sinon on reset le bloc

      else if(this.hasMaster)
      {
          if(!checkForMaster())
          {
              this.reset();
          }
      }
      

      Sinon si il n’a pas de master alors il doit il va essayer de créer une structure

      else if(!this.hasMaster)
      {
          if(this.checkStructure())
          {
              this.setupStructure();
          }
      }
      

      La situation de notre bloc a changé, on le signal.

      this.markDirty();
      

      Voilà, tout fonctionne, les autres variables que vous voudriez enregistrer doivent êtres enregistrer dans le master
      seulement, mettez donc une condition dans les fonctions read et write et n’oubliez pas de reset les variables
      dans la fonction reset.

      Bonus

      Une idée ?

      Résultat

      Pour une plus grande clartée j’ai ajouté des blocstates, chaque situation
      à sa propre couleur, rouge si le bloc ne fait pas partie d’une structure,
      rose si il fait partie d’une structure mais qu’il n’est pas master, et
      jaune si il est master.

      0_1529311139345_multiblock-action.png

      1 réponse Dernière réponse Répondre Citer 0
      • SCAREX
        SCAREX dernière édition par

        Tutoriel intéressant mais quelques problèmes dans le code : dans ta fonction checkStructure et setupStructure, d’où sort le “pos” ? Si c’est une variable de la TileEntity, mets un this.pos sinon on peut difficilement comprendre.

        De plus, à quoi sert le “else if (!t.hasMaster)” ? Un simple else suffit :

        if(t.hasMaster)
        {
        if(pos.getX() == t.getMasterX() && pos.getY() == t.getMasterY() && pos.getZ() == t.getMasterZ())
        {
        n++;
        }
        }
        else if(!t.hasMaster)
        {
        n++;
        }
        

        Site web contenant mes scripts : http://SCAREXgaming.github.io

        Pas de demandes de support par MP ni par skype SVP.
        Je n'accepte sur skype que l…

        1 réponse Dernière réponse Répondre Citer 0
        • BrokenSwing
          BrokenSwing Moddeurs confirmés Rédacteurs dernière édition par

          Efectivement pos est une variable de la classe TileEntity, je mettrai le this (le week-end prochain) et pour le else if pareil, c’est vrai qu’il ne sert à rien

          EDIT : mis à jour

          1 réponse Dernière réponse Répondre Citer 0
          • Folgansky
            Folgansky Correcteurs dernière édition par

            Salut les gens, juste pour savoir, ce tuto marche-t-il aussi en 1.7.10?
            Des fonctions que j’ai pu voir logiquement oui, mais je ne suis pas certain.

            1 réponse Dernière réponse Répondre Citer 0
            • robin4002
              robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

              Il faut adapter les blocs pos par x, y z et les block state par les metadata et normalement c’est bon.

              1 réponse Dernière réponse Répondre Citer 0
              • TheXrayFR
                TheXrayFR dernière édition par

                pour l’ider tu pourrai four une structure mais avec un gui et fait une machine ?

                1 réponse Dernière réponse Répondre Citer 0
                • JustAnDev
                  JustAnDev dernière édition par

                  comment on fait pour faire une condition ex jene veux que mon block de base ne fasse rien et que mon multiblock,si il y a dde l’orage imprimer dans le chat il u a l’orage(je sais il faut un

                  System.out.println("c'est orageux")
                  

                  )mais quand meme

                  s

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

                  MINECRAFT FORGE FRANCE © 2018

                  Powered by NodeBB