Résolu Crash lors d'un give via la casse d'un bloc
-
Voici mon code :
package fr.altiscraft.altiscraft.common; import java.util.Random; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.world.World; public class BlockPomme extends Block { public Random rand = new Random(); public void onBlockDestroyedByPlayer(World world, int x, int y, int z, int l) { if(!world.isRemote){ Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory(new ItemStack(Items.apple, 1 + rand.nextInt(5))); world.setBlock(x, y, z, ModAltisCraft.blockPomme, 0, 2); } } protected BlockPomme() { super(Material.leaves); } public boolean renderAsNormalBlock() { return false; } public boolean isOpaqueCube() { return false; } }
J’ai revu mon sujet : http://www.minecraftforgefrance.fr/showthread.php?tid=2384&highlight=casse
Mais je ne sais pas comment résoudre le problème cette fois merci de m’aider :S
Ps voici le crash report :
-
public void onBlockDestroyedByPlayer(World world, int x, int y, int z, int l) {
if(!world.isRemote){
Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory(new ItemStack(Items.apple, 1 + rand.nextInt(5)));
world.setBlock(x, y, z, ModAltisCraft.blockPomme, 0, 2);
}
La classe Minecraft est une classe client et n’existe pas côté serveur. -
Oui je sais mais comment résoudre ça j’ai essayer avec des SideOnly ou avec des conditions if(world.isRemote) etc mais je n’y arrive pas :S
-
Essaie en retirant le ! d’exclamation de ta condition :
if(world.isRemote)
{}Ou essaie en la retirant complétement
-
Quand j’enlève le !, le bloc ne respawn pas mais je gagne les pommes et si j’enlève la condition, ça crash avec ce crash-report : http://pastebin.com/2wgABSd5
-
Voilà le bon code
if(!world.isRemote){ world.spawnEntityInWorld(new EntityItem(world, x, y, z, new ItemStack(Items.apple, 1 + rand.nextInt(5)))) world.setBlock(x, y, z, ModAltisCraft.blockPomme, 0, 2); }
Par-contre c’est un peu différent, ça le fait spawn mais ne l’ajoute pas directement à l’inventaire du joueur. Mais au final c’est pareil…
-
Ce que je veux c’est que ça spawn directement dans son inventaire ….
-
Dans ce cas essaie avec les event
@SubscribeEvent public void onBlockDestroyed(BreakEvent event) { if(event.block == TaClassePrincipale.blockPomme) { event.getPlayer().inventory.addItemStackToInventory(new ItemStack(Items.apple, 1 + rand.nextInt(5))); event.world.setBlock(x, y, z, ModAltisCraft.blockPomme, 0, 2); } }
-
Pas moyen d’éviter les events ?
-
Non je ne connais pas d’autre méthode dans la classe Block appelé lorsqu’il est cassé. Mais tu sais tu devras bien y passer en + ce n’est pas compliqué.
Tu rajoutes cette ligne là dans ta méthode init :
MinecraftForge.EVENT_BUS.register(new TaClasseDEvent());EDIT = Y’a moyen de faire autrement, il suffit d’envoyer un packet.
-
Ouai mais bon les events et moi… :S
-
Et tout mais pas les packets :') enfin bon je suis sûr que c’est possible avec mon code de base quelqu’un d’autre a des idées ?
-
Nop je suis la seule personne ce soir =D
Essaie ça, je n’y avais pas du tout pensépublic void onBlockDestroyedByPlayer(World world, int x, int y, int z, int l) { if(world.isRemote){ Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory(new ItemStack(Items.apple, 1 + rand.nextInt(5))); } else { world.setBlock(x, y, z, ModAltisCraft.blockPomme, 0, 2); } }
-
Ca marche impec’ merci beaucoup
-
Nop ça ne marche pas j’ai testé.
Regarde bien, fais toi giver l’item par le block, déco-reco et tu verras qu’il n’est pas sauvegardé dans ta barre d’action….
C’est sûrement un prob de Sides, on a dû placer le code au mauvais endroit (dans la mauvaise condition). Il faut regarder dans les autres classes de Minecraft, par-exemple la vache et son saut de lait. Pour ça je te laisse tu ne devrais pas avoir trop de mal -
Alors voilà ma nouvelle classe :
package fr.altiscraft.altiscraft.common; import java.util.ArrayList; import java.util.Random; import net.minecraft.block.BlockBush; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.IShearable; public class CannabisPlante extends BlockBush implements IShearable { protected CannabisPlante() { super(Material.leaves); float f = 0.4F; setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.8F, 0.5F + f); } public void onBlockDestroyedByPlayer(World world, int x, int y, int z, int l) { if (world.isRemote) { Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory(new ItemStack(ModAltisCraft.itemCannabis, 1)); } else { world.setBlock(x, y, z, ModAltisCraft.CannabisPlante, 0, 2); } } public boolean isShearable(ItemStack item, IBlockAccess world, int x, int y, int z) { return false; } public ArrayList <itemstack>onSheared(ItemStack item, IBlockAccess world, int x, int y, int z, int fortune) { return null; } public int quantityDropped(Random rdm) { return 0; } public Item getItemDropped(int int1, Random rdm, int int2) { return Item.getItemFromBlock(this); } }
Le problème est celui que tu as dis ça ne sauvegarde pas j’ai regardé du côté sceau de lait mais je n’ai vu que ça qui ne m’aide pas trop…
/** * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. */ public boolean interact(EntityPlayer p_70085_1_) { ItemStack itemstack = p_70085_1_.inventory.getCurrentItem(); if (itemstack != null && itemstack.getItem() == Items.bucket && !p_70085_1_.capabilities.isCreativeMode) { if (itemstack.stackSize-- == 1) { p_70085_1_.inventory.setInventorySlotContents(p_70085_1_.inventory.currentItem, new ItemStack(Items.milk_bucket)); } else if (!p_70085_1_.inventory.addItemStackToInventory(new ItemStack(Items.milk_bucket))) { p_70085_1_.dropPlayerItemWithRandomChoice(new ItemStack(Items.milk_bucket, 1, 0), false); } return true; } else { return super.interact(p_70085_1_); } }
Voilà je ne sais pas comment résoudre ça :x Merci d’avance</itemstack>
-
On te l’a dit utilise les events !
Le give d’objet ça se fait uniquement coté serveur.
Le système a été fait pour te simplifier la vie, tu te compliques la vie en cherchant a le contourner. -
Surtout que le code n’est pas très compliqué :
(code 1.8)@SubscribeEvent public void onPlayerBreakBlock(BreakEvent event) { if(event.state.getBlock() == TestMod.plante && !event.getPlayer().capabilities.isCreativeMode) //Ne donne pas le bloc si le joueur est en créatif car ça peut être embêtant { event.getPlayer().inventory.addItemStackToInventory(new ItemStack(TestMod.plante)); } }
-
Franchement les événements c’est super simple …
Et sinon il y a cette fonction :public void harvestBlock(World world, EntityPlayer player, int x, int y, int z, int metadata) { super.harvestBlock(world, player, x, y, z, metadata); player.inventory.addItemStackToInventory(new ItemStack(Items.apple, 1 + world.rand.nextInt(5))); }
-
Merci pour la fonction c’est bon en faite je n’aime pas trop passé par les events perso voilà merci beaucoup à tous !
EDIT: La fonction ne marche pas en multi comment faire ?? (Encore sans les events de préférences :S)
S’il vous plaît, merci
EDIT-EDIT:
- @SubscribeEvent
- public void onBlockDestroyed(BreakEvent event)
- {
- if(event.block == ModAltisCraft.blockPomme)
- {
- event.getPlayer().inventory.addItemStackToInventory(new ItemStack(Items.apple, 1));
- event.world.setBlock(x, y, z, ModAltisCraft.blockPomme, 0, 2);
- }
- }
J’ai mis ça dans ma classe des events mais rien :S