Jump to content

Recommended Posts

Posted

Hi,

I just went to create a block that is guaranteed to drop three different items (e.g. 1 of item a, 1 of item b and 1 of item c) when broken, which would, previously, have been done through the getDrops method in Block:

Spoiler

@Deprecated
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
        NonNullList<ItemStack> ret = NonNullList.create();
        getDrops(ret, world, pos, state, fortune);
        return ret;
    }

 

where you create a NonNullList with the items and return it.

However, this is deprecated, so now we should use the new getDrops method in Block:

Spoiler

/**
     * This gets a complete list of items dropped from this block.
     *
     * @param drops add all items this block drops to this drops list
     * @param world The current world
     * @param pos Block position in world
     * @param state Current state
     * @param fortune Breakers fortune level
     */
    public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
        Random rand = world instanceof World ? ((World)world).rand : RANDOM;

        int count = quantityDropped(state, fortune, rand);
        for (int i = 0; i < count; i++)
        {
            Item item = this.getItemDropped(state, rand, fortune);
            if (item != Items.AIR)
            {
                drops.add(new ItemStack(item, 1, this.damageDropped(state)));
            }
        }
    }

 

This instead takes the list as an argument, and returns nothing.

 

How does one use this new method? How will forge have the ItemStack list to pass when it is called, or do I have to call it myself - in which case, from where? I couldn't find anything in Block, and I don't know where else to look.

Thanks :)

Posted

For these types of functions the list would simply be passed in already created (you dont have to make it yourself with 'new') and you simply add the drops to the list provided.

 

Because its passed by reference then the list will be the same once your function has completed, ready for forge to drop the items onto the ground (or more likely go through the event system first so other mods can make changes to the drops)

 

So just add a, b and c to drops

Posted (edited)
7 minutes ago, Notunknown said:

For these types of functions the list would simply be passed in already created (you dont have to make it yourself with 'new') and you simply add the drops to the list provided.

 

Because its passed by reference then the list will be the same once your function has completed, ready for forge to drop the items onto the ground (or more likely go through the event system first so other mods can make changes to the drops)

 

So just add a, b and c to drops

I can't find any provided list - there doesn't seem to be a NonNullList declared in Block.

 

6 minutes ago, _Bedrockbreaker_ said:

I am thinking (which means I may be totally wrong) that you want to override the onBlockBroken method and call something that has a reference to a custom loot table which would allow to do almost anything with the blocks drops.

That could be it considering that onBlockDestroyedByPlayer (assuming that's what you meant since there is no onBlockBroken) has no body in the Block class, I'll give it a try.

Edited by Sommanker
Posted (edited)

I doubt the list would be in the Block, but in whatever function calls getDrops. Your drops should be added to the NonNullList provided. For example:

 

public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune)

{

super.getDrops(drops, world, pos, state, fortune);

drops.add(new ItemStack(Items.IRON_INGOT));

drops.add(new ItemStack(Items.GOLD_INGOT));

drops.add(new ItemStack(Items.DIAMOND));

}

Edited by Notunknown
Cant use forums xP
Posted

Ok, so I therefore assume that I have to override the onBlockDestroyedByPlayer and the same for explosions so that I can do that?

And also override dropBlockAsItem and dropBlockAsItemWithChance, as they still use the deprecated for backwards compatibility meaning that I should un-override them again once the deprecated method is removed?

 

 

Posted

No, dropBlockAsItem calls dropBlockAsItemWithChance, which calls getDrops. Override getDrops and it will affect the other two, but you can override them all if your situation requires it.

Posted

dropBlockAsItemWithChance calls the deprecated getDrops at the moment though:

Spoiler

public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune)
    {
        if (!worldIn.isRemote && !worldIn.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe
        {
            List<ItemStack> drops = getDrops(worldIn, pos, state, fortune); // use the old method until it gets removed, for backward compatibility
            chance = net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(drops, worldIn, pos, state, fortune, chance, false, harvesters.get());

            for (ItemStack drop : drops)
            {
                if (worldIn.rand.nextFloat() <= chance)
                {
                    spawnAsEntity(worldIn, pos, drop);
                }
            }
        }
    }

 

which has different arguments, so overriding the new getDrops won't affect it I thought?

Posted

Oh, and onBlockDestroyedByPlayer and onBlockDestroyedByExplosion are empty, so only override them if you need some functionality to occur in those situations (such as giving an advancement or something, presumably)

Posted (edited)

If I don't override those, then when is the new getDrops called? Don't I have to override those, where I declare the NonNullList and pass it to getDrops?

Edited by Sommanker
Posted (edited)

Ah, I think I understand, so the old getDrops is called automatically, so I don't need to override the onBlockDestroyed methods to call it, nor the dropBlockAsItem methods, so I just need to override the old getDrops to add stuff to the NonNullList it creates, and leave everything else the same, until the old getDrops method is removed.

I'll try it :3

If this is correct, it's kinda weird since the comments above the old getDrops tells you to use the other one...

Edited by Sommanker
Posted

Yeah, but you can't override and use the new one because then there is no way to add items to the NonNullList which must be passed to it unless you override all the other methods I list in earlier posts, which I thought should be unnecessary (and I assumed will be when the deprecated getDrops is removed)?

Posted

Yeah, so basically dont use getDrops(IBlockAccess, BlockPos, IBlockState, int) as it will probably be removed entirely by 1.13 and doesnt do anything important, either.

 

As for dropBlockAsItem and dropBlockAsItemWithChance, for most blocks you will not need to override either of those.

Posted

Ahhh

I think I might finally understand? Sorry if I'm being thick.

So forge calls the old getDrops, which calls the new one.

I need to override the new getDrops in order to populate the list - and do nothing else.

I'll try that!

 

  • Like 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.