Guide Disabling Looting/Fortune for certain blocks or entities

U9G

New member
Jan 7, 2022
5
1
3

Disabling Fortune

In a BlockDropItemEvent (we use a BlockDropItemEvent since then we know durability damage has already been done to the tool and the block is already broken)
  1. Check if this is a block we don't want to apply fortune to, If so:
  2. Clear the current block drops
  3. Get the drops of the block with the item that's in the players hand without fortune
    1. In order to do that, we clone the pickaxe then just remove fortune from the cloned pickaxe
As Kotlin code, this looks like:
JavaScript:
private val DONT_FORTUNE_MATERIALS = listOf(Material.FLINT)
class FortuneDisablerListener : Listener {
    @EventHandler
    fun onBlockBreak(event: BlockDropItemEvent) {
        if (event.block.type !in DONT_FORTUNE_MATERIALS) return

        event.items.clear()

        val noFortuneItem = event.player.inventory.itemInMainHand.clone()
        noFortuneItem.editMeta { it.removeEnchant(Enchantment.LOOT_BONUS_BLOCKS) }
        event.block.getDrops(noFortuneItem, event.player).forEach {
            event.player.world.dropItemNaturally(event.block.location, it)
        }
    }
}

Disabling Looting

In an EntityDeathEvent
  1. Ensure this is an entity we don't want looting to apply to and ensure that the entity has a loottable (by checking the entity is a Mob)
  2. Get the killer, if there is a killer:
  3. Roll the entity's loottable, if the loot is not null:
  4. Clear the event's drops array
  5. add the new drops from the loottable roll
As Kotlin code, this looks like:
JavaScript:
private val DONT_LOOTING_ENTITIES: List<EntityType> = listOf(EntityType.CREEPER)

class LootingDisablerListener : Listener {
    @EventHandler
    fun onEntityDeath(event: EntityDeathEvent) {
        val mob = event.entity
        if (mob.type !in DONT_LOOTING_ENTITIES || mob !is Mob) return
        val killer = event.entity.killer ?: return
        val lootContext = LootContext.Builder(event.entity.location).lootedEntity(event.entity).lootingModifier(0).killer(killer)
        val loot = mob.lootTable?.populateLoot(ThreadLocalRandom.current(), lootContext.build()) ?: return
        event.drops.clear()
        event.drops.addAll(loot)
    }
}