Util FakeFortune

Discussion in 'Resources' started by MCMastery, Feb 5, 2020.

  1. Offline

    MCMastery

    This is a quick and dirty little piece of code that returns the number of drops an item should have, given the level of fortune a player has. This gives the correct amount for coal ore, diamond ore, emerald ore, nether quartz ore, redstone ore, and lapis ore.

    I needed this because I wanted to override the BlockBreakEvent (which does not have access to a list of drops) and give items directly into the player's inventory.

    I am posting this because it was a pain to write (although it probably would have been easier with maps or something).

    Code:
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    
    public class FakeFortune {
        private FakeFortune() {}
    
        public static int getFortuneLevel(Player player) {
            ItemStack tool = player.getInventory().getItemInMainHand();
            return tool.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS);
        }
        public static int calculateDrops(Material mat, int fortune) {
            double d = Math.random();
            if (mat == Material.COAL_ORE || mat == Material.DIAMOND_ORE || mat == Material.EMERALD_ORE
                    || mat == Material.NETHER_QUARTZ_ORE) {
                // source https://minecraft.gamepedia.com/Fortune
                if (fortune == 0)
                    return 1;
                if (fortune == 1) {
                    // 33% chance of 2x drops
                    if (d < 1/3.0)
                        return 2;
                    return 1;
                } else if (fortune == 2) {
                    // 25% chance 2x, 25% chance 3x
                    if (d < 0.25)
                        return 2;
                    if (d < 0.50)
                        return 3;
                    return 1;
                } else if (fortune == 3) {
                    // 20% chance 2x, 20% chance 3x, 20% chance 4x, 40% chance 1x
                    if (d < 0.20)
                        return 2;
                    if (d < 0.40)
                        return 3;
                    if (d < 0.60)
                        return 4;
                    return 1;
                }
            } else if (mat == Material.REDSTONE_ORE) {
                // source: https://minecraft.gamepedia.com/Redstone_Ore
                if (fortune == 0) {
                    // 50% 4, 50% 5
                    if (d < 0.5)
                        return 4;
                    return 5;
                } else if (fortune == 1) {
                    // 25% 4, 25% 6, 50% 5
                    if (d < 0.25)
                        return 4;
                    if (d < 0.50)
                        return 6;
                    return 5;
                } else if (fortune == 2) {
                    // 1/6 4, 1/6 7, 1/3 5, 1/3 6
                    if (d < 1/6.0)
                        return 4;
                    if (d < 2/6.0)
                        return 7;
                    if (d < 4/6.0)
                        return 5;
                    return 6;
                } else if (fortune == 3) {
                    // 1/8 4, 1/8 8, 1/4 5, 1/4 6, 1/4 7
                    if (d < 1/8.0)
                        return 4;
                    if (d < 2/8.0)
                        return 8;
                    if (d < 4/8.0)
                        return 5;
                    if (d < 6/8.0)
                        return 6;
                    return 7;
                }
            } else if (mat == Material.LAPIS_ORE) {
                // https://minecraft.gamepedia.com/Lapis_Lazuli_Ore
                // im starting to think theres a better way to do this
                if (fortune == 0) {
                    if (d < 1/6.0)
                        return 4;
                    if (d < 2/6.0)
                        return 5;
                    if (d < 3/6.0)
                        return 6;
                    if (d < 4/6.0)
                        return 7;
                    if (d < 5/6.0)
                        return 8;
                    return 9;
                } else if (fortune == 1) {
                    if (d < 1/18.0)
                        return 10;
                    if (d < 2/18.0)
                        return 12;
                    if (d < 3/18.0)
                        return 14;
                    if (d < 4/18.0)
                        return 16;
                    if (d < 5/18.0)
                        return 18;
    
                    if (d < 7/18.0)
                        return 4;
                    if (d < 9/18.0)
                        return 5;
                    if (d < 11/18.0)
                        return 6;
                    if (d < 13/18.0)
                        return 7;
                    if (d < 15/18.0)
                        return 9;
                    // 1/6.0 = 3/18.0
                    return 8;
                } else if (fortune == 2) {
                    if (d < 1/24.0)
                        return 10;
                    if (d < 2/24.0)
                        return 14;
                    if (d < 3/24.0)
                        return 15;
                    if (d < 4/24.0)
                        return 16;
                    if (d < 5/24.0)
                        return 21;
                    if (d < 6/24.0)
                        return 24;
                    if (d < 7/24.0)
                        return 27;
    
                    if (d < 9/24.0)
                        return 4;
                    if (d < 11/24.0)
                        return 5;
                    if (d < 13/24.0)
                        return 6;
                    if (d < 15/24.0)
                        return 7;
                    if (d < 17/24.0)
                        return 9;
                    if (d < 19/24.0)
                        return 12;
                    if (d < 21/24.0)
                        return 18;
                    return 8;
                } else if (fortune == 3) {
                    if (d < 1/30.0)
                        return 10;
                    if (d < 2/30.0)
                        return 14;
                    if (d < 3/30.0)
                        return 15;
                    if (d < 4/30.0)
                        return 20;
                    if (d < 5/30.0)
                        return 21;
                    if (d < 6/30.0)
                        return 27;
                    if (d < 7/30.0)
                        return 28;
                    if (d < 8/30.0)
                        return 32;
                    if (d < 9/30.0)
                        return 36;
    
                    if (d < 11/30.0)
                        return 4;
                    if (d < 13/30.0)
                        return 5;
                    if (d < 15/30.0)
                        return 6;
                    if (d < 17/30.0)
                        return 7;
                    if (d < 19/30.0)
                        return 9;
                    if (d < 21/30.0)
                        return 12;
                    if (d < 23/30.0)
                        return 16;
                    if (d < 25/30.0)
                        return 18;
                    if (d < 27/30.0)
                        return 24;
                    // 1/10 = 3/10
                    return 8;
                }
            }
            return 1;
        }
    }
    
     
  2. Offline

    The_Spaceman

    what about the Block#getDrops(ItemStack)?
     
  3. Offline

    MCMastery

    I'm pretty sure that method doesn't take fortune into account. I researched that method before and found it wouldn't give correct results. I forget the exact reason though
     
  4. Offline

    Xp10d3

    Question @MCMastery: Couldn't you just loop the level of fortune if for some random reason they have like fortune 1000? Just a thought.
     

Share This Page