Solved Iterating through enum

Discussion in 'Spigot Plugin Development' started by SuperBroodje, Apr 13, 2017.

  1. Hi,

    I'm creating a plugin and I need some help, simply what I need:

    I got an enum with the following template in it:
    Code (Text):
    // material, data, level, points, tool
        FARMLAND(Material.SOIL, 0, 1, 0, Material.WOOD_SPADE),
    When a player breaks a block, it must check his level, job and the tool he uses, I use the enum to save te block data in. When a player breaks a block what isn't the needed job, it checks what job needed and sends a message to the player what job he needs. The only problem is that it always says you need another job and spams the chat:

    [​IMG]

    I already tried to use break and return methods, this is the code:

    Code (Text):
    package nl.themelvin.minenation.blocks;

    import org.bukkit.Chunk;
    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 nl.themelvin.minenation.MainClass;
    import nl.themelvin.minenation.api.API;
    import nl.themelvin.minenation.api.MessagesAPI;
    import nl.themelvin.minenation.cooldowns.Cooldowns;
    import nl.themelvin.minenation.enums.blocks.Algemeen;
    import nl.themelvin.minenation.enums.blocks.BoerData;
    import nl.themelvin.minenation.enums.blocks.BouwerData;
    import nl.themelvin.minenation.enums.blocks.HouthakkerData;
    import nl.themelvin.minenation.enums.blocks.MinerData;
    import nl.themelvin.minenation.enums.blocks.SmidData;

    public class MinerEvent implements Listener {
       
        @EventHandler
        public void onBreak(BlockBreakEvent e) {
            Player p = e.getPlayer();
            String baan = API.getBaanNoColor(p);
            Chunk chunk = e.getBlock().getLocation().getChunk();
            ItemStack blonkie = new ItemStack(e.getBlock().getType(), 1, (short) e.getBlock().getData());
            if(baan.equals("&3Mijnwerker")) {
               

                if(Cooldowns.tryCooldown(p, "BlockBreak", API.getCooldown(p))) {
                   
                    if(!API.getChunkIsClaimed(chunk) || !API.getChunkInfoEigenaar(chunk).equals(API.getTeamNaam(p))) {
                       
                        e.setCancelled(true);
                        p.sendMessage("§cOm deze actie uit te kunnen voeren moet je zijn toegevoegd op deze chunk!");
                        Cooldowns.removeCooldowns(p);  
                       
                    } else {
                       
                                         // When player is a miner, it will iterate through all the MinerData values and check their level etc.
                        for(MinerData miner : MinerData.values()) {
                           
                            ItemStack enumblok = new ItemStack(miner.getMaterial(), 1, (short) miner.getData());
                           
                            if(enumblok == blonkie) {
                           
                                if(API.getLevel(p) < miner.getLevel()) {
                                   
                                                                 // Player has the wrong level

                                    e.setCancelled(true);
                                    p.sendMessage("§cOm dit te kunnen doen moet je minimaal level §4" + miner.getLevel() + " §3Mijnwerker" + " §czijn.");
                                    Cooldowns.removeCooldowns(p);  
                                   
                                }
                               
                                if(API.getLevel(p) >= miner.getLevel()) {
                                   
                                    if(!p.getInventory().getItemInMainHand().equals(miner.getTool()) || !p.getInventory().getItemInOffHand().equals(miner.getTool())) {
                                       
                                                                           // Player uses the wrong tool

                                        e.setCancelled(true);
                                        p.sendMessage("§cOm dit te kunnen doen zal je gebruik moeten maken van een §c" + miner.getTool().toString() + " §c.");
                                        Cooldowns.removeCooldowns(p);
                                       
                                    } else {
                                       
                                                                            // Add XP to the player when everything is fine

                                        API.setXP(p, API.getXP(p) - miner.getPunten());
                                       
                                    }
                                   
                                }
                               
                            } else {
                               
                                                        // If the block is not in the MinerData, check in what Data it is

                                if(enumblok != blonkie) {

                                                            // 'Algemeen' has blocks everyone can break

                                for(Algemeen alg : Algemeen.values()) {
                                   
                                    ItemStack algemeen = new ItemStack(alg.getMaterial(), 1, (short) alg.getData());
                                   
                                                                    // If broken block is not equal to values in 'Algemeen'

                                    if(algemeen != blonkie) {
                                       
                                        String beroep = "§7None";
                                       
                                                                              // Check first job
                                        for(BoerData boer : BoerData.values()) {                                  
                                            ItemStack boeritem = new ItemStack(boer.getMaterial(), 1, (short) boer.getData());                                      
                                            if(boeritem == blonkie) {
                                                beroep = "§6Boer";
                                            }                      
                                        }
                                       
                                                                               // Check next job
                                        for(BouwerData boer : BouwerData.values()) {
                                            ItemStack boeritem = new ItemStack(boer.getMaterial(), 1, (short) boer.getData());
                                            if(boeritem == blonkie) {
                                                beroep = "§eBouwer";
                                            }
                                        }
                               
                                                                               // Check next job      
                                        for(HouthakkerData boer : HouthakkerData.values()) {
                                            ItemStack boeritem = new ItemStack(boer.getMaterial(), 1, (short) boer.getData());
                                            if(boeritem == blonkie) {              
                                                beroep = "§2Houthakker";
                                            }
                                        }
                                       
                                                                               // Check next job
                                        for(SmidData boer : SmidData.values()) {
                                            ItemStack boeritem = new ItemStack(boer.getMaterial(), 1, (short) boer.getData());
                                            if(boeritem == blonkie) {
                                                beroep = "§5Smid";
                                            }
                                        }
                                       
                                                 // Cancelling the event and sending the message

                                        p.sendMessage("§cYou need to be a " + beroep + "§c.");
                                        e.setCancelled(true);
                                        Cooldowns.removeCooldowns(p);
                                    }

                                }
                           
                            }
                               
                        }
                    }

                           
                }} else {
                   
                                    // Player is on cooldown

                    e.setCancelled(true);
                    long cooldown = (Cooldowns.getCooldown(p, "BlockBreak") / 1000);
                    String cool = Long.toString(cooldown);
                    p.sendMessage(MessagesAPI.Cooldown.replaceAll("%TIJD%", cool));
                   
                }
       
            }
        }
        }

     

    I hope someone can help me
     
  2. Its spams the message, because you loop through every entry of "Algemeen"
    Beginning at this section:


    // 'Algemeen' has blocks everyone can break

    for(Algemeen alg : Algemeen.values()) {
     
  3. inside the for loop, you could check if the material is the one you are looking for, if it is, use
    Code (Java):
    break;
    //or
    return;
    to exit the loop.
     
  4. So, with using return I fixed the issue with the spam, but when I break a grass block (which is configured as Miner in the enum) it still says None.
     
    • Don't compare objects with ==, use Object::equals(Object)
      • Enums and primitives (byte, short, char, int, long, float, double, boolean) are compared using ==
    • Don't wrap your Block in an ItemStack, just directly compare the Material/data
    • Don't abuse static, you're relying on it way too much. Create instances of classes and pass them around.
    • Instead of iterating over the enum, use a Map<Material-data-tuple, YourEnumType> for faster lookups
      • Obviously, you need to create your own class to store the Material-data-tuple.
      • (As an additional note, it's fine to store that in a static field inside the enum class)
    • Use
      Code (Java):
      if (!statement) {
          // Code
          return;
      }
      Over
      Code (Java):
      if (statement) {
         
      } else {
          // Code
      }
      to reduce nesting depth (code becomes easier to read/follow)
    • Store jobs (translation of 'baan', for you non-Dutch folk) as enums instead of Strings, for faster comparison, and reduced chances of errors (like typos)
    • Use ChatColor instead of section sign (§) (either constants like ChatColor.RED or ChatColor.translateAlternateColorCodes('&', string))
    • Use interfaces to abstract the block enums, it'll allow you to simply fetch the players job, grab the right enum, and check whether they can even break the block. For example:
      Code (Java):
      interface BlockEnum {
          boolean canBreak(Job job);
      }
      (where Job is an enumeration of jobs)
    • Use String::replace(String, String) when replacing literals (non regex Strings), String::replaceAll(String, String) is for regex
     
    • Agree Agree x 2
    • Like Like x 1
  5. Thank you very much for your help, I fixed it now!