diff --git a/src/main/java/net/glowstone/block/GlowBlock.java b/src/main/java/net/glowstone/block/GlowBlock.java index a2eb638b18..316df24439 100644 --- a/src/main/java/net/glowstone/block/GlowBlock.java +++ b/src/main/java/net/glowstone/block/GlowBlock.java @@ -450,6 +450,10 @@ public String toString() { * @return true if the block was destroyed */ public boolean breakNaturally(float yield) { + return breakNaturally(yield, ItemTable.instance().getBlock(getType()).getMinedDrops(this)); + } + + public boolean breakNaturally(float yield, Collection drops) { Random r = new Random(); if (getType() == Material.AIR) { @@ -457,8 +461,7 @@ public boolean breakNaturally(float yield) { } Location location = getLocation(); - Collection toDrop = ItemTable.instance().getBlock(getType()).getMinedDrops(this); - toDrop.stream().filter(stack -> r.nextFloat() < yield).forEach(stack -> getWorld().dropItemNaturally(location, stack)); + drops.stream().filter(stack -> r.nextFloat() < yield).forEach(stack -> getWorld().dropItemNaturally(location, stack)); setType(Material.AIR); return true; @@ -471,8 +474,9 @@ public boolean breakNaturally() { @Override public boolean breakNaturally(ItemStack tool) { - if (!getDrops(tool).isEmpty()) { - return breakNaturally(); + Collection drops = getDrops(tool); + if (!drops.isEmpty()) { + return breakNaturally(1.0f, drops); } else { return setTypeId(Material.AIR.getId()); } diff --git a/src/main/java/net/glowstone/block/ItemTable.java b/src/main/java/net/glowstone/block/ItemTable.java index 9e46537eb4..0567cd5203 100644 --- a/src/main/java/net/glowstone/block/ItemTable.java +++ b/src/main/java/net/glowstone/block/ItemTable.java @@ -98,19 +98,19 @@ private void registerBuiltins() { reg(Material.MOSSY_COBBLESTONE, new BlockDirectDrops(ToolType.PICKAXE)); reg(Material.STONE, new BlockStone()); reg(Material.OBSIDIAN, new BlockDirectDrops(ToolType.DIAMOND_PICKAXE)); - reg(Material.COAL_ORE, new BlockDirectDrops(Material.COAL, ToolType.PICKAXE)); + reg(Material.COAL_ORE, new BlockOre(Material.COAL, ToolType.PICKAXE)); reg(Material.COAL_BLOCK, new BlockDirectDrops(ToolType.PICKAXE)); reg(Material.IRON_ORE, new BlockDirectDrops(ToolType.STONE_PICKAXE)); reg(Material.IRON_BLOCK, new BlockDirectDrops(ToolType.STONE_PICKAXE)); reg(Material.GOLD_ORE, new BlockDirectDrops(ToolType.IRON_PICKAXE)); reg(Material.GOLD_BLOCK, new BlockDirectDrops(ToolType.IRON_PICKAXE)); - reg(Material.DIAMOND_ORE, new BlockDirectDrops(Material.DIAMOND, ToolType.IRON_PICKAXE)); + reg(Material.DIAMOND_ORE, new BlockOre(Material.DIAMOND, ToolType.IRON_PICKAXE)); reg(Material.DIAMOND_BLOCK, new BlockDirectDrops(ToolType.IRON_PICKAXE)); - reg(Material.EMERALD_ORE, new BlockDirectDrops(Material.EMERALD, ToolType.IRON_PICKAXE)); + reg(Material.EMERALD_ORE, new BlockOre(Material.EMERALD, ToolType.IRON_PICKAXE)); reg(Material.EMERALD_BLOCK, new BlockDirectDrops(ToolType.PICKAXE)); - reg(Material.LAPIS_ORE, new BlockRandomDrops(Material.INK_SACK, 4, 4, 8, ToolType.STONE_PICKAXE)); + reg(Material.LAPIS_ORE, new BlockOre(Material.INK_SACK, ToolType.STONE_PICKAXE, 4, 4, 8)); reg(Material.LAPIS_BLOCK, new BlockDirectDrops(ToolType.STONE_PICKAXE)); - reg(Material.QUARTZ_ORE, new BlockDirectDrops(Material.QUARTZ, ToolType.PICKAXE)); + reg(Material.QUARTZ_ORE, new BlockOre(Material.QUARTZ, ToolType.PICKAXE)); reg(Material.REDSTONE_ORE, new BlockRedstoneOre()); reg(Material.GLOWING_REDSTONE_ORE, new BlockLitRedstoneOre()); reg(Material.REDSTONE_BLOCK, new BlockDirectDrops(ToolType.PICKAXE)); diff --git a/src/main/java/net/glowstone/block/blocktype/BlockDirectDrops.java b/src/main/java/net/glowstone/block/blocktype/BlockDirectDrops.java index a9782f4314..8b88d54f29 100644 --- a/src/main/java/net/glowstone/block/blocktype/BlockDirectDrops.java +++ b/src/main/java/net/glowstone/block/blocktype/BlockDirectDrops.java @@ -53,7 +53,7 @@ protected MaterialMatcher getNeededMiningTool(GlowBlock block) { return neededTool; } - private ItemStack getDrops(GlowBlock block) { + protected ItemStack getDrops(GlowBlock block) { if (dropType == null) { return new ItemStack(block.getType(), amount, block.getData()); } else { diff --git a/src/main/java/net/glowstone/block/blocktype/BlockNeedsTool.java b/src/main/java/net/glowstone/block/blocktype/BlockNeedsTool.java index 9c2c387ad1..3b5971febb 100644 --- a/src/main/java/net/glowstone/block/blocktype/BlockNeedsTool.java +++ b/src/main/java/net/glowstone/block/blocktype/BlockNeedsTool.java @@ -8,7 +8,7 @@ public abstract class BlockNeedsTool extends BlockType { @Override - public final Collection getDrops(GlowBlock block, ItemStack tool) { + public Collection getDrops(GlowBlock block, ItemStack tool) { MaterialMatcher neededTool = getNeededMiningTool(block); if (neededTool != null && (tool == null || !neededTool.matches(tool.getType()))) diff --git a/src/main/java/net/glowstone/block/blocktype/BlockOre.java b/src/main/java/net/glowstone/block/blocktype/BlockOre.java new file mode 100644 index 0000000000..42d15769ff --- /dev/null +++ b/src/main/java/net/glowstone/block/blocktype/BlockOre.java @@ -0,0 +1,102 @@ +package net.glowstone.block.blocktype; + +import net.glowstone.block.GlowBlock; +import net.glowstone.inventory.MaterialMatcher; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +public class BlockOre extends BlockNeedsTool { + private final Material dropType; + private final MaterialMatcher neededTool; + private final int minCount, maxCount; + private final int data; + + public BlockOre(Material dropType, MaterialMatcher neededTool, int data, int minCount, int maxCount) { + this.dropType = dropType; + this.neededTool = neededTool; + this.minCount = minCount; + this.maxCount = maxCount; + this.data = data; + } + + public BlockOre(Material dropType, MaterialMatcher neededTool, int data, int count) { + this(dropType, neededTool, data, count, count); + } + + public BlockOre(Material dropType, MaterialMatcher neededTool, int data) { + this(dropType, neededTool, data, 1); + } + + public BlockOre(Material dropType, MaterialMatcher neededTool) { + this(dropType, neededTool, 1, 1); + } + + public Collection getDrops(GlowBlock block, ItemStack tool) { + ThreadLocalRandom random = ThreadLocalRandom.current(); + int count = minCount; + if (maxCount > minCount) { + count += random.nextInt(maxCount - minCount); + } + ItemStack stack = new ItemStack(dropType, count, (short) data); + if (tool == null) { + return Collections.unmodifiableList(Arrays.asList(stack)); + } + Collection drops = super.getDrops(block, tool); + if (drops.size() == 0) { + return drops; + } + if (tool.containsEnchantment(Enchantment.LOOT_BONUS_BLOCKS)) { + stack.setAmount(count * getMultiplicator(random, tool.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS))); + } + return Collections.unmodifiableList(Arrays.asList(stack)); + } + + @Override + public Collection getMinedDrops(GlowBlock block) { + return getDrops(block, null); + } + + @Override + protected MaterialMatcher getNeededMiningTool(GlowBlock block) { + return neededTool; + } + + private int getMultiplicator(Random random, int level) { + if (level <= 0) { + return 1; + } + double r = random.nextDouble(); + if (level == 1) { + if (r < 0.33) { + return 2; + } + } + if (level == 2) { + if (r < 0.25) { + return 2; + } + if (r < 0.5) { + return 3; + } + } + if (level == 3) { + if (r < 0.2) { + return 2; + } + if (r < 0.4) { + return 3; + } + if (r < 0.6) { + return 4; + } + } + return 1; + } +}