Bug NBTTag pour Item avec craft
-
Les items n’ont pas de limite pour les metadatas : seul les blocks en ont. Regarde les potions et les oeufs pour faire apparaître les mobs.
-
A oui je croyais mais j’avais gardé l’utilisation des métadatas pour d’autres blocks de mon mod. Peut-on m’expliquer mes erreurs dans mon code svp ?
-
“L’utilisation des métadatas pour d’autres blocks” ?!
Si tu veux vraiment utiliser les NBT, il te faut une classe implements IRecipe.
Mais je te rappelle que les métadatas sont une bien meilleure solution.
-
Tu me l’aurai signalé je l’aurai restauré. Depuis mybb 1.8 les posts supprimés deviennent juste invisible est peuvent être restauré. Seuls les admin peuvent supprimer définitivement les posts.
Je répété aussi la même chose :
Ça ne fonctionne pas du tout comme ça.
Là tu essaye de mettre des variables sur l’item, or tu n’as qu’un seule instance par item.
Il faut tout mettre dans le tag nbt.
Tes variables isImprovableInClouMode, isImprovableInPoisonMode, wasImprovedInClouMode , wasImprovedInPoisonMode ne devraient pas exister. -
@‘SCAREX’:
“L’utilisation des métadatas pour d’autres blocks” ?!
Si tu veux vraiment utiliser les NBT, il te faut une classe implements IRecipe.
Mais je te rappelle que les métadatas sont une bien meilleure solution.
J’ai une regardé un peu l’interface IRecipe et je n’arrive pas vraiment à voir ce qu’elle va me faire gagner de + ?
-
Grâce à cette interface, tu peux spécifier l’output et donc y ajouter des NBT en plus selon le craft ou autre.
-
Robin -> Pour mes valeurs isImprovableIn…Mode je suis convaincu qu’elles doivent rester puisqu’elle font partie de mon constructeur. Et pour les valeurs wasImprovedIn…Mode tu veux qu’elles soient locale à la méthode onCreated c’est ça ? Mais j’ai en ai besoin pour mes getter…
SCAREX -> Merci de ta réponse détaillée je vais me pencher là dessus
-
Je crois que j’ai pas suivis quelque chose alors …
Tu utilises cette classe pour plusieurs items ?Si tu veux un exemple d’utilisation des tags d’item :
https://github.com/FFMT/nanotech_mod/blob/master/common/fr/mcnanotech/kevin_68/nanotechmod/main/items/ItemLightSaber.java
https://github.com/FFMT/nanotech_mod/blob/master/common/fr/mcnanotech/kevin_68/nanotechmod/main/items/ItemNanomiteArrowGun.java#L50 -
Oui tiens une partie de mon ItemHandler pour te situer la chose

