Solved Auto Smelt Help

Discussion in 'Plugin Development' started by andrewginn, Apr 6, 2016.

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

    andrewginn

    Hi there,

    I'm new to coding and I've been testing different listeners so I can reach my goal on making a custom enchant plugin. Anyways, I was wondering since I have managed to make it so when a player mines a block it goes into his inventory, now what I want is when that block enters that person's inventory it checks if that block is what I have stated in the code I am about to show, then if that block is the block which is stated it will get smelted. But I do not know the code for that, here is my code
    Code:
          @EventHandler
          public void Pickupitem(PlayerPickupItemEvent e){
              ItemStack item = new ItemStack(Material.IRON_ORE);
              if(e.getItem().getItemStack().equals(item)){
    Note I have left it at there since I do not know the code for smelting blocks in the players inventory ^ even after looking on google
     
  2. Offline

    DoggyCode™

    ItemStack smelted new ItemStack(Material.IRON_INGOT);
    ^ that is the smelted version of the ore, and that you should already know from playing mine craft xD. So you would use the
    p.getInventory().removeItem(item);
    p.getInventory().addItem(smelted);

    You could also have a timer before executing the code above so it actually takes time before it smelt, rather than just having it smelt instantly.

    I'd make a Utils class making a smelt method if you wanna do the above multiple times ;) Making a SmeltItem also object should work, and you can do all the functionality in there.
     
  3. Offline

    andrewginn

    Alright literally it popped into my head, remove the ore insert the ingot, I don't have a coders brain yet xD

    Also what do you mean by the smeltitem? I understand the rest :)

    EDIT: Also I know this is a dumb question but I just forgot how I would link the classes together so all the events work together? xD
    @DoggyCode™
     
  4. Offline

    DoggyCode™

    Have you learned about creating an object in Java? Read!: http://www.tutorialspoint.com/java/java_object_classes.htm
     
  5. Offline

    andrewginn

    Ahh yes I have seen this, I'm not 100% sure on it tho xD I understand it because I read the simple stuff just a bit confused on how it works aha @DoggyCode™

    Alright so I got the item>smelt perfectly but a little bug, when there is one iron ore left and I pick it up it gives the iron ingot but does not remove the iron ore? therefore I can get infinite iron ingots, also if I pickup more than 1 of ironore in 1 go it does not smelt anything, I guess this is debugging huh xD @DoggyCode™

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.

    Thanks mod ^
     
    Last edited: Apr 6, 2016
  6. Offline

    DoggyCode™

    Let me show you how you could do this. If you don't learn, I swear. Do not just copy, read

    Make a new class called SmeltItem

    Code:
    public class SmeltItem {
    
    private int timer = 3;
    private ItemStack item;
    private Material ItemStack resultItem;
    
    public SmeltItem(ItemStack itemToSmelt){
      this.item = itemToSmelt;
      switch(itemToSmelt.getType()){
        case Material.IRON_ORE:
          this.resultItem = Material.IRON_INGOT;
          break;
        default:
          throw new NullPointerException("Item is a invalid smelt");
      }
    
    public ItemStack getSmeltedItem(){
        return new ItemStack(this.resultItem, 1);
      }
    }
    Now in your event handler use:
    Code:
    SmeltItem smeltItem = new SmeltItem(item);
    p.getInventory().removeItem(item);
    p.getInventory().addItem(smeltItem.getSmeltedItem());
    I'm sorry if this isn't the best code, I wrote this on my iPad. You could also possibly add a timer as I mentioned earlier.

    Therefore you should have a timer, so we can be sure that the item is in the inventory and read to be smelted. I can't show you how to do this now as I'm on a ipad

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Apr 6, 2016
  7. Offline

    andrewginn

    Alright, thank you for the code, just to prove I haven't copied - the timer I am guessing is in 3 seconds and you have created a itemstack called item, then you have created a material which contains the itemstack resultitem? Or are they added together? Then there is a new method which is casted to itemstack and itemtosmelt? this.item is the itemstack from the other method and would be the item to smelt such as the iron ore, then you used a switch thinking that in the future I will need to add more? Because there are no other alternatives, then you put case so the switch would choose from the list of the case? Then you have put the result item as the iron ingot to present it being smelted then you used the break to end the loop, I don't know what a throw is, then you put new to create a instance/array which is the code afterwards? with a message. Then you made a new method, with return to finish the whole method and then finally give 1 iron ingot, in the event handler it is looking for the event to run and then executes the commands.

    If I go wrong somewhere please tell me xD @DoggyCode™

    Edit:
    I got a few errors with the resultItem and on the case Material.IRON_ORE:
    And on my event handler the "item" variables are having red lines underneath them
     
    Last edited: Apr 6, 2016
    DoggyCode™ likes this.
  8. Offline

    mine-care

    That isn't really the apropriate exception type since nothing here is null. Throw an IllegalArgumentException instead.
    Also do not spoonfeed code! Please read: https://bukkit.org/threads/plugin-d...ules-of-the-plugin-development-forums.409700/
    After you read, see the evidence:
    Anyways, in response to the thread:

    Prefer to compare enums with == instead of .equals(Object param); because unlike objects it behaves just as .equals but is null-proof :p

    Now about your question, your code serves its purpose. Here you need to asert wether or not it is efficient to create a 'table' with the ore and the smelt item, or if it is better to just have 1/2/3 if statements to check instead.
    So if you plan to do that for all ores and smeltables, you may want to consider using a map with the values (ore and result after smelting) and then access it when the event fires.
    On the other hand, if we are talking about 1-2-3 ores, then you can simply check if it is lets say iron-ore and if it is turn it into an Iron ingot.
     
  9. Offline

    andrewginn

    Alright so I didn't copy what @DoggyCode™ did and I made my own, I know it's nothing like his but I'm just trying out and I want to learn. Here is my code
    Code:
    package me.andrew.reward;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    
    
    public class main extends JavaPlugin implements Listener{
        @Override
        public void onEnable() {
            Bukkit.getPluginManager().registerEvents(this, this);
            getLogger().info("Plugin has been Enabled!");
           
        }
        @Override
        public void onDisable() {
            getLogger().info("Plugin has been Disabled!");
    
        }
       
        @EventHandler
        public void onBlockBreak(BlockBreakEvent e) {
             Block b = e.getBlock();
             Player p = e.getPlayer();
             for(ItemStack item : b.getDrops()) {
                 p.getInventory().addItem(item);
                
             }
           
          }
       
        @EventHandler
        public void onBlockBreak1(BlockBreakEvent e) {
             ItemStack item = new ItemStack(Material.IRON_ORE);
             ItemStack itemone = new ItemStack(Material.IRON_INGOT);
             Player p = e.getPlayer();
             if(e.getBlock().getType().equals(Material.IRON_ORE)){
                 p.getInventory().removeItem(item);
                 p.getInventory().addItem(itemone);
                
             }
            
                 
        }
    }
    But now I get 2 errors, the blocks don't go into my inventory when I mine it, and the other is I do not get a iron ingot, I have a idea and could do that be the return true/false at the end of my code? Don't want to touch anything unless I ruin it even more, if you could help by saying what I need to do instead of providing me the code that would be great.
     
  10. Offline

    CraftCreeper6

    @andrewginn
    First and for most, follow Java Naming Conventions, all classes should start with an uppercase. Why do you have 2 block break events?

    Use a switch statement for ores into ingots (Unless there's a method that I don't know about). It's possible that there is an issue with having two events fired from the same action.
     
  11. Offline

    andrewginn

    @CraftCreeper6 I have changed the class to a uppercase, I have 2 block break events since I did not know you could make 1 event do all the things for you? I shall try what you said now
     
  12. Offline

    Gonmarte

    Just dont please....
    [​IMG]
     
    DoggyCode™ likes this.
  13. Offline

    andrewginn

  14. Offline

    CraftCreeper6

    @andrewginn
    What does it say? The error?

    EDIT: Remove Material. from the start
     
  15. Offline

    andrewginn

    So that should now work? @CraftCreeper6 I removed the Material but will it still recognize that itemone is the same as Iron_ore?
     
  16. Offline

    CraftCreeper6

  17. Offline

    andrewginn

  18. Offline

    CraftCreeper6

    @andrewginn
    Then that's good.

    For each case of the switch statement, if a condition is met where it is an ore, add the itemstack of the corresponding ore as an ingot to the players inventory.
     
  19. Offline

    andrewginn

    @CraftCreeper6 Got a slight issue, when I break a block for instance sand, I get the sand block but also a iron ingot? Here is my code
    Code:
    package me.andrew.reward;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    
    
    public class Main extends JavaPlugin implements Listener{
        @Override
        public void onEnable() {
            Bukkit.getPluginManager().registerEvents(this, this);
            getLogger().info("Plugin has been Enabled!");
           
        }
        @Override
        public void onDisable() {
            getLogger().info("Plugin has been Disabled!");
    
        }
       
        @EventHandler
        public void onBlockBreak(BlockBreakEvent e) {
             Block b = e.getBlock();
             Player p = e.getPlayer();
             ItemStack itemone = new ItemStack(Material.IRON_ORE);
             ItemStack itemtwo = new ItemStack(Material.IRON_INGOT);
             for(ItemStack item : b.getDrops()){
                 b.setType(Material.AIR);
                  p.getInventory().addItem(item);
                }
                  switch(itemone.getType()){
                    case IRON_ORE:
                        p.getInventory().removeItem(itemone);
                        p.getInventory().addItem(itemtwo);
                        break;
                    case COAL_ORE:
                        break;
                    default:
                        break;
        
             }
           
          }
                
             }
            
                  
     
  20. Offline

    CraftCreeper6

    @andrewginn
    Your formatting is horrible. Please format your code and send it again.
     
  21. Offline

    andrewginn

  22. Offline

    mcdorli

    If you use eclipse then Ctrl+Shift+F, if you use intellij, then ctrl+alt+L
     
  23. Offline

    andrewginn

    Here is my new one @mcdorli @CraftCreeper6
    Code:
    package me.andrew.reward;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin implements Listener {
        @Override
        public void onEnable() {
            Bukkit.getPluginManager().registerEvents(this, this);
            getLogger().info("Plugin has been Enabled!");
    
        }
    
        @Override
        public void onDisable() {
            getLogger().info("Plugin has been Disabled!");
    
        }
    
        @EventHandler
        public void onBlockBreak(BlockBreakEvent e) {
            Block b = e.getBlock();
            Player p = e.getPlayer();
            ItemStack itemone = new ItemStack(Material.IRON_ORE);
            ItemStack itemtwo = new ItemStack(Material.IRON_INGOT);
            for (ItemStack item : b.getDrops()) {
                b.setType(Material.AIR);
                p.getInventory().addItem(item);
            }
            switch (itemone.getType()) {
            case IRON_ORE:
                p.getInventory().removeItem(itemone);
                p.getInventory().addItem(itemtwo);
                break;
            case COAL_ORE:
                break;
            default:
                break;
    
            }
        }
    }
    This is my issue: Got a slight issue, when I break a block for instance sand, I get the sand block but also a iron ingot? Here is my code
     
  24. Offline

    mcdorli

    Why do you check for itemone's material? Ypu already know that, and you never change it.
     
  25. Offline

    andrewginn

  26. Offline

    mcdorli

    Code:
    onBlockBreak(BlockBreakEvent e) {
            Block b = e.getBlock();
            Player p = e.getPlayer();
            ItemStack itemone = new ItemStack(Material.IRON_ORE);
            ItemStack itemtwo = new ItemStack(Material.IRON_INGOT);
            for (ItemStack item : b.getDrops()) {
                b.setType(Material.AIR);
                p.getInventory().addItem(item);
            }
            switch (itemone.getType()) {
            case IRON_ORE:
                p.getInventory().removeItem(itemone);
                p.getInventory().addItem(itemtwo);
                break;
            case COAL_ORE:
                break;
            default:
                break;
    
            }
        }
    
    Here.

    If you still can't understand, then go trough the code, and say out loud what it should do and what it does.
     
  27. Offline

    andrewginn

    The Itemstack itemone is like a alias in code for the material.IRON_ORE therefore if I state that it will == the same as material.IRON_ORE
    Same for the itemtwo itemstack
    the next part is a loop where it will get the drops of what the item broken gives and it cancels the drop and gets the players inventory and adds the drops, on the switch I am looking for the same value as itemone which is material.IRON_ORE but the case does not accept the material. part therefore IRON_ORE is there, and then after that if the value of itemone matches IRON_ORE it will run those 2 codes underneath which will remove the iron ore and give the iron ingot, the break is that if It matches that value it will not have to scan through any more of the cases. I have not done for the other ores yet since I have not got the iron ore working. @mcdorli

    Ohh I get what u mean in the switch. I did that because I do not know what else to put in there, no one has told me and I haven't seen any videos or pages about it.

    @CraftCreeper6 Can you still help?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Apr 6, 2016
  28. Offline

    CraftCreeper6

    @andrewginn
    Is it still not working? Just the auto smelt? Let me run down a list of things you need to do.

    • Create an event to check when you break a block
    • Run the block type through a switch statement to check if it is an ore
    • If it's an ore, replace it with an ingot (Does this work?)
    • Create a default case for the switch statement that breaks from the switch statement.
     
  29. Offline

    andrewginn

    @CraftCreeper6

    Okay so I just did a test, I made a new java project with the things you told me to do from the above ^, it was all working and then I implemented that code into my old one which from which I was trying to get blocks into the inventory and autosmelt, something must be colliding but I am not sure. If you could help that would be great,
    here is my code
    Code:
    package me.andrew.reward;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin implements Listener {
        @Override
        public void onEnable() {
            Bukkit.getPluginManager().registerEvents(this, this);
    
        }
    
        @EventHandler
        public void onBlockBreak(BlockBreakEvent e) {
            Block b = e.getBlock();
            Player p = e.getPlayer();
            ItemStack itemone = new ItemStack(Material.IRON_ORE);
            ItemStack itemtwo = new ItemStack(Material.IRON_INGOT);
            for (ItemStack item : b.getDrops()) {
                b.setType(Material.AIR);
                p.getInventory().addItem(item);
                switch (itemone.getType()) {
                case IRON_BLOCK:
                    p.getInventory().removeItem(itemone);
                    p.getInventory().addItem(itemtwo);
                    break;
                default:
                    break;
    
                }
            }
        }
    }
    @CraftCreeper6
     
  30. Offline

    CraftCreeper6

    @andrewginn
    You say it's a problem with the project? Just start a new one, it happens sometimes where there is a glitch in the project, I don't think it's fixable.
     
Thread Status:
Not open for further replies.

Share This Page