Problème d'item fantôme



  • Bonjour, j'ai une partie de code qui me permet de casser "instantanément" les blocs d'un arbre à condition qu'il ait une taille inférieure à 7 blocs. Voici la fonction :

    
    public boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntityLivingBase playerIn)
       {
           if (worldIn.getBlockState(pos.up(7)).getBlock().isWood(worldIn, pos.up(7)))
           {
               if (playerIn instanceof EntityPlayer && !worldIn.isRemote)
               {
    
               }
               return super.onBlockDestroyed(stack, worldIn, state, pos, playerIn);
           }
           for (int i = 0; i < 7; i++)
           {
               BlockPos testPos = pos.up(i);
    
               if (worldIn.getBlockState(testPos).getBlock().isWood(worldIn, testPos))
               {
                   stack.damageItem(1, playerIn);
    
                   if (!worldIn.isRemote && worldIn.getGameRules().getBoolean("doTileDrops"));
                   {
                       float f = 0.7F;
    
                       double d0 = (double)(worldIn.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
                       double d1 = (double)(worldIn.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
                       double d2 = (double)(worldIn.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
    
                       EntityItem entityItem = new EntityItem(worldIn, (double)testPos.getX() + d0, (double)testPos.getY() + d1, (double)testPos.getZ() + d2, new ItemStack(Item.getItemFromBlock(state.getBlock()), 1, worldIn.getBlockState(testPos).getBlock().getMetaFromState(worldIn.getBlockState(testPos))));
                       entityItem.setDefaultPickupDelay();
                       worldIn.spawnEntity(entityItem);
                   }
                   worldIn.setBlockToAir(testPos);
               }
               else
               {
                   return super.onBlockDestroyed(stack, worldIn, state, testPos, playerIn);
               }
           }
           return super.onBlockDestroyed(stack, worldIn, state, pos, playerIn);
       }
    
    

    Tout fonctionne bien, du moins le principe. Il y a un souci d'item fantôme : (je vais expliquer sur un exemple)
    Lorsque je détruit un pillier de 3 buche de haut par exemple, tout l'arbre se détruit mais au lieu de looter 3 items de buche il y en a 6. Et je ne peux en récupérer que 3; les autres sont visuellement présent mais je n'interagit pas avec : d'où le nom d'item fantôme. 😉
    Du coup, comment faire disparaître ces fantômes ?
    Merci par avance pour votre aide .



  • Salut, World#spawnEntity ne doit être appelé que côté serveur. Du coup il te faut rajouter un if(worldIn.isRemote), juste avant.


  • Administrateurs

    La condition est déjà présente :
    if (!worldIn.isRemote && worldIn.getGameRules().getBoolean("doTileDrops"));
    Donc il ne devrait pas avoir d'item en double, étrange.



  • J'ai réussi à réglé le souci des items fantômes, j'ai juste du remplacer la partie où je fais spawn un item par cette ligne :

    
    worldIn.getBlockState(testPos).getBlock().dropBlockAsItem(worldIn, testPos, state, 0);
    
    

    Voici la fonction modifiée :

    
    public boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntityLivingBase playerIn)
       {
           if (worldIn.getBlockState(pos.up(7)).getBlock().isWood(worldIn, pos.up(7)))
           {
               if (playerIn instanceof EntityPlayer && !worldIn.isRemote)
               {
    
               }
               return super.onBlockDestroyed(stack, worldIn, state, pos, playerIn);
           }
           for (int i = 0; i < 7; i++)
           {
               BlockPos testPos = pos.up(i);
    
               if (worldIn.getBlockState(testPos).getBlock().isWood(worldIn, testPos))
               {
                   stack.damageItem(1, playerIn);
    
                   if (!worldIn.isRemote && worldIn.getGameRules().getBoolean("doTileDrops"));
                   {
                       worldIn.getBlockState(testPos).getBlock().dropBlockAsItem(worldIn, testPos, state, 0);
                   }
                   worldIn.setBlockToAir(testPos);
               }
               else
               {
                   return super.onBlockDestroyed(stack, worldIn, state, testPos, playerIn);
               }
           }
           return super.onBlockDestroyed(stack, worldIn, state, pos, playerIn);
       }
    
    

    Merci de votre aide. Je passe le sujet en résolu. 🙂