Solved Changing the item a block drops.

Discussion in 'Plugin Development' started by StyL_TwisT, Feb 12, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    StyL_TwisT

    Hello,

    I'm trying to make it so if a player mines gold ore, or iron ore they will drop ingots.
    How can I change the drop from IRON/GOLD_ORE to IRON/GOLD_INGOT?
    I would like it so this would happen in the onEnable so that it won't mess with any of my code.

    Thanks,

    StyL TwisT
     
  2. Offline

    RealDope

    • Personal attacks = bad
    Are you dumb?

    How are you possibly going to listen for BlockBreakEvent inside your onEnable()? And what do you mean "mess with any of my code"? Unless your code is HORRIBLY put together, adding a 10 line listener isn't going to affect anything.
     
  3. Offline

    StyL_TwisT

    RealDope Sorry i got a little mixed up lol completely forgot about having to listen!xD

    This is my current code:
    Code:
    package me.styltwist.minepay;
     
    import java.util.HashMap;
     
    import net.milkbowl.vault.chat.Chat;
    import net.milkbowl.vault.permission.Permission;
    import org.bukkit.enchantments.Enchantment;
     
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.EventPriority;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
     
    public class MyBlockListener implements Listener {
        public static Permission perms = null;
        public static Chat chat = null;
        public static MinePay plugin;
        public static HashMap<Material, Integer> orelist = new HashMap<Material, Integer>();
     
        public MyBlockListener(MinePay instance) {
            plugin = instance;
         
            int diamond = plugin.getConfig().getInt("diamond");
            int coal = plugin.getConfig().getInt("coal");
            int gold = plugin.getConfig().getInt("gold");
            int iron = plugin.getConfig().getInt("iron");
            int emerald = plugin.getConfig().getInt("emerald");
            int redstone = plugin.getConfig().getInt("redstone");
            int lapis = plugin.getConfig().getInt("lapis");
         
            orelist.put(Material.COAL_ORE, coal);
            orelist.put(Material.DIAMOND_ORE, diamond);
            orelist.put(Material.GOLD_ORE, gold);
            orelist.put(Material.REDSTONE_ORE, redstone);
            orelist.put(Material.LAPIS_ORE, lapis);
            orelist.put(Material.EMERALD_ORE, emerald);
            orelist.put(Material.IRON_ORE, iron);
         
        }
     
        @EventHandler(priority=EventPriority.HIGH)
        public void onBlockBreak(BlockBreakEvent event){
                Material block = event.getBlock().getType();
                Player player = event.getPlayer();
                    if(orelist.containsKey(block)){
                        int Money = orelist.get(block);
                        if(block == Material.IRON_ORE){
                            if(player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)){
                            }else{
                                plugin.econ.depositPlayer(player.getName(), Money);
                                player.sendMessage("§b+ " + Money);
                            }
                    }
                }
            }
    }
     
     
     
    
    How can i add the listener to this without affecting anything?
     
  4. Offline

    Birdgeek3

  5. Offline

    StyL_TwisT

    I don't know how to remove a drop and then add another with that method, i have never used it before + I was wondering if i could implement it into my code without affecting the rest of it.
     
  6. Offline

    RealDope

    It's very counter-intuitive.

    To remove a drop:
    Code:JAVA
    1.  
    2. event.getDrops().remove(ItemStack);
    3.  

    To add a drop:
    Code:JAVA
    1.  
    2. event.getDrops().add(ItemStack);
    3.  


    Also don't send me a message telling me to read your reply after 10 minutes.
     
  7. Offline

    Zarius

    Unfortunately there is no "getDrops()" function on the BlockBreakEvent (see here). You need to cancel the event, manually drop the item and manually replace the block with air.

    I would change the listener to something like this:

    Code:
        // rename orelist to rewardOreList
        // add a "replaceOreList" and:
        replaceOreList.put(Material.IRON_ORE, Material.IRON_INGOT);
        // etc
     
     
     
        @EventHandler(priority=EventPriority.HIGH)
        public void onBlockBreak(BlockBreakEvent event){
            if (event.isCancelled()) return; // skip if the event has been cancelled.
        rewardPlayer(event);
            if (replaceOreList.has(event.getBlock().getMaterial())) replaceDrop(event);  // <- typed from memory, function calls may not be correct
        }
     
        public void replaceDrop(event) {
            block.getLocation.getWorld.dropItemNaturally(new ItemStack(replaceOreList.get(block.getMaterial));
            event.setCancelled(true);  // need to cancel to avoid the default drop
            block.setTo(Material.AIR); // need to replace block since the event has been cancelled.
        }
     
        public void rewardPlayer(BlockBreakEvent event) {
                Material block = event.getBlock().getType();
                Player player = event.getPlayer();
                    if(orelist.containsKey(block)){
                        int Money = orelist.get(block);
                        if(block == Material.IRON_ORE){
                            if(player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)){
                            }else{
                                plugin.econ.depositPlayer(player.getName(), Money);
                                player.sendMessage("§b+ " + Money);
                            }
                    }
                }
        }
     
    
    Note: a good bit of that is typed from memory so function names (eg. checking that the Map has a value) may not be quite correct.

    StyL_TwisT - did my suggestion on post #7 make sense?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
  8. Offline

    StyL_TwisT

    Well yes it did, BUT it started to get a little messy so i changed it up a little.
    I now have this:
    Code:
    package me.styltwist.minepay;
     
    import java.util.ArrayList;
    import java.util.HashMap;
    
    import net.milkbowl.vault.chat.Chat;
    import net.milkbowl.vault.permission.Permission;
    
    import org.bukkit.block.Block;
    import org.bukkit.enchantments.Enchantment;
    
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.EventPriority;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.inventory.ItemStack;
     
    public class MyBlockListener implements Listener {
        public static Permission perms = null;
        public static Chat chat = null;
        public static MinePay plugin;
        public static HashMap<Material, Integer> orelist = new HashMap<Material, Integer>();
        ArrayList<Material> ingot = new ArrayList<Material>();
        
        public MyBlockListener(MinePay instance) {
            plugin = instance;
            
            int diamond = plugin.getConfig().getInt("diamond");
            int coal = plugin.getConfig().getInt("coal");
            int emerald = plugin.getConfig().getInt("emerald");
            int redstone = plugin.getConfig().getInt("redstone");
            int lapis = plugin.getConfig().getInt("lapis");
            
            orelist.put(Material.COAL_ORE, coal);
            orelist.put(Material.DIAMOND_ORE, diamond);
            orelist.put(Material.REDSTONE_ORE, redstone);
            orelist.put(Material.LAPIS_ORE, lapis);
            orelist.put(Material.EMERALD_ORE, emerald);
            
        }
    
        @EventHandler(priority=EventPriority.HIGH)
        public void onBlockBreak(BlockBreakEvent event){
                Material block = event.getBlock().getType();
                Player player = event.getPlayer();
                    if(orelist.containsKey(block)){
                        int Money = orelist.get(block);
                            if(player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)){
                            }else{
                                plugin.econ.depositPlayer(player.getName(), Money);
                                player.sendMessage("§b+ " + Money);
                                
                            }
                    }else if(block == Material.IRON_ORE){
                        int iron = plugin.getConfig().getInt("iron");
                        if(player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)){
                            
                        }else{
                            event.getWorld().dropItemNaturally(event.getBlock().getLocation(), new ItemStack(Material.IRON_INGOT, 1));
                            event.setCancelled(true);
                            event.getBlock().setType(Material.AIR);
                            plugin.econ.depositPlayer(player.getName(), iron);
                            player.sendMessage("§b+ " + iron);
                        }
                    }else if(block == Material.GOLD_ORE){
                        int gold = plugin.getConfig().getInt("gold");
                        if(player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)){
                            
                        }else{
                            event.getWorld().dropItemNaturally(event.getBlock().getLocation(), new ItemStack(Material.GOLD_INGOT, 1));
                            event.setCancelled(true);
                            event.getBlock().setType(Material.AIR);
                            plugin.econ.depositPlayer(player.getName(), gold);
                            player.sendMessage("§b+ " + gold);
                        }
                }
            }
    }
        
        
    
    
    BUT i have one error, (on getWorld, in the two "}else if" statements, for gold and iron)
    Is there any way I can fix that or am i doing this wrong? :S

    Anyone?
    Know how I could fix the code above?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
  9. Offline

    Zarius

    That's because there's no .getWorld() for the event - you need to use event.getBlock().getLocation().getWorld() I believe.

    Are you using an IDE or just a text editor? I'd second microgeek's suggestion and suggest an IDE like Eclipse or Netbeans (I use Eclipse) - might take a while to set up but the autocomplete is awesome and well worth it (ie. you type event. and it will list a drop down of all possible functions).

    Also, I'd avoid duplicating the money giving code. Now if you want to do something different or change the message you need to do it in three places. I'll post an example using a new class shortly.
     
  10. Offline

    StyL_TwisT

    I removed iron and gold from the orelist and everything worked fine besides the drop.
     
  11. Offline

    Zarius

    Try this:

    Code:
    public class MyBlockListener implements Listener {
           
            class BreakReward {
                    Integer money;
                    Material toDrop;
                   
                    BreakReward(Integer passMoney, Material passToDrop) {
                            this.money = passMoney;
                            this.toDrop = passToDrop;
                    }
                   
            }
           
        public static Permission perms = null;
        public static Chat chat = null;
        public static OtherDrops plugin;
        public static Map<Material, BreakReward> orelist = new HashMap<Material, BreakReward>();
       
        public MyBlockListener(OtherDrops instance) {
            plugin = instance;
           
            FileConfiguration config = plugin.getConfig();
           
            orelist.put(Material.COAL_ORE,    new BreakReward(config.getInt("coal)"), null));
            orelist.put(Material.DIAMOND_ORE,  new BreakReward(config.getInt("diamond)"), null));
            orelist.put(Material.REDSTONE_ORE, new BreakReward(config.getInt("redstone)"), null));
            orelist.put(Material.LAPIS_ORE,    new BreakReward(config.getInt("lapis)"), null));
            orelist.put(Material.EMERALD_ORE,  new BreakReward(config.getInt("emerald)"), null));
            orelist.put(Material.IRON_ORE,  new BreakReward(config.getInt("iron)"), Material.IRON_INGOT));
            orelist.put(Material.GOLD_ORE,  new BreakReward(config.getInt("gold)"), Material.GOLD_INGOT));
           
        }
     
        @EventHandler(priority=EventPriority.HIGH)
        public void onBlockBreak(BlockBreakEvent event){
            Material block = event.getBlock().getType();
            Player player = event.getPlayer();
            if (orelist.containsKey(block)){
                    BreakReward reward = orelist.get(block);
                    if (player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
                    } else {
                            giveMoney(reward.money, player);
                    }
                   
                    if (reward.toDrop != null) {
                            event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), new ItemStack(reward.toDrop, 1));
                            event.setCancelled(true);
                            event.getBlock().setType(Material.AIR);
                    }                     
            }
        }
     
            private void giveMoney(Integer money, Player player) {
                    plugin.econ.depositPlayer(player.getName(), money);
                    player.sendMessage("§b+ " + money);           
            }
    }
    
    Having the separate reward class allows you more flexibility and it should be easy for you to add new blocks/reward/drops now.

    Separating the "giveMoney" bit makes it easier later, for example in the silktouch section you might want to use giveMoney(reward.money * enchantmentLevel) or something like that. This way the actual giving of money and message is still just in one place - less chance of bugs and easier to update later.

    @ Anyone - noticed I usually use Map<k, v> blah = new HashMap<k, v>(); whereas StyL_TwisT used HashMap<k, v> blah = new HashMap<k, v>();

    Is there much (if any) difference between the two?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
  12. Offline

    c0mp

    Mopped up off-topic discussion about rules, snarky responses, et cetera. I see the thread is already solved, but if the discussion does continue, let's ensure that it stays on topic, please and thank you.
     
    Lactem likes this.
Thread Status:
Not open for further replies.

Share This Page