batteBaseball = new DyingCraftItemSword(batteBaseballToolMaterial, true, true).setUnlocalizedName("batteBaseball").setTextureName(DyingCraftMod.MODID + ":batteBaseball"); GameRegistry.registerItem(batteBaseball, "batteBaseball"); batteCricket = new DyingCraftItemSword(batteCricketToolMaterial, true, true).setUnlocalizedName("batteCricket").setTextureName(DyingCraftMod.MODID + ":batteCricket"); GameRegistry.registerItem(batteCricket, "batteCricket"); grosseHache = new DyingCraftItemSword(grosseHacheToolMaterial, false, true).setUnlocalizedName("grosseHache").setTextureName(DyingCraftMod.MODID + ":grosseHache"); GameRegistry.registerItem(grosseHache, "grosseHache"); petitCouteau = new DyingCraftItemSword(petitCouteauToolMaterial, false, true).setUnlocalizedName("petitCouteau").setTextureName(DyingCraftMod.MODID + ":petitCouteau"); GameRegistry.registerItem(petitCouteau, "petitCouteau");J’ai pas forcément de difficultés avec les Tags même si je n’y compris rien je me débrouille avec les méthodes, c’est juste pour relier le tout aux craft. Mais pour l’instant je découvre l’interface IRecipe, j’espère qu’elle me conduira à la solution =D
-
Mais pourquoi vouloir utiliser les tag nbt de l’itemstack alors :huh:
-
@‘robin4002’:
Mais pourquoi vouloir utiliser les tag nbt de l’itemstack alors :huh:
En fait mes armes seront améliorables (certaines aux clous, d’autres au poison, d’autres pas du tout, d’autres les deux à la fois) c’est à ça que servent les 2 boolean supplémentaires dans le constructeur. Mais de base tous mes nouveaux items sont normaux, je veux juste me servir des NBTTag pour enregistrer si certaines de ces armes ont subi une des 2 améliorations. Tu comprends ou pas ? :huh:
-
En fait mes armes seront améliorables (certaines aux clous, d’autres au poison, d’autres pas du tout, d’autres les deux à la fois) c’est à ça que servent les 2 boolean supplémentaires dans le constructeur. Mais de base tous mes nouveaux items sont normaux, je veux juste me servir des NBTTag pour enregistrer si certaines de ces armes ont subi une des 2 améliorations. Tu comprends ou pas ? :huh:
-
Dans ce cas pourquoi avoir fait plusieurs items ? Un seul suffit non ?
-
Alors il faut passer par une classe implements IRecipe, voici un code qui devrait t’aider (Dans ce code je me suis fait une API un peu difficile à comprendre, demande si tu as besoin d’aide sur ce code) :
package fr.scarex.ascalonmod.recipe; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import fr.scarex.ascalonmod.block.AscalonModBlocks; import fr.scarex.ascalonmod.item.AscalonModItems; /** * @author SCAREX * */ public class KeyRecipe implements IRecipe { private static final Random RNG = new Random(); protected ItemStack result; protected ExtendedItem[][] matrix; protected byte slotIndex; public KeyRecipe(ItemStack result, byte slotIndex, ExtendedItem[][] matrix) { this.result = result; this.matrix = matrix; this.slotIndex = slotIndex; } public KeyRecipe(CraftMatrix c) { this.result = c.result; this.slotIndex = c.slot; this.matrix = c.matrix; } @Override public boolean matches(InventoryCrafting inv, World world) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (!ExtendedItem.corresponds(this.matrix*[j], inv.getStackInSlot(i * 3 + j))) return false; } } return true; } @Override public ItemStack getCraftingResult(InventoryCrafting inv) { NBTTagCompound comp = new NBTTagCompound(); if (slotIndex > 0) comp.setInteger("key", inv.getStackInSlot(slotIndex).getTagCompound().getInteger("key")); else comp.setInteger("key", RNG.nextInt()); ItemStack stack = result.copy(); stack.setTagCompound(comp); return stack; } @Override public int getRecipeSize() { return 9; } @Override public ItemStack getRecipeOutput() { return result.copy(); } public static enum CraftMatrix { KEY( new ItemStack(AscalonModItems.ITEM_KEY), -1, new Item[][] { new Item[] { Items.iron_ingot, Items.iron_ingot, null }, new Item[] { null, Items.iron_ingot, null }, new Item[] { null, Items.iron_ingot, null } }), COPY_KEY( new ItemStack(AscalonModItems.ITEM_KEY), 6, new Item[][] { new Item[] { Items.iron_ingot, Items.iron_ingot, null }, new Item[] { null, Items.iron_ingot, null }, new Item[] { AscalonModItems.ITEM_KEY, Items.iron_ingot, null } }), LOCKED_CHEST( new ItemStack(AscalonModBlocks.BLOCK_LOCKED_CHEST), 5, new Item[][] { new Item[] { Items.iron_ingot, Items.iron_ingot, Items.iron_ingot }, new Item[] { AscalonModItems.ITEM_LOCK, Item.getItemFromBlock(Blocks.chest), AscalonModItems.ITEM_KEY }, new Item[] { Items.iron_ingot, Items.iron_ingot, Items.iron_ingot } }), LOCKED_DOOR( new ItemStack(AscalonModItems.ITEM_SPRUCE_DOOR), 5, new ExtendedItem[][] { new ExtendedItem[] { new ExtendedItem(Blocks.planks, 1), new ExtendedItem(Blocks.planks, 1), null }, new ExtendedItem[] { new ExtendedItem(Blocks.planks, 1), new ExtendedItem(Blocks.planks, 1), new ExtendedItem(AscalonModItems.ITEM_KEY) }, new ExtendedItem[] { new ExtendedItem(Blocks.planks, 1), new ExtendedItem(Blocks.planks, 1), null } }); public ItemStack result; public byte slot; public ExtendedItem[][] matrix; private CraftMatrix(ItemStack stack, int slotIndex, Item[][] matrix) { this.result = stack; this.slot = (byte) slotIndex; this.matrix = ExtendedItem.convertMatrix(matrix); } private CraftMatrix(ItemStack result, int slot, ExtendedItem[][] matrix) { this.result = result; this.slot = (byte) slot; this.matrix = matrix; } } public static class ExtendedItem { private Item item; private int metadata; public ExtendedItem(Item item, int meta) { this.item = item; this.metadata = meta; } public ExtendedItem(Block block, int metadata) { this.item = Item.getItemFromBlock(block); this.metadata = metadata; } public ExtendedItem(Item item) { this.item = item; this.metadata = 0; } public ExtendedItem(Block block) { this.item = Item.getItemFromBlock(block); this.metadata = 0; } /** * @return the item */ public Item getItem() { return item; } /** * @return the metadata */ public int getMetadata() { return metadata; } public static ExtendedItem[][] convertMatrix(Item[][] items) { ExtendedItem[][] xItems = new ExtendedItem[3][3]; for (int i = 0; i < xItems.length; i++) { for (int j = 0; j < xItems*.length; j++) { xItems*[j] = new ExtendedItem(items*[j]); } } return xItems; } public static boolean corresponds(ExtendedItem item, ItemStack stack) { if (stack == null && item != null && item.getItem() != null) return false; if (stack != null && (item == null || item.getItem() == null)) return false; if (stack != null && item.getItem() != null && (stack.getItem() != item.getItem() || stack.getItemDamage() != item.getMetadata())) return false; return true; } } } -
Non les item que je t’ai montré dans mon message 12 sont différents. Ils subiront tous des améliorations. Exemple la grosse hâche qui pourra être amélioré en mode poison, la batte de baseball en mode clou, etc…
SCAREX, si tu lis ce message j’ai trouvé ces 2 lien pour l’interface mais j’ai du mal à comprendre
http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/modification-development/2181203-how-to-use-the-irecipe-interface
http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/modification-development/2230695-irecipe-help
http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/modification-development/2268796-help-me-use-nbtAu niveau de l’enregistrement ça va.
Pour l méthode matches() c’est juste la méthode où on doit spécifier quels items se trouvent dans quels slots, je penseOk je viens de voir ton message ><
-
matches -> regarde si les slots correspondent
getCraftingResult -> retourne un ItemStack correspondant à l’output du craft
getRecipeSize -> retourne le nombre de slots à utiliser ( 9 = toute la table je crois)
getRecipeOutput -> l’ItemStack sans modifications, je ne sais pas à quoi çà sert -
Ok je me suis dépatouillé et j’ai enfin réussi. Merci SCAREX au fait ton code a l’air super, dommage que je ne le comprenne pas dans son intégralité

