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

    Non résolu Table de Craft custom ! Passage en 1.12.2

    Support pour les moddeurs
    1.12.2
    1
    1
    119
    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.
    • A
      Aiko dernière édition par

      Bonjour à vous !
      J’aimerai demander votre aide… Récemment j’ai repris le dev sur forge en 1.12.2 et j’arrive au moment fatidique de la table de craft custom disons Malheureusement la doc suivi date de la 1.9 J’ai donc essayé de l’adapté pour la 1.12.2 mais c’est plus difficile que ce je pensais ce dont je suis certains c’est que j’ai fais un peu avec ce que j’avais et que des possible aberration ai été effectuer je men excuse d’avance :anxious_face_with_sweat:
      Je compte sur vous pour m’éclairé voici les class importante
      Container:

      public class ContainerForge extends Container {
          /** Largeur du craft */
          public static final int craftWidth = 4;
          /** Hauteur du craft */
          public static final int craftHeigth = 4;
      
          /** Inventaire contenant le craft */
          private final InventoryCrafting craftMatrix = new InventoryCrafting(this, craftWidth, craftHeigth);
          /** Inventaire contenant le résultat du craft */
          private final IInventory craftResult = new InventoryCraftResult();
      
          private final World worldObj;
          private final BlockPos pos;
      
          public ContainerForge(InventoryPlayer invPlayer, World world, BlockPos pos)
          {
              this.worldObj = world;
              this.pos = pos;
      
              //Ajout du slot pour le résultat
              this.addSlotToContainer(new ForgeSlotCrafting(invPlayer.player, craftMatrix, craftResult, 0, 141, 43));
      
              int startX = 8; //Position x ou les slots de craft commencent à être dessinés
              int startY = 7; //Position y ou les slots de craft commencent à être dessinés
              //Ajout des slots de craft
              for (int y = 0; y < craftHeigth; ++y)
              {
                  for(int x = 0; x < craftWidth; ++x)
                  {
                      this.addSlotToContainer(new Slot(craftMatrix, x + y * craftWidth, startX + x * 18, startY + y * 18));
                  }
              }
      
              startX = 8; //Position x ou les slots de l'inventaire commencent à être dessinés
              startY = 106; //Position y ou les slots de l'inventaire commencent à être dessinés
              //Ajout des slots de l'inventaire du joueur
              for (int y = 0; y < 3; ++y)
              {
                  for(int x = 0; x < 9; ++x)
                  {
                      this.addSlotToContainer(new Slot(invPlayer, x + y * 9 + 9, startX + x * 18, startY + y * 18));
                  }
              }
              startY = 164; //Position y ou les slots de la hotbar commencent à être dessinés
              //Ajout des slots de la hotbar
              for (int x = 0; x < 9; ++x)
              {
                  this.addSlotToContainer(new Slot(invPlayer, x, startX + x * 18, startY));
              }
          }
      
          /**
           * Appelé quand la matrice (les slots de craft) change
           */
          @Override
          public void onCraftMatrixChanged(IInventory iiventory)
          {
              //On met le résultat du craft dans le slot de résultat
              craftResult.setInventorySlotContents(0, ForgeCraftingManager.getInstance().findMatchingRecipe(craftMatrix, worldObj));
          }
      
          /**
           * Retourne true si le joueur peut interagir avec ce gui, en général on teste la distance par rapport au joueur dans cette fonction
           */
          @Override
          public boolean canInteractWith(EntityPlayer player)
          {
              return this.worldObj.getBlockState(this.pos).getBlock() != BlocksInit.FORGE ? false : player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
          }
      
          /**
           * Appelé quand le container est fermé
           */
          @Override
          public void onContainerClosed(EntityPlayer player)
          {
              super.onContainerClosed(player);
              if (!this.worldObj.isRemote) //Si on est sur le serveur, on loot les items à la fermeture du gui
              {
                  for (int i = 0; i < 9; ++i)
                  {
                      ItemStack itemstack = this.craftMatrix.removeStackFromSlot(i);
                      if (itemstack != null)
                      {
                          player.dropItem(itemstack, false);
                      }
                  }
              }
          }
      
          /**
           * Cette fonction est appelée lors du shift+clic (je vous conseille de la laisser comme tel, elle s'adaptera en fonction de la taille de votre craft)
           * EDIT 11/01/16 Le contenu de cette fonction a été modifié via notepad++ et n'a pas été testé, si vous avez un problème rapportez le moi
           */
          @Override
          public ItemStack transferStackInSlot(EntityPlayer player, int slotId)
          {
              ItemStack itemstack = null;
              Slot slot = this.inventorySlots.get(slotId);
      
              if (slot != null && slot.getHasStack())
              {
                  ItemStack itemstack1 = slot.getStack();
                  itemstack = itemstack1.copy();
      
                  int invStart = craftWidth * craftHeigth + 1;
                  int hotbarStart = invStart + 27;
                  if (slotId == 0)
                  {
                      if (!this.mergeItemStack(itemstack1, invStart, hotbarStart + 9, true))
                      {
                          return null;
                      }
                      slot.onSlotChange(itemstack1, itemstack);
                  }
                  else if (slotId >= invStart && slotId < invStart + 27)
                  {
                      if (!this.mergeItemStack(itemstack1, hotbarStart, hotbarStart + 9, false))
                      {
                          return null;
                      }
                  }
                  else if (slotId >= hotbarStart && slotId < hotbarStart + 9)
                  {
                      if (!this.mergeItemStack(itemstack1, invStart, invStart + 27, false))
                      {
                          return null;
                      }
                  }
                  else if (!this.mergeItemStack(itemstack1, invStart, hotbarStart + 9, false))
                  {
                      return null;
                  }
                  if (itemstack1.getCount() == 0)
                  {
                      slot.putStack((ItemStack)null);
                  }
                  else
                  {
                      slot.onSlotChanged();
                  }
                  if (itemstack1.getCount() == itemstack.getCount())
                  {
                      return null;
                  }
      
                  slot.onTake(player, itemstack1);
              }
              return itemstack;
          }
      
          /**
           * Appelé quand on double clic sur un slot :
           * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in
           * is null for the initial slot that was double-clicked.
           */
          public boolean canMergeSlot(ItemStack stack, Slot slotIn)
          {
              return slotIn.inventory != this.craftResult && super.canMergeSlot(stack, slotIn);
          }
      }
      

      CraftingManager:

      public class ForgeCraftingManager
      {
          private static final ForgeCraftingManager INSTANCE = new ForgeCraftingManager();
      
          public static ForgeCraftingManager getInstance()
          {
              return INSTANCE;
          }
      
          /** La liste des recettes */
          private final List<IRecipe> recipes = Lists.<IRecipe>newArrayList();
      
          private ForgeCraftingManager()
          {
              addRecipe(new ItemStack(Items.ARROW), "X", "X", "X", 'X', Items.APPLE);
          }
      
          /**
           * Adds a shaped recipe to the games recipe list.
           */
          public ForgeShapedRecipes addRecipe(ItemStack result, Object... recipeComponents)
          {
              String s = "";
              int i = 0;
              int j = 0;
              int k = 0;
              if( recipeComponents[i] instanceof String[] )
              {
                  String[] astring = (String[]) ((String[]) recipeComponents[i++]);
                  for ( int l = 0; l < astring.length; ++l )
                  {
                      String s2 = astring[l];
                      ++k;
                      j = s2.length();
                      s = s + s2;
                  }
              }
              else
              {
                  while ( recipeComponents[i] instanceof String )
                  {
                      String s1 = (String) recipeComponents[i++];
                      ++k;
                      j = s1.length();
                      s = s + s1;
                  }
              }
              Character character;
              Map<Character, Object> components = Maps.<Character, Object>newHashMap();
              Object in;
              for ( ; i < recipeComponents.length; i += 2 )
              {
                  in = recipeComponents[i + 1];
                  Object component = null;
                  character = (Character) recipeComponents[i];
                  if( in instanceof Item )
                  {
                      component = new ItemStack((Item) recipeComponents[i + 1]);
                  }
                  else if( in instanceof Block )
                  {
                      component = new ItemStack((Block) recipeComponents[i + 1], 1, 32767);
                  }
                  else if( in instanceof ItemStack )
                  {
                      component = (ItemStack) recipeComponents[i + 1];
                  }
                  else if( in instanceof String )
                  {
                      component = (String) in;
                  }
                  else
                  {
                      throw new IllegalArgumentException("Invalid shaped recipe: unknown type " + in.getClass().getName() + "!");
                  }
                  components.put(character, component);
              }
              Object[] aitemstack = new Object[j * k];
              char key;
              Object component;
              for ( int i1 = 0; i1 < j * k; ++i1 )
              {
                  key = s.charAt(i1);
                  if( components.containsKey(Character.valueOf(key)) )
                  {
                      component = components.get(Character.valueOf(key));
                      if( component instanceof ItemStack )
                      {
                          aitemstack[i1] = ((ItemStack) component).copy();
                      }
                      else
                      {
                          aitemstack[i1] = component;
                      }
                  }
                  else
                  {
                      aitemstack[i1] = null;
                  }
              }
              ForgeShapedRecipes shapedrecipes = new ForgeShapedRecipes(j, k, aitemstack, result);
              System.out.println(aitemstack);
              this.recipes.add(shapedrecipes);
              return shapedrecipes;
          }
      
      
          /**
           * Adds a shapeless crafting recipe to the the game.
           */
          public void addShapelessRecipe(ItemStack result, Object... recipeComponents)
          {
              List list = Lists.newArrayList();
              for (Object component : recipeComponents) //Pour chaque composant de la recette
              {
                  if (component instanceof ItemStack)
                  {
                      list.add(((ItemStack)component).copy());
                  }
                  else if (component instanceof Item)
                  {
                      list.add(new ItemStack((Item)component));
                  }
                  else if(component instanceof Block)
                  {
                      list.add(new ItemStack((Block)component));
                  }
                  else if(component instanceof String) //Pour l'ore dictionnary
                  {
                      list.add(component);
                  }
                  else throw new IllegalArgumentException("Invalid shapeless recipe: unknown type " + component.getClass().getName() + "!");
              }
              this.recipes.add(new ForgeShapelessRecipes(result, list));
          }
      
          /**
           * Adds an IRecipe to the list of crafting recipes.
           */
          public void addRecipe(IRecipe recipe)
          {
              this.recipes.add(recipe);
          }
      
          /**
           * Retourne le résultat de la recette ou null si il n'y en a aucun
           */
          @Nullable
          public ItemStack findMatchingRecipe(InventoryCrafting craftMatrix, World worldIn)
          {
              for (IRecipe irecipe : this.recipes) //Pour chaque recette
              {
                  if (irecipe.matches(craftMatrix, worldIn)) //Si elle correspond à la matrice actuelle
                  {
                      return irecipe.getCraftingResult(craftMatrix); //On donne son résultat
                  }
              }
              return null;
          }
      
          /**
           * Retourne les items retants après un craft
           */
          public NonNullList<ItemStack> getRemainingItems(InventoryCrafting craftMatrix, World worldIn)
          {
              for (IRecipe irecipe : this.recipes) //Pour chaque recette
              {
                  if (irecipe.matches(craftMatrix, worldIn)) //Si elle correspond à la matrice actuelle
                  {
                      return irecipe.getRemainingItems(craftMatrix); //On retourne les items restants
                  }
              }
              NonNullList<ItemStack> aitemstack = NonNullList.create();
              for (int i = 0; i < craftMatrix.getSizeInventory(); ++i)
              {
                  aitemstack.set(i, craftMatrix.getStackInSlot(i));
              }
              return aitemstack; //Si ça ne correspond à aucune recette, on retourne tous les items qui sont présents dans la matrice
          }
      
          public List<IRecipe> getRecipeList()
          {
              return this.recipes;
          }
      }
      

      SlotCrafting:

      public class ForgeSlotCrafting extends Slot {
          /** The craft matrix inventory linked to this result slot. */
          private final InventoryCrafting craftMatrix;
          /** The player that is using the GUI where this slot resides. */
          private final EntityPlayer thePlayer;
          /** The number of items that have been crafted so far. Gets passed to ItemStack.onCrafting before being reset. */
          private int amountCrafted;
      
          public ForgeSlotCrafting(EntityPlayer player, InventoryCrafting craftingInventory, IInventory inventoryIn, int slotIndex, int xPosition, int yPosition)
          {
              super(inventoryIn, slotIndex, xPosition, yPosition);
              this.thePlayer = player;
              this.craftMatrix = craftingInventory;
          }
      
          /**
           * Check if the stack is a valid item for this slot. Always true beside for the armor slots.
           */
          @Override
          public boolean isItemValid(@Nullable ItemStack stack)
          {
              return false;
          }
      
          /**
           * Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new
           * stack.
           */
          @Override
          public ItemStack decrStackSize(int amount)
          {
              if (this.getHasStack())
              {
                  this.amountCrafted += Math.min(amount, this.getStack().getCount());
              }
              return super.decrStackSize(amount);
          }
      
          /**
           * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood. Typically increases an
           * internal count then calls onCrafting(item).
           */
          @Override
          protected void onCrafting(ItemStack stack, int amount)
          {
              this.amountCrafted += amount;
              this.onCrafting(stack);
          }
      
          /**
           * Appelé quand on craft, permet de gérer les achievements
           */
          @Override
          protected void onCrafting(ItemStack stack)
          {
              if (this.amountCrafted > 0)
              {
                  stack.onCrafting(this.thePlayer.world, this.thePlayer, this.amountCrafted);
              }
              this.amountCrafted = 0;
          }
      
          /**
           * Appelée quand le joueur retire l'item du slot, permet de retirer le composants utilisés pour le craft
           */
          @Override
          public ItemStack onTake(EntityPlayer playerIn, ItemStack stack)
          {
              FMLCommonHandler.instance().firePlayerCraftingEvent(playerIn, stack, craftMatrix); //Distribue l'event de craft
              this.onCrafting(stack); //Gestion des achievements
              ForgeHooks.setCraftingPlayer(playerIn); //Utilisé afin de retirer les items utiliser (pas sur de cela)
              NonNullList<ItemStack> aitemstack = ForgeCraftingManager.getInstance().getRemainingItems(this.craftMatrix, playerIn.world); //On récupère les items restants
              ForgeHooks.setCraftingPlayer(null);
      
              for (int i = 0; i < aitemstack.size(); ++i) //On actualise les slots de craft
              {
                  ItemStack itemstack = this.craftMatrix.getStackInSlot(i);
                  ItemStack itemstack1 = aitemstack.get(i);
      
                  if (!itemstack.isEmpty())
                  {
                      this.craftMatrix.decrStackSize(i, 1);
                      itemstack = this.craftMatrix.getStackInSlot(i);
                  }
      
                  if (!itemstack1.isEmpty())
                  {
                      if (itemstack.isEmpty())
                      {
                          this.craftMatrix.setInventorySlotContents(i, itemstack1);
                      }
                      else if (ItemStack.areItemsEqual(itemstack, itemstack1) && ItemStack.areItemStackTagsEqual(itemstack, itemstack1))
                      {
                          itemstack1.grow(itemstack.getCount());
                          this.craftMatrix.setInventorySlotContents(i, itemstack1);
                      }
                      else if (!this.thePlayer.inventory.addItemStackToInventory(itemstack1))
                      {
                          this.thePlayer.dropItem(itemstack1, false);
                      }
                  }
              }
              return stack;
          }
      }
      

      ShapedRecipes:

      public class ForgeShapedRecipes implements IRecipe {
          /** How many horizontal slots this recipe is wide. */
          public final int recipeWidth;
          /** How many vertical slots this recipe uses. */
          public final int recipeHeight;
          /** Is a array of ItemStack that composes the recipe. */
          public final Object[] recipeItems;
          /** Is the ItemStack that you get when craft the recipe. */
          private final ItemStack recipeOutput;
          private boolean copyIngredientNBT;
      
          public ForgeShapedRecipes(int width, int height, Object[] items, ItemStack output)
          {
              this.recipeWidth = width;
              this.recipeHeight = height;
              this.recipeItems = items;
              this.recipeOutput = output;
          }
      
          public ItemStack getRecipeOutput()
          {
              return this.recipeOutput;
          }
      
          public NonNullList<ItemStack> getRemainingItems(InventoryCrafting inv)
          {
              ItemStack[] aitemstack = new ItemStack[inv.getSizeInventory()];
              for (int i = 0; i < aitemstack.length; ++i)
              {
                  ItemStack itemstack = inv.getStackInSlot(i);
                  aitemstack[i] = net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack);
              }
              return null;
          }
      
          /**
           * Used to check if a recipe matches current crafting inventory
           * Retourne true si la recette correspond à la matrice donnée (le craft que le joueur a fait)
           */
          public boolean matches(InventoryCrafting inv, World worldIn)
          {
              for (int i = 0; i <= inv.getWidth() - this.recipeWidth; ++i)
              {
                  for (int j = 0; j <= inv.getHeight() - this.recipeHeight; ++j)
                  {
                      if (this.checkMatch(inv, i, j, true))
                      {
                          return true;
                      }
                      if (this.checkMatch(inv, i, j, false))
                      {
                          return true;
                      }
                  }
              }
              return false;
          }
      
          /**
           * Checks if the region of a crafting inventory is match for the recipe.
           * Compare deux parties du craft
           */
          private boolean checkMatch(InventoryCrafting inv, int regionX, int regionY, boolean mirror)
          {
              for (int x = 0 ; x < inv.getWidth() ; ++x)
              {
                  for (int y = 0 ; y < inv.getHeight() ; ++y)
                  {
                      int x1 = x - regionX;
                      int y1 = y - regionY;
                      Object patternStack = null;
                      if (x1 >= 0 && y1 >= 0 && x1 < this.recipeWidth && y1 < this.recipeHeight)
                      {
                          if (mirror)
                              patternStack = this.recipeItems[this.recipeWidth - x1 - 1 + y1 * this.recipeWidth];
                          else
                              patternStack = this.recipeItems[x1 + y1 * this.recipeWidth];
                          if(patternStack instanceof String)
                          {
                              List <ItemStack>stacks = OreDictionary.getOres((String) patternStack);
                              boolean matches = false;
                              for(ItemStack stack : stacks)
                              {
                                  if(areItemStacksEquals(stack, inv.getStackInRowAndColumn(x, y))) //If the pattern's stack doesn't match with the stack in the inv crafting
                                  {
                                      matches = true;
                                  }
                              }
                              if(!matches)
                                  return false;
                          }
                          else if(!areItemStacksEquals((ItemStack) patternStack, inv.getStackInRowAndColumn(x, y)))
                          {
                              return false;
                          }
                      }
                  }
              }
              return true;
          }
      
          /**
           * Compare les deux stacks
           */
          public static boolean areItemStacksEquals(ItemStack stack1, ItemStack stack2)
          {
              if(stack1 == null || stack2 == null) return stack1 == stack2;
              return stack1.getItem() == stack2.getItem() && (stack1.getMetadata() == OreDictionary.WILDCARD_VALUE || stack1.getMetadata() == stack2.getMetadata());
          }
      
          /**
           * Returns an Item that is the result of this recipe
           */
          public ItemStack getCraftingResult(InventoryCrafting inv)
          {
              ItemStack itemstack = this.getRecipeOutput().copy();
              if (this.copyIngredientNBT)
              {
                  for (int i = 0; i < inv.getSizeInventory(); ++i)
                  {
                      ItemStack itemstack1 = inv.getStackInSlot(i);
                      if (itemstack1 != null && itemstack1.hasTagCompound())
                      {
                          itemstack.setTagCompound((NBTTagCompound)itemstack1.getTagCompound().copy());
                      }
                  }
              }
              return itemstack;
          }
      
          @Override
          public boolean canFit(int width, int height) {
              return false;
          }
      
          /**
           * Returns the size of the recipe area
           */
          public int getRecipeSize()
          {
              return this.recipeWidth * this.recipeHeight;
          }
      
          /**
           * Set this crafting recipe to copy the NBT tag compound of the last ItemStack that has one in the crafting table.
           */
          public ForgeShapedRecipes setCopyIngredientNBT()
          {
              this.copyIngredientNBT = true;
              return this;
          }
      
          @Override
          public IRecipe setRegistryName(ResourceLocation name) {
              return null;
          }
      
          @Nullable
          @Override
          public ResourceLocation getRegistryName() {
              return null;
          }
      
          @Override
          public Class<IRecipe> getRegistryType() {
              return null;
          }
      }
      

      ShapelessRecipes:

      public class ForgeShapelessRecipes implements IRecipe {
          /** Is the ItemStack that you get when craft the recipe. */
          private final ItemStack recipeOutput;
          /** Is a List of ItemStack that composes the recipe. */
          public final List recipeItems;
      
          public ForgeShapelessRecipes(ItemStack output, List inputList)
          {
              this.recipeOutput = output;
              this.recipeItems = inputList;
          }
      
          public ItemStack getRecipeOutput()
          {
              return this.recipeOutput;
          }
      
          public NonNullList<ItemStack> getRemainingItems(InventoryCrafting inv)
          {
              ItemStack[] aitemstack = new ItemStack[inv.getSizeInventory()];
              for (int i = 0; i < aitemstack.length; ++i)
              {
                  ItemStack itemstack = inv.getStackInSlot(i);
                  aitemstack[i] = net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack);
              }
              return null;
          }
      
          /**
           * Used to check if a recipe matches current crafting inventory
           * Retourne true si la recette correspond à la matrice donnée (le craft que le joueur a fait)
           *
           * La fonction prend une liste des items requis pour le craft, puis pour chaque item rencontré dans la matrice, le retire de la liste des items,
           * si la liste ne contient pas l'item, c'est qu'il y a un item en trop dans le craft et la fonction retourne false, à la fin, si la liste est vide, la
           * fonction retourne true.
           */
          public boolean matches(InventoryCrafting inv, World worldIn)
          {
              ArrayList arraylist = Lists.newArrayList(this.recipeItems); //Copie les items du craft dans une nouvelle liste
              for (int i = 0; i < inv.getHeight(); ++i)
              {
                  for (int j = 0; j < inv.getWidth(); ++j)
                  {
                      ItemStack itemstack = inv.getStackInRowAndColumn(j, i);
                      if (itemstack != null)
                      {
                          boolean flag = false;
                          for(Object component : arraylist)
                          {
                              if(component instanceof String) //Search in ore dictionary
                              {
                                  List <ItemStack>stacks = OreDictionary.getOres((String) component);
                                  for(ItemStack itemstack1 : stacks)
                                  {
                                      if (ForgeShapedRecipes.areItemStacksEquals(itemstack1, itemstack))
                                      {
                                          flag = true;
                                          arraylist.remove(itemstack1);
                                          break;
                                      }
                                  }
                              }
                              else
                              {
                                  ItemStack itemstack1 = (ItemStack)component;
                                  if (ForgeShapedRecipes.areItemStacksEquals(itemstack1, itemstack))
                                  {
                                      flag = true;
                                      arraylist.remove(itemstack1);
                                      break;
                                  }
                              }
                          }
                          if (!flag)
                              return false;
                      }
                  }
              }
              return arraylist.isEmpty();
          }
      
          /**
           * Returns an Item that is the result of this recipe
           */
          public ItemStack getCraftingResult(InventoryCrafting inv)
          {
              return this.recipeOutput.copy();
          }
      
          @Override
          public boolean canFit(int width, int height) {
              return false;
          }
      
          /**
           * Returns the size of the recipe area
           */
          public int getRecipeSize()
          {
              return this.recipeItems.size();
          }
      
          @Override
          public IRecipe setRegistryName(ResourceLocation name) {
              return null;
          }
      
          @Nullable
          @Override
          public ResourceLocation getRegistryName() {
              return null;
          }
      
          @Override
          public Class<IRecipe> getRegistryType() {
              return null;
          }
      }
      

      Merci encore pour l’aide qui serra apporté !!! Si il manque quoi que ce soit n’hésité pas a me demandé.

      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