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 :

    http://pastebin.com/DLMwXLHm


  • Administrateurs

    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.


  • Rédacteurs

    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));
    }
    }
    
    

  • Administrateurs

    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:

    1. @SubscribeEvent
    2. public void onBlockDestroyed(BreakEvent event)
    3. {
    4. if(event.block == ModAltisCraft.blockPomme)
    5. {
    6. event.getPlayer().inventory.addItemStackToInventory(new ItemStack(Items.apple, 1));
    7.    event.world.setBlock(x, y, z, ModAltisCraft.blockPomme, 0, 2);
    8. }
    9. }

    J'ai mis ça dans ma classe des events mais rien :S