J’ai juste une dernière question à quoi sert cette ligne :
for (int k1 = 0; k1 < craftingTable.getSizeInventory(); ++k1)Je sais que c’est une boucle et tout…qu’elle est répétée 9 fois puisqu’il y a 9 slot dans l’inventaire mais elle permet de vérifier chaque slot, si c’est bien ça pourquoi la méthode ne s’en charge pas toute seule étant donné que la méthode matches () est une méthode tickée ?
-
la méthode matches te demande de verifier si le craft est bon, si tu mets return true, n’importe quoi donnera ton craft. Ici j’utilise une boucle for pour me s’implifier la vie avec les matrix que j’ai mis plus bas : ce sont des array d’Item (ou extended item pour les metadatas). çà rend les choses plus simple.
-
Désolé de devoir réouvrir ce sujet mais ça évitera d’en recréer un qui traite le même problème. Je voudrai que si mon Item passé en argument du constructeur, soit inutile si il possède déjà un Tag. En gros on ne peut pas réaliser le craft si par-exemple ma batte de baseball possède déjà le NBT Boolean “wasImprovedInClouMode”. Déjà soit je n’ai toujrous rien compris soit je sais pas , mon premier println n’est même pas appelé (celui de la méthode matches()) alors que mon item possède bien un tag, donc logiquement le stackTagCompound ne devrait pas être null, or c’est le second println qui est appelé.
Voici mon codepackage fr.mrplaigon.dyingcraft.common.customrecipe; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import fr.mrplaigon.dyingcraft.common.handler.ItemHandler; import fr.mrplaigon.dyingcraft.common.item.DyingCraftItemSword; public class ImprovementsRecipe implements IRecipe { private DyingCraftItemSword itemImproved; private byte statut; public ImprovementsRecipe(DyingCraftItemSword itemImproved) { this.itemImproved = itemImproved; statut = 0; } @Override public boolean matches(InventoryCrafting craftingTable, World world) { ItemStack itemstack = new ItemStack(itemImproved, 1); if(itemstack.stackTagCompound != null) { System.out.println("stackTagCompound non null"); } else { System.out.println("stackTagCompound null"); } for (int k1 = 0; k1 < craftingTable.getSizeInventory(); ++k1) { if(itemImproved.isImprovableInClouMode()) { if(craftingTable.getStackInSlot(1) != null && craftingTable.getStackInSlot(3) != null && craftingTable.getStackInSlot(4) != null && craftingTable.getStackInSlot(5) != null && craftingTable.getStackInSlot(7) != null) { if(craftingTable.getStackInSlot(1).getItem() == ItemHandler.boiteClous && craftingTable.getStackInSlot(3).getItem() == ItemHandler.boiteClous && craftingTable.getStackInSlot(5).getItem() == ItemHandler.boiteClous && craftingTable.getStackInSlot(7).getItem() == ItemHandler.boiteClous && craftingTable.getStackInSlot(4).getItem() == itemImproved) { statut = 1; return true; } } } if(itemImproved.isImprovableInPoisonMode()) { if(craftingTable.getStackInSlot(1) != null && craftingTable.getStackInSlot(3) != null && craftingTable.getStackInSlot(4) != null && craftingTable.getStackInSlot(5) != null && craftingTable.getStackInSlot(7) != null) { if(craftingTable.getStackInSlot(1).getItem() == ItemHandler.fiolePoison && craftingTable.getStackInSlot(3).getItem() == ItemHandler.fiolePoison && craftingTable.getStackInSlot(5).getItem() == ItemHandler.fiolePoison && craftingTable.getStackInSlot(7).getItem() == ItemHandler.fiolePoison && craftingTable.getStackInSlot(4).getItem() == itemImproved) { statut = 2; return true; } } } } return false; } @Override public ItemStack getCraftingResult(InventoryCrafting inventorycrafting) { ItemStack itemstack = new ItemStack(itemImproved, 1); NBTTagCompound compound = new NBTTagCompound(); // if(statut == 1 && !itemstack.stackTagCompound.hasKey("wasImprovedInClouMode")) // { // compound.setBoolean("wasImprovedInClouMode", true); // return itemstack; // } // if(statut == 1 && itemstack.stackTagCompound.hasKey("wasImprovedInClouMode")) // { // EventHandlerClient.drawCraftPicture(168, 138, new ResourceLocation("dyingcraftmod", "textures/gui/improvements/errorsMessages.png")); // } // else if(statut == 2 && !itemstack.stackTagCompound.hasKey("wasImprovedInPoisonMode")) // { // compound.setBoolean("wasImprovedInPoisonMode", true); // return itemstack; // } if(statut == 1) { compound.setBoolean("wasImprovedInClouMode", true); } else { compound.setBoolean("wasImprovedInPoisonMode", true); } itemstack.setTagCompound(compound); return itemstack; } @Override public int getRecipeSize() { return 9; } @Override public ItemStack getRecipeOutput() { return new ItemStack(itemImproved); } } -
Une instance de ta classe = un craft ou un groupe de crafts.
Ton matches te donne accès à tous les items de la table de craft, c’est à toi d’aller les chercher au bon endroit et de regarder qu’ils soient bien là.
Pense à enregistrer ton recipe avec GameRegistry.addRecipe(new TaClasse()).