Avoiding if else statements

Discussion in 'Spigot Plugin Development' started by Wapic, May 14, 2017.

  1. A friend and I have been trying to create a plugin. We've come to a point where it's very hard read and edit.
    I was wondering how we could rewrite the code but avoid using a shit ton of if else statements.
    I've been looking around and from what I've seen It's either using HashMaps or Instances/Enums
    I was hoping someone could explain how I would implement it.

    here's how the code looks right now.
    a lot of the code is probably broken right now.
    Code (Text):

    package com.animeiswrong;

    import java.util.Arrays;
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.scheduler.BukkitTask;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.inventory.PlayerInventory;

    //TODO: Tidy code please
    public class BlockListener implements Listener{

        private final main plugin;
        static int x, y, z, MineLevel;
        static String world;
        static BukkitTask sb, so;
        static short d;
        static String p;
        PlayerInventory gPi;
     
        public BlockListener(main plugin){
            this.plugin = plugin;
            plugin.getServer().getPluginManager().registerEvents(this, plugin);
        }
     
        @SuppressWarnings("deprecation")
        @EventHandler
        public void onBlockBreakEvent(BlockBreakEvent e) {
        if(!e.getPlayer().isOp()){
        p = e.getPlayer().getName();
        MineLevel = SQL.getLevel(p);
        Material gBlock = e.getBlock().getType();
        x = e.getBlock().getLocation().getBlockX();  
        y = e.getBlock().getLocation().getBlockY();  
        z = e.getBlock().getLocation().getBlockZ();
        world = e.getPlayer().getWorld().getName();
        Block block = Bukkit.getWorld(world).getBlockAt(x, y, z);
        gPi = e.getPlayer().getInventory();
        Material gi = e.getPlayer().getItemInHand().getType();
        d = block.getState().getData().getData();
        e.setCancelled(true);
              //iron
              if(gBlock == ItemList.ore[0]){
                  if(MineLevel >= plugin.getConfig().getInt("Iron level")){
                      if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                  sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                  SQL.XpCounter(p, plugin.getConfig().getInt("Iron XP"));
                  so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Iron")*20);
                  gPi.addItem(ItemList.iron);
                      }else{
                          e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                      }
                  }else{
                      e.getPlayer().sendMessage("you need to be level "+plugin.getConfig().getInt("Iron level")+" to mine Iron ore!");
                  }
              //coal
              }else if(gBlock == ItemList.ore[1]){
                  if(MineLevel >= plugin.getConfig().getInt("Coal level")){
                      if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                      SQL.XpCounter(p, plugin.getConfig().getInt("Coal XP"));
                        so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Coal")*20);
                      gPi.addItem(ItemList.coal);
                  }else{
                          e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                  }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Coal level")+" to mine Coal ore");
                  }
              //Diamond
              }else if(gBlock == ItemList.ore[2]){
                  if(MineLevel >= plugin.getConfig().getInt("Diamond level")){
                      if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Diamond XP"));
                            so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Diamond")*20);
                          gPi.addItem(ItemList.diamond);
                      }else{
                          e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Diamond level")+" to mine Diamond ore");
                  }
              //Emerald
              }else if(gBlock == ItemList.ore[3]){
                  if(MineLevel >= plugin.getConfig().getInt("Emerald level")){
                      if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Emerald XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Emerald")*20);
                          gPi.addItem(ItemList.emerald);
                      }else{
                          e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Emerald level")+" to mine Emerald ore");
                  }
              //Redstone
              }else if(gBlock == ItemList.ore[4]){
                  if(MineLevel >= plugin.getConfig().getInt("Redstone level")){
                      if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Redstone XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Redstone")*20);
                          gPi.addItem(ItemList.redstone);
                      }else{
                          e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Redstone level")+" to mine Redstone ore");
                  }
              //Gold
              }else if(gBlock == ItemList.ore[5]){
                  if(MineLevel >= plugin.getConfig().getInt("Gold level")){
                      if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Gold XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Gold")*20);
                          gPi.addItem(ItemList.gold);
                      }else{
                          e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Gold level")+" to mine Gold ore");
                  }
              //Lapis
              }else if(gBlock == ItemList.ore[6]){
                  if(MineLevel >= plugin.getConfig().getInt("Lapis level")){
                      if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Lapis XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Lapis")*20);
                          gPi.addItem(ItemList.lapis);
                      }else{
                          e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Lapis level")+" to mine Lapis ore");
                  }
              //Log TODO:Different types
              }else if(gBlock == Material.LOG){
                  if(d == 0 && MineLevel >= plugin.getConfig().getInt("Oak level")){
                  if(MineLevel >= plugin.getConfig().getInt("Log level")){
                      if(Arrays.asList(ItemList.axe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Oak XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Oak")*20);
                          ItemList.logs.setDurability(d);
                          gPi.addItem(ItemList.logs);
                      }else{
                          e.getPlayer().sendMessage("You need an axe to chop down this tree!");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Oak level")+" to Chop down this tree");
                  }
              }else if(gBlock == Material.LOG){
                  if(d == 1 && MineLevel >= plugin.getConfig().getInt("Spruce level")){
                      if(Arrays.asList(ItemList.axe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Sprue XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Spruce")*20);
                          ItemList.logs.setDurability(d);
                          gPi.addItem(ItemList.logs);
                      }else{
                          e.getPlayer().sendMessage("You need an axe to chop down this tree!");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Spruce level")+" to Chop down this tree");
                  }
              }else if(gBlock == Material.LOG){
                  if(d == 2 && MineLevel >= plugin.getConfig().getInt("Birch level")){
                      if(Arrays.asList(ItemList.axe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Birch XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Birch")*20);
                          ItemList.logs.setDurability(d);
                          gPi.addItem(ItemList.logs);
                      }else{
                          e.getPlayer().sendMessage("You need an axe to chop down this tree!");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Birch level")+" to Chop down this tree");
                  }
              }else if(gBlock == Material.LOG){
                  if(d == 3 && MineLevel >= plugin.getConfig().getInt("Jungle level")){
                      if(Arrays.asList(ItemList.axe).contains(gi)){
                          sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                          SQL.XpCounter(p, plugin.getConfig().getInt("Jungle XP"));
                          so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Jungle")*20);
                          ItemList.logs.setDurability(d);
                          gPi.addItem(ItemList.logs);
                      }else{
                          e.getPlayer().sendMessage("You need an axe to chop down this tree!");
                      }
                  }else{
                      e.getPlayer().sendMessage("You need to be level "+plugin.getConfig().getInt("Jungle level")+" to Chop down this tree");
                  }
              }
           
          }
        }
      }
    }
    EDIT: i just realised this is probably the wrong section :/
     
  2. my personal pattern for executing stuff if conditions are involved is as:

    Code (Java):

    if (!condition) {
         return;
    }
    doSomething();
     
    it'll run the if statement, then if that condition is true, it'll return any won't execute any other statements after it. however, if that's false, it'll run the doSomething method.

    bit easier to read on the eyes, and a bit more organized than if, if else, ifelse statements.
     
    • Agree Agree x 3
  3. WAS

    WAS

    Definitely kills syntax arching. I'm working on replacing a lot of lazy plugins with better logic like this. Not sure why I never started doing things like this but than again I was more concerned with hating Java and getting a "stupid" plugin I needed finished.
     
  4. That wouldn't really help in our case I believe since we're checking for specific blocks being broken and do specific stuff for those blocks
     
  5. WAS

    WAS

    Why not? I don't seem to understand why you don't think it's not usable. It's really much the same but only handling the else conditions that you would bail on anyway.
     
  6. Correct me if I'm wrong but we would still have to use
    Code (Text):

              if(gBlock == ItemList.ore[0]){
                 if(Level >= plugin.getConfig().getInt("Iron level")){
                     if(Arrays.asList(ItemList.pickaxe).contains(gi)){
                 sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
                 SQL.XpCounter(p, plugin.getConfig().getInt("Iron XP"));
                 so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Iron")*20);
                 gPi.addItem(ItemList.iron);
                     }else{
                         e.getPlayer().sendMessage("You need a pickaxe to mine ore");
                     }
                 }else{
                     e.getPlayer().sendMessage("you need to be level "+plugin.getConfig().getInt("Iron level")+" to mine Iron ore!");
                 }
     
    for every single block which is what I wanna avoid if possible

    I feel like I'm missing something here so feel free to correct me.
     
  7. Code (Java):

    //you could also combine these in some cases if the 'error message' or output is the same.
    if (gBlock != itemList.ore[0]) {
         //error message
         return;
    }
    if (Level < plugin.getConfig().getInt("Iron level")) {
         //error message
         return;
    }
    if (!Arrays.asList(ItemList.pickaxe).contains(gi)) {
         //error message
         return;
    }
    //runs given that the above if statements are false.
    sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
    SQL.XpCounter(p, plugin.getConfig().getInt("Iron XP"));
    so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Iron")*20);
    gPi.addItem(ItemList.iron);
     
    essentially invert the conditions leading to what's suppose to happen, then finally put what's actually suppose to happen.
     
  8. Ok, I think get it.
    So I would create a class for every block that I want to check?

    Code (Java):

    if (gBlock != itemList.ore[0]) {
         //error message
         return;
    }
     
    Also this would be unnecessary since we're checking multiple blocks right?
     
  9. you wouldn't make a class, you would make a code block for every condition you want to check against.

    also, im sure it would be necessary. my example was 'error message' given that each 'error' message was different. however, for example if i had this(output for whatever im checking for is the same, i wouldnt want to repeat my code):

    Code (Java):

    if (object != object2) {
         System.out.println("They aren't the same, sorry!");
         return;
    }
    if (object3 != object4) {
         System.out.println("They aren't the same, sorry!");
    }
     
    you'd want to essentially combine them at times so you're not repeating yourself.

    Code (Java):

    if (object != object2 || object3 != object4) {
         System.out.println("They aren't the same, sorry!");
         return;
    }
     
  10. I can't seem to get my head around this
    In your code, how would I go about adding other ores?
    making another block break event function checking for another ore?
    Code (Java):

    public void IronOreBreak(BlockBreakEvent e)
    {
    if (gBlock != itemList.ore[0]) {
         //error message
         return;
    }
    if (Level < plugin.getConfig().getInt("Iron level")) {
         //error message
         return;
    }
    if (!Arrays.asList(ItemList.pickaxe).contains(gi)) {
         //error message
         return;
    }
    sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
    SQL.XpCounter(p, plugin.getConfig().getInt("Iron XP"));
    so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Iron")*20);
    gPi.addItem(ItemList.iron);
    }
    public void CoalOreBreak(BlockBreakEvent e)
    {
    if (gBlock != itemList.ore[1]) {
         //error message
         return;
    }
    if (Level < plugin.getConfig().getInt("Coal level")) {
         //error message
         return;
    }
    if (!Arrays.asList(ItemList.pickaxe).contains(gi)) {
         //error message
         return;
    }
    sb = new SetBedrock(this.plugin).runTaskLater(this.plugin, 3);
    SQL.XpCounter(p, plugin.getConfig().getInt("Coal XP"));
    so = new SetOriginal(this.plugin).runTaskLater(this.plugin, plugin.getConfig().getInt("Coal")*20);
    gPi.addItem(ItemList.coal);
    }
     
     
    #10 Wapic, May 14, 2017
    Last edited: May 14, 2017
  11. mathhulk

    mathhulk Retired Moderator
    Retired

    Moved to Spigot Plugin Development.
     
    • Agree Agree x 2
  12. First off
    1) Stop abusing static. Poor little thing :(
    2) Don't access the configuration everytime someone broke a block. Store them in a method. If you need to store a ink such as a level, make a variable of it. This way you avoid accessing the configuration everytime someone breaks a block.
    3) You could use a switch statement for this.