[SOLVED] Creating multiple classes :: Reading the same Methods and Commands

Discussion in 'Spigot Plugin Development' started by fujiboy4, May 26, 2015.

Thread Status:
Not open for further replies.
  1. Hi, again. I have a very long bit of code here. And I want to make it into separate classes, for my sake. Here
    is my code that I have developed.

    Code (Text):
    package ultrapvp.ssm;

    import java.io.File;
    import java.util.List;

    import org.bukkit.Bukkit;
    import org.bukkit.Color;
    import org.bukkit.Effect;
    import org.bukkit.EntityEffect;
    import org.bukkit.FireworkEffect;
    import org.bukkit.GameMode;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.Sound;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Arrow;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Firework;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.entity.EntityDamageEvent;
    import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
    import org.bukkit.event.entity.FoodLevelChangeEvent;
    import org.bukkit.event.entity.PlayerDeathEvent;
    import org.bukkit.event.player.PlayerDropItemEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.event.player.PlayerPickupItemEvent;
    import org.bukkit.event.player.PlayerToggleFlightEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.FireworkMeta;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
    import org.bukkit.scoreboard.Scoreboard;
    import org.bukkit.scoreboard.ScoreboardManager;
    import org.bukkit.scoreboard.Team;
    import org.bukkit.util.Vector;

    public class Main extends JavaPlugin implements Listener {

        static ScoreboardManager scorem = Bukkit.getScoreboardManager();

        static Scoreboard board = scorem.getNewScoreboard();

        static Team spider = board.registerNewTeam("spider");

        static Team skeleton = board.registerNewTeam("skeleton");

        @Override
        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);
            if (new File(getDataFolder().toString()).exists() == false) {
                this.getConfig().set("TestMap", null);
                this.getConfig().set("TestMap.x", 0);
                this.getConfig().set("TestMap.y", 0);
                this.getConfig().set("TestMap.z", 0);
                saveConfig();
         
            } else {
                reloadConfig();
            }

            getLogger().info(
                    "Test has been enabled.  Depends on DisguiseCraft");
        }

        @Override
        public void onDisable() {
            getLogger().info("Test has been disabled.");;
        }

        @EventHandler
        public void drop(PlayerDropItemEvent e) {
            final Player p = e.getPlayer();
            e.setCancelled(true);
            p.sendMessage("§cSSM> You cannot drop items here.");
        }

        @EventHandler
        public void pickup(PlayerPickupItemEvent e) {
            e.setCancelled(true);
        }

        @EventHandler
        public void onDeath(PlayerDeathEvent e) {
            final Player p = e.getEntity();
                p.getWorld().strikeLightningEffect(p.getLocation());
         
                e.getDrops().clear();
                p.setHealth(20);
                p.setFoodLevel(20);
                p.setGameMode(GameMode.SPECTATOR);
                p.sendMessage("§cSSM> You have died.  You will respawn in 10 seconds...");

             

                Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {

                    @SuppressWarnings("deprecation")
                    @Override
                    public void run() {

                        p.sendMessage("§aSSM> You have respawned.  Go get em! ;)");
                        p.playEffect(p.getLocation(), Effect.HEART, 500);
                        p.playSound(p.getLocation(), Sound.IRONGOLEM_HIT, 10, 2);
                        p.setGameMode(GameMode.ADVENTURE);
                        if (spider.hasPlayer(p)) {
                            spiderClass(p);
                        }
                        if (skeleton.hasPlayer(p)) {
                            skeletonClass(p);
                        }

                        try {
                            final Location loc = p.getLocation();
                            final Firework f = p.getLocation().getWorld()
                                    .spawn(loc, Firework.class);

                            // f.getLocation().setX(p.getLocation().getX() +
                            // (a*1000));
                            FireworkMeta fm = f.getFireworkMeta();

                            fm.addEffect(FireworkEffect.builder()

                            .trail(true).with(FireworkEffect.Type.BURST)
                                    .with(FireworkEffect.Type.BALL)
                                    .with(FireworkEffect.Type.BALL_LARGE)
                                    .withColor(Color.GREEN).withColor(Color.YELLOW)
                                    .build());

                            fm.setPower(0);
                            f.setFireworkMeta(fm);
                        } catch (Exception e) {
                            Bukkit.getServer().broadcastMessage(e.toString());
                        }

                    }
                }, 200L);

        }

        @EventHandler
        public void onFoodLevelChange(FoodLevelChangeEvent e) {
            final Player p = (Player) e.getEntity();
            if (e.getEntity() instanceof Player) {
                e.setCancelled(true);
                p.setFoodLevel(20);
            }

        }

        @EventHandler
        public void onPlayerDamage(EntityDamageEvent e) {
            if (e.getEntity() instanceof Player) {
                if (e.getCause() == DamageCause.FALL) {
                    e.setCancelled(true);
                }
            }

        }

        @SuppressWarnings("deprecation")
        @EventHandler
        public void onPlayerMove(PlayerMoveEvent event) {

            Player p = event.getPlayer();
            if (p.isOnGround()) {
                p.setAllowFlight(true);
            }
         
         
            Location respawn = new Location(p.getWorld(), p.getLocation()
                    .getBlockX(), 100, p.getLocation().getBlockZ());
         
            if (p.getLocation().getY() < 1) {
                p.getWorld().strikeLightningEffect(p.getLocation());
                if (p.isOp()) {
                    p.teleport(respawn);
                } else {
                    if (p.isOp() == false) {
                        p.teleport(respawn);
                    }
                }
                reset(p);
                p.setHealth(20);
                p.setFoodLevel(20);
                p.setGameMode(GameMode.SPECTATOR);
                p.sendMessage("§cSSM> You have died.  You will respawn in 10 seconds...");
         
                Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {

                    @Override
                    public void run() {

                        p.sendMessage("§aSSM> You have respawned.  Go get em! ;)");
                        p.playEffect(p.getLocation(), Effect.HEART, 500);
                        p.playSound(p.getLocation(), Sound.IRONGOLEM_HIT, 10, 2);
                        p.setGameMode(GameMode.ADVENTURE);
                        if (spider.hasPlayer(p)) {
                            spiderClass(p);
                        }
                        if (skeleton.hasPlayer(p)) {
                            skeletonClass(p);
                        }

                        try {
                            final Location loc = p.getLocation();
                            final Firework f = p.getLocation().getWorld()
                                    .spawn(loc, Firework.class);

                            // f.getLocation().setX(p.getLocation().getX() +
                            // (a*1000));
                            FireworkMeta fm = f.getFireworkMeta();

                            fm.addEffect(FireworkEffect.builder()

                            .trail(true).with(FireworkEffect.Type.BURST)
                                    .with(FireworkEffect.Type.BALL)
                                    .with(FireworkEffect.Type.BALL_LARGE)
                                    .withColor(Color.GREEN).withColor(Color.YELLOW)
                                    .build());

                            fm.setPower(0);
                            f.setFireworkMeta(fm);
                        } catch (Exception e) {
                            Bukkit.getServer().broadcastMessage(e.toString());
                        }

                    }
                }, 200L);
            }
        }

        @SuppressWarnings("deprecation")
        @EventHandler
        public void interact(PlayerInteractEvent e) {
            final Player p = e.getPlayer();
         
            //Right click with an axe.
            if ((e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK)
                    && p.getItemInHand().getType() == Material.IRON_AXE) {
             
             
                // If player is invisible...
                if (p.hasPotionEffect(PotionEffectType.INVISIBILITY)) {
                 
                 
                    //Say you cannot use this for 5 seconds.
                    p.sendMessage("§cSSM> You cannot use this for 5 seconds...");
                } else {
                 
                    //But, if player does have invisibility...
                    if (!p.hasPotionEffect(PotionEffectType.INVISIBILITY)) {
                     
                        //Set players health to 20, and create a death radius.
                        p.setHealth(20);
                        double radius = 5D;
                        List<Entity> near = p.getLocation().getWorld()
                                .getEntities();
                        for (Entity e1 : near) {
                            if (e1.getLocation().distance(p.getLocation()) <= radius) {
                                if (e1 instanceof Player) {
                                    ((Player) e1).damage(15);
                                    p.addPotionEffect(new PotionEffect(
                                            PotionEffectType.REGENERATION, 100, 10));
                                } else {
                                    if (e1 instanceof Arrow) {

                                    } else {
                                        p.sendMessage("§cSSM> That is Entity: "
                                                + e1.getEntityId()
                                                + ". You cannot attack that type of Entity.");
                                    }

                                }

                            }
                        }

                        p.setVelocity(new Vector(0, 2, 0));
                        p.addPotionEffect(new PotionEffect(
                                PotionEffectType.INVISIBILITY, 100, 1));
                        p.playEffect(p.getLocation(), Effect.EXPLOSION_HUGE, 500);
                        p.playSound(p.getLocation(), Sound.EXPLODE, 100, 1);
                        p.sendMessage("§aSSM> You used Hidden Leap.");

                    }

                }

            }

            if ((e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK)
                    && p.getItemInHand().getType() == Material.IRON_SWORD) {

                if (p.hasPotionEffect(PotionEffectType.SPEED)) {
                    p.sendMessage("§cSSM> You cannot use this for 5 seconds...");
                } else {
                    if (!p.hasPotionEffect(PotionEffectType.SPEED)) {
                        p.sendMessage("§aSSM> You used Arrow Attack.");

                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.shootArrow().setBounce(false);
                        p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,
                                100, 1));
                    }
                }
            }
        }

        @EventHandler
        public void join(PlayerJoinEvent e) {
            final Player p = e.getPlayer();
            p.sendMessage("§aSSM> Welcome back.  Don't forget to choose a class by typing /classes.");
            p.setAllowFlight(true);
            p.playEffect(EntityEffect.WOLF_HEARTS);
            p.playSound(p.getLocation(), Sound.CHEST_OPEN, 10, 2);
        }

        @EventHandler
        public void onFlightAttempt(PlayerToggleFlightEvent event) {

            final Player p = event.getPlayer();
            if (p.getGameMode() != GameMode.CREATIVE) {
                p.playSound(p.getLocation(), Sound.IRONGOLEM_DEATH, 10, -10);
                event.setCancelled(true);
                p.setAllowFlight(false);
                Vector v = p.getLocation().getDirection().setY(1);
                p.setVelocity(v);
            } else {

            }

        }

        @SuppressWarnings("deprecation")
        public boolean onCommand(CommandSender s, Command cmd, String label,
                String[] args) {
            Player p = (Player) s;
            if (cmd.getName().equalsIgnoreCase("classes")) {
                p.sendMessage("§a--- §e[Classes] §a---");
                p.sendMessage("§a/Class Spider");
                return true;
            }
            if (cmd.getName().equalsIgnoreCase("class")) {
                if (args.length == 0) {
                    p.sendMessage("§cSSM> Please type a kit!");
                    return true;
                } else {
                    if (args[0].equalsIgnoreCase("spider")) {
                        spiderClass(p);
                        p.sendMessage("§aSSM> You have chosen the §e§lSPIDER§a.");
                        p.playSound(p.getLocation(), Sound.NOTE_PLING, 10, 2);
                        p.playEffect(p.getLocation(), Effect.CLOUD, 500);

                        return true;
                    } else if (args[0].equalsIgnoreCase("skeleton")) {
                        skeletonClass(p);
                        p.sendMessage("§aSSM> You have chosen the §e§lSKELETON§a.");

                        p.playSound(p.getLocation(), Sound.NOTE_PLING, 10, 2);
                        p.playEffect(p.getLocation(), Effect.CLOUD, 500);

                    }
                    return true;
                }

            }

            if (cmd.getName().equalsIgnoreCase("ssm")) {
                p.sendMessage("§aSuperSmashMobs: §eCoded by: Fuji4DaW1N_, SirJackLaserGuns, and Temena");
                return true;
            }

            if (cmd.getName().equalsIgnoreCase("creater")) {
                if (args.length == 0) {
                    p.sendMessage("§cSSM> Please supply with a respawn point.");
                } else {

                    this.getConfig().set(args[0], null);
                    this.getConfig().set(args[0] + ".x",
                            p.getLocation().getBlockX());
                    this.getConfig().set(args[0] + ".y",
                            p.getLocation().getBlockY());
                    this.getConfig().set(args[0] + ".z",
                            p.getLocation().getBlockZ());
                    saveConfig();
                    p.sendMessage("§aSSM> You have set a respawn point called: "
                            + args[0] + ".");
                }
            }

            return false;
        }

        private void spiderClass(Player p) {
            p.performCommand("d spider");

            spider.addPlayer(p);

            p.getInventory().clear();

            p.setHealth(20);

            p.setFoodLevel(20);

            ItemStack Sword = new ItemStack(Material.IRON_SWORD);
            ItemMeta im = Sword.getItemMeta();

            im.setDisplayName("§a§lSpider §e- §a§lRight-Click Hold");
            Sword.setItemMeta(im);

            p.getInventory().addItem(Sword);

            ItemStack Axe = new ItemStack(Material.IRON_AXE);
            ItemMeta im1 = Axe.getItemMeta();

            im1.setDisplayName("§a§lSpider §e- §a§lRight Click");
            Axe.setItemMeta(im1);
            p.getInventory().addItem(Axe);

            p.getInventory().setChestplate(
                    new ItemStack(Material.LEATHER_CHESTPLATE));
            p.getInventory().setLeggings(new ItemStack(Material.LEATHER_LEGGINGS));
            p.getInventory().setBoots(new ItemStack(Material.CHAINMAIL_BOOTS));
        }

        private void skeletonClass(Player p) {
            p.performCommand("d skeleton");

            skeleton.addPlayer(p);

            p.getInventory().clear();

            p.setHealth(20);

            p.setFoodLevel(20);

            ItemStack Sword = new ItemStack(Material.IRON_SWORD);
            ItemMeta im = Sword.getItemMeta();

            im.setDisplayName("§a§lSkeleton §e- §a§lRight-Click Hold");
            Sword.setItemMeta(im);

            p.getInventory().addItem(Sword);

            ItemStack Axe = new ItemStack(Material.IRON_AXE);
            ItemMeta im1 = Axe.getItemMeta();

            im1.setDisplayName("§a§lSkeleton §e- §a§lRight Click");
            Axe.setItemMeta(im1);
            p.getInventory().addItem(Axe);

            ItemStack Bow = new ItemStack(Material.BOW);
            ItemMeta im2 = Bow.getItemMeta();

            im2.setDisplayName("§a§lSkeleton §e- §a§lRight Click");
            Bow.setItemMeta(im2);
            p.getInventory().addItem(Bow);

            p.getInventory().setChestplate(
                    new ItemStack(Material.CHAINMAIL_CHESTPLATE));
            p.getInventory()
                    .setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS));
            p.getInventory().setBoots(new ItemStack(Material.CHAINMAIL_BOOTS));
        }

        private void reset(Player p) {
            p.getInventory().clear();
            p.getInventory().setHelmet(null);
            p.getInventory().setBoots(null);
            p.getInventory().setChestplate(null);
            p.getInventory().setLeggings(null);
            p.removePotionEffect(PotionEffectType.SPEED);
            p.removePotionEffect(PotionEffectType.SLOW);
            p.removePotionEffect(PotionEffectType.FAST_DIGGING);
            p.removePotionEffect(PotionEffectType.SLOW_DIGGING);
            p.removePotionEffect(PotionEffectType.INCREASE_DAMAGE);
            p.removePotionEffect(PotionEffectType.HEAL);
            p.removePotionEffect(PotionEffectType.HARM);
            p.removePotionEffect(PotionEffectType.JUMP);
            p.removePotionEffect(PotionEffectType.CONFUSION);
            p.removePotionEffect(PotionEffectType.REGENERATION);
            p.removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE);
            p.removePotionEffect(PotionEffectType.FIRE_RESISTANCE);
            p.removePotionEffect(PotionEffectType.WATER_BREATHING);
            p.removePotionEffect(PotionEffectType.INVISIBILITY);
            p.removePotionEffect(PotionEffectType.BLINDNESS);
            p.removePotionEffect(PotionEffectType.NIGHT_VISION);
            p.removePotionEffect(PotionEffectType.HUNGER);
            p.removePotionEffect(PotionEffectType.WEAKNESS);
            p.removePotionEffect(PotionEffectType.POISON);
            p.removePotionEffect(PotionEffectType.WITHER);
            p.removePotionEffect(PotionEffectType.SATURATION);
            p.removePotionEffect(PotionEffectType.HEALTH_BOOST);
        }

    }


    EDIT: I want it so the EventHandlers are in this class and the kits are in their own classes.
     
  2. Actually, that's what you might want to look into. The tutorial shows you how to create a listener class. Instead of making your main class implement the Listener interface and all the @EventHandler listeners inside there, create a separate class and put your @EventHandler methods inside there. Read the tutorial on how to do that.
     
  3. Omnivion

    Patron

    OOC, any opinions on using the
    Code (Text):
    registerEvent(Class<? extends Event> event, Listener listener, EventPriority priority, EventExecutor executor, Plugin plugin, boolean ignoreCancelled)
    method, rather than the
    Code (Text):
    registerEvents(Listener listener, Plugin plugin)
    ?
     
  4. You'll want to use registerEvents(). It's much easier to use and your code will be more readable.
     
  5. Omnivion

    Patron

    I don't necessarily agree on either point; I like having a central point in my code in which control variables, such as event priority, or ignore cancelled, are located.

    And this way, everything can be neatly organized into their own classes, rather than having one massive PlayerListener class or something.
     
  6. You can still organize methods per class and then register the classes. Then you can also have the event priority in that class as well.
     
  7. I would say the first could be a tad faster, if implemented properly, as it doesn't necessarily has to use reflection to invoke the method
     
    • Informative Informative x 1
  8. It is technically faster, but I personally think it's a bit sloppy. It's all opinion, though :)

    EDIT: Reflection is insignificantly slower than normal in this case as the Method is stored and the only slow part of reflection is registering it, which is only done once.
     
  9. Omnivion

    Patron


    Thank you both for the information :)
     
  10. OK. I'm asking one of my friends for help anyway, so at least I have backup. Thanks all.
     
  11. You mean like organizing all the code into classes like "Listeners", well if you need to do it like that then in your on Enable then you need to add
    PluginManager pm = Bukkit.getPluginManager();
    Then you just need to reference the class by:
    pm.registerEvents(new Listeners(this), this);
    And then you would just have to create a constructor in the Listener class.
    Hope it helps :)
     
  12. Im looking more on the lines of:

    A Listener class
    A SpiderKit Class
    A SkeletonKit Class

    The 2 kit classes ^^ should be able to run commands. And I'm thinking that there needs to be something to tie all three classes into one. And still have all the methods from each class (if that's even possible. if not that's fine).
     
  13. Omnivion

    Patron

    Is an abstract class something you're looking for?
     
  14. Yes.
     
  15. That's what method overriding is meant for ;).
    • Create a class which will be the base class
    • Move all common fields to the base class
    • Move all common methods to the base class - note that 'common' here means semantically common, that it does (roughly) the same
    • If you have methods which are invoked in the same manner (like a skill activation on right click), you can create an abstract method in the base class, and invoke it from there (without casting to a subclass).
    If done properly (and following the Liskov Substitution Principle) you should be able to replace most of the types with the abstract type, aside perhaps types in the subclasses themselves.
    It uses Method#invoke to run the event handling methods, so reflection is used every time the event fires.
    Aside that this would only hold if the JVM has warmed up properly, I would still like to see your sources.
     
  16. I pretty much know how to use the extracting methods and all that, but my problem is making the Base class know what the Listener class is, as well as the SpiderClass (e.g)

    Example:
    Code (Text):
    [Base Class]
               |
               |
    [Listener Class] {Can get methods from Base Class}
               +
               +
    [SpiderClass] {Can get methods from Base Class And Listener Class}
    Does that kind of straighten it out? Sorry this is really hard to explain..
    My Question: How can the plugin read all the classes as one plugin?
     
Thread Status:
Not open for further replies.