Dropt

Dropt

3M Downloads

Forestry's Apatite Ore / Evilcraft's Dark Ore continue to drop their experience

KAfable opened this issue · 1 comments

commented

Given this JSON: https://hastebin.com/rocucewulu.json, I'm trying to make blocks silk touch drop their ores and for all of the ores listed except Forestry's Apatite (forestry:resources:0) and Evilcraft's Dark Ores, those still continue to drop experience. Any insight on this?

If nothing can be done on Dropt's end, what should I be recommending to the Evilcraft/Forestry devs to change about their ore blocks so it'll respect Dropt's changes?

Thanks again btw for your earlier changes with the XP replace strategy, it's been helping a lot with my planned ore processing so far.

commented

Dropt can't do anything about those blocks dropping XP because they spawn the XP into the world directly.

Both Forestry and EvilCraft call Block#dropXpOnBlockBreak(World, BlockPos, int) to drop the XP which spawns it into the world directly.

https://github.com/ForestryMC/ForestryMC/blob/mc-1.12/src/main/java/forestry/core/blocks/BlockResourceOre.java#L66

https://github.com/CyclopsMC/EvilCraft/blob/master-1.12/src/main/java/org/cyclops/evilcraft/block/DarkOre.java#L100

Dropt intercepts XP in the BlockEvent.BreakEvent event, which gets its XP by calling Block#getExpDrop(IBlockState, IBlockAccess, BlockPos, int). For Dropt to be able to manipulate a block's XP drop, the mod's block must override Block#getExpDrop and return the XP amount from that method.

This is how vanilla does it:

    @Override
    public int getExpDrop(IBlockState state, IBlockAccess world, BlockPos pos, int fortune)
    {
        Random rand = world instanceof World ? ((World)world).rand : new Random();
        if (this.getItemDropped(state, rand, fortune) != Item.getItemFromBlock(this))
        {
            int i = 0;

            if (this == Blocks.COAL_ORE)
            {
                i = MathHelper.getInt(rand, 0, 2);
            }
            else if (this == Blocks.DIAMOND_ORE)
            {
                i = MathHelper.getInt(rand, 3, 7);
            }
            else if (this == Blocks.EMERALD_ORE)
            {
                i = MathHelper.getInt(rand, 3, 7);
            }
            else if (this == Blocks.LAPIS_ORE)
            {
                i = MathHelper.getInt(rand, 2, 5);
            }
            else if (this == Blocks.QUARTZ_ORE)
            {
                i = MathHelper.getInt(rand, 2, 5);
            }

            return i;
        }
        return 0;
    }

Block#dropXpOnBlockBreak(World, BlockPos, int) is called from the Block#tryHarvestBlock(BlockPos) method after the block break event is processed. The XP amount from the block break event is passed into the call to Block#dropXpOnBlockBreak(World, BlockPos, int) to actually spawn the XP in the world.

I would recommend that mod blocks override the Block#getExpDrop method instead of calling the other method directly. It seems more correct, if there even is such a thing in modded MC. ¯\_(ツ)_/¯