Non résolu Table de Craft custom ! Passage en 1.12.2
-
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é.