Solved When mined block is placed again it re-registers it in my scoreboard

Discussion in 'Plugin Development' started by tizrain, Nov 19, 2015.

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

    tizrain

    Hello. The title is a little unclear but it's hard to explain shortly.

    So, the plugin I'm making is for an AbbaRules event, but when you've mined a block that gives you a certain score in the scoreboard I've created, you can place it again and break it once more, this means that you get the same score again. So i.e. if you mined an emerald block that gives you 7 points (the plugin gives a silk touch pick, which is the meaning of abbarules) you are able to place it down again, break it and get another 7 points over and over again.

    I would like to find a solution to this in the way that you're checking if the block has been broken before OR that the block has been placed by the user before it's broken.

    For now I don't know if this is possible, and if so, how?

    Thanks for reading, I've posted my code below.

    Code:
    package com.github.theepicexcalibur.abbarules;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.OfflinePlayer;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.enchantments.Enchantment;
    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.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitTask;
    import org.bukkit.scoreboard.DisplaySlot;
    import org.bukkit.scoreboard.Objective;
    import org.bukkit.scoreboard.Score;
    import org.bukkit.scoreboard.Scoreboard;
    
    public class AbbaRules extends JavaPlugin implements Listener {
        Scoreboard sb;
        Objective obj;
        List<String> playerList;
        HashSet<UUID> giveItemList;
        HashMap<UUID, ItemStack[]> saveInv;
        Map<Material, Integer> blockValues;
        boolean ready = false;
        boolean started = false;
    
        BukkitTask countdownTask;
        BukkitTask timerTask;
    
        int gameLength = 1200;
    
        public void onDisable() {
            if (obj != null) {
                obj.unregister();
                obj = null;
            }
            if (countdownTask != null) countdownTask.cancel();
            if (timerTask != null) timerTask.cancel();
        }
    
        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);
            playerList = new ArrayList<String>();
            giveItemList = new HashSet<UUID>();
            saveInv = new HashMap<UUID, ItemStack[]>();
            blockValues = new HashMap<Material, Integer>();
    
            //static for now
            blockValues.put(Material.REDSTONE_ORE, 1);
            blockValues.put(Material.GLOWING_REDSTONE_ORE, 1);
            blockValues.put(Material.LAPIS_ORE, 2);
            blockValues.put(Material.GOLD_ORE, 3);
            blockValues.put(Material.DIAMOND_ORE, 5);
            blockValues.put(Material.EMERALD_ORE, 7);
        }
    
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            Player player = (Player) sender;
           
            String usage = ChatColor.GREEN + "/abba create: Skapa en abbarules match\n" +
                    "/abba join: Gå med i AbbaRules\n" +
                    "/abba leave: Lämna Abbarules eventet\n" +
                    "/abba start: Starta timern\n" +
                    "/abba stop: Stoppa timern\n" +
                    "/abba reset: Avsluta abbarules matchen";
                    ;
            if (!(sender instanceof Player)) {
                player.sendMessage("Detta kommandot kan inte köras från konsollen.");
                return false;
            }
            if (label.equals("abba")) {
                if (args.length == 0) {
                    player.sendMessage(usage);
                } else if (args[0].equalsIgnoreCase("create")) {
                    if (player.hasPermission("abbarules.create")) {
                        createGame(player);
                    } else {
                        player.sendMessage(ChatColor.RED + "Du kan inte utföra detta kommando!");
                    }
                } else if (args[0].equalsIgnoreCase("list")) {
                    player.sendMessage("giveItemList: " + giveItemList);
                    player.sendMessage("playerList: " + playerList);
                } else if (args[0].equalsIgnoreCase("join")) {
                    if (started == false) {
                        addPlayer(player);
                    } else {
                        player.sendMessage(ChatColor.RED + "Du kan inte gå med i eventet när det är startat!");
                    }
                } else if (args[0].equalsIgnoreCase("leave")) {
                    if (!playerList.contains(player.getName())) {
                        player.sendMessage(ChatColor.RED + "Du är inte med i något event och kan därför inte lämna!");
                    } else {
                        if (player.getName().equalsIgnoreCase(playerList.get(0)) && started == true) {
                            player.sendMessage(ChatColor.RED + "Du kan inte lämna eventet eftersom du hostar det!");
                        } else {
                            UUID id = player.getUniqueId();
                            Bukkit.getPlayer(id).getInventory().clear();
                            if (saveInv.containsKey(id)) {
                                Bukkit.getPlayer(id).getInventory().setContents(saveInv.get(id));
                            }
                            removePlayer(player);
                        }
                    }
                } else if (args[0].equalsIgnoreCase("start")
                        && !playerList.isEmpty()
                        && player.getName().equalsIgnoreCase(playerList.get(0))) {
                    if (player.hasPermission("abbarules.start")) {
                        if (args.length > 1) {
                            try {
                                gameLength = Integer.parseInt(args[1]) * 60;
                            } catch (NumberFormatException e) {
                                player.sendMessage(ChatColor.RED + "/abba start [time]");
                            }
                        } else {
                            gameLength = 20*60;
                        }
                    startGame(player);
                    } else {
                        player.sendMessage(ChatColor.RED + "Du kan inte utföra detta kommando!");
                    }
                } else if (args[0].equalsIgnoreCase("stop")
                        && !playerList.isEmpty()
                        && player.getName().equalsIgnoreCase(playerList.get(0))) {
                    if (player.hasPermission("abbarules.stop")) {
                        stopGame();
                    } else {
                        player.sendMessage(ChatColor.RED + "Du kan inte utföra detta kommando!");
                    }
                } else if (args[0].equalsIgnoreCase("reset")
                        && !playerList.isEmpty()
                        && player.getName().equalsIgnoreCase(playerList.get(0))) {
                    if (player.hasPermission("abbarules.reset")) {
                        resetGame(player);
                    } else {
                        player.sendMessage(ChatColor.RED + "Du kan inte utföra detta kommando!");
                    }
                } else {
                    player.sendMessage(usage);
                }
                return true;
            } else {
                return false;
            }
        }
    
        public void createGame(Player player) {
            if (sb == null) sb = Bukkit.getScoreboardManager().getMainScoreboard();
            if (obj != null) {
                obj.unregister();
                obj = null;
            }
            obj = sb.registerNewObjective("abba_score", "dummy");
            obj.setDisplayName("Score");
            obj.setDisplaySlot(DisplaySlot.SIDEBAR);
    
            playerList.clear();
            giveItemList.clear();
            ready = true;
            started = false;
    
            Bukkit.broadcastMessage(ChatColor.GOLD + player.getName() + " har skapat ett AbbaRules event!" +
                    " Gå med med hjälp av /abba join.");
            player.sendMessage(ChatColor.AQUA + "När alla har gått med, starta eventet med /abba start");
            addPlayer(player);
        }
    
        public void resetGame(Player player) {
            if (!ready) {
                player.sendMessage(ChatColor.RED + "Det finns inget spel att avsluta.");
                return;
            }
            if (started) {
                stopGame();
            }
            if (obj != null) {
                obj.unregister();
                obj = null;
            }
            ready = false;
            started = false;
        }
    
        @SuppressWarnings("deprecation")
        public void addPlayer(Player player) {
            if (!ready) {
                player.sendMessage(ChatColor.RED + "Inget AbbaRules event är igång just nu.");
                return;
            }
            OfflinePlayer op = Bukkit.getOfflinePlayer(player.getName());
            obj.getScore(op).setScore(1);
            obj.getScore(op).setScore(0);
           
            if (!playerList.contains(player.getName())) {
                playerList.add(player.getName());
                giveItemList.add(player.getUniqueId());
                player.sendMessage(ChatColor.GREEN + "Du har gått med i eventet!");
            } else {
                player.sendMessage(ChatColor.RED + "Du har redan gått med i eventet!");
                return;
            }
        }
       
        @SuppressWarnings("deprecation")
        public void removePlayer(Player player) {
            OfflinePlayer op = Bukkit.getOfflinePlayer(player.getName());
            obj.getScore(op).getScoreboard().resetScores(op);
           
            if (playerList.contains(player.getName())) {
                Bukkit.broadcastMessage(ChatColor.GOLD + player.getName() + ChatColor.AQUA + " lämnade eventet!");
                playerList.remove(player.getName());
                giveItemList.remove(player.getName());
            } else {
                player.sendMessage(ChatColor.RED + "Du är inte med i något event!");
                return;
            }
        }
    
        public void startGame(Player player) {
            if (!ready) {
                player.sendMessage(ChatColor.RED + "Det finns inget event att starta.");
                return;
            }
            Bukkit.broadcastMessage(ChatColor.AQUA + "AbbaRules eventet börjar om:");
           
            for (UUID id : giveItemList) {
                saveInv.put(id, Bukkit.getPlayer(id).getInventory().getContents());
            }
           
            if (countdownTask != null) countdownTask.cancel();
            countdownTask = Bukkit.getScheduler().runTaskTimer(this, new Runnable() {
                int time = 3;
                public void run() {
                    if (time > 0) {
                        Bukkit.broadcastMessage(ChatColor.GOLD + Integer.toString(time));
                        time--;
                    } else {
                        started = true;
                        for (UUID id : giveItemList) {
                            Bukkit.getPlayer(id).getInventory().clear();
                        }
                        Bukkit.broadcastMessage(ChatColor.GOLD + "Låt AbbaRules eventet börja!");
                        countdownTask.cancel();
                        countdownTask = null;
    
                        for (UUID id : giveItemList) {
                            ItemStack pickaxe = new ItemStack(Material.DIAMOND_PICKAXE);
                            ItemStack shovel = new ItemStack(Material.DIAMOND_SPADE);
                            ItemStack food = new ItemStack(Material.COOKED_BEEF, 64);
                            ItemStack torch = new ItemStack(Material.TORCH, 64);
                           
                           
                            ItemMeta pickaxemeta = pickaxe.getItemMeta();
                            pickaxemeta.setDisplayName(ChatColor.GOLD + "Super Hackan");
                            pickaxemeta.addEnchant(Enchantment.SILK_TOUCH, 1, true);
                            pickaxemeta.addEnchant(Enchantment.DURABILITY, 1, true);
                            pickaxemeta.addEnchant(Enchantment.DIG_SPEED, 1, true);
                            pickaxe.setItemMeta(pickaxemeta);
                           
                            ItemMeta shovelmeta = shovel.getItemMeta();
                            shovelmeta.setDisplayName(ChatColor.GOLD + "Super Spaden");
                            shovelmeta.addEnchant(Enchantment.DURABILITY, 1, true);
                            shovelmeta.addEnchant(Enchantment.DIG_SPEED, 1, true);
                            shovel.setItemMeta(shovelmeta);
                           
                            Bukkit.getPlayer(id).getInventory().addItem(pickaxe);
                            Bukkit.getPlayer(id).getInventory().addItem(shovel);
                            Bukkit.getPlayer(id).getInventory().addItem(food);
                            Bukkit.getPlayer(id).getInventory().addItem(torch);
                           
                            Bukkit.getPlayer(id).setHealth(20);
                            Bukkit.getPlayer(id).setFoodLevel(20);
                        }
                        startTimer();
                    }
                }
            }, 0, 20);
        }
    
        public void startTimer() {
            timerTask = Bukkit.getScheduler().runTaskTimer(this, new Runnable() {
                int time = gameLength;
                @SuppressWarnings("deprecation")
                public void run() {
                    if (time > 0) {
                        obj.getScore(Bukkit.getOfflinePlayer("Tid Kvar: ")).setScore(time);
                        time--;
                    } else {
                        stopGame();
                    }
                }
            }, 0, 20);
        }
    
        @SuppressWarnings("deprecation")
        public void stopGame() {
            if (!started) {
                return;
            }
            started = false;
            if (countdownTask != null) {
                countdownTask.cancel();
                countdownTask = null;
            }
            if (timerTask != null) {
                timerTask.cancel();
                timerTask = null;
            }
            for (UUID id : giveItemList) {
                Bukkit.getPlayer(id).getInventory().clear();
               
                Bukkit.getPlayer(id).getInventory().setContents(saveInv.get(id));
            }
            Bukkit.broadcastMessage(ChatColor.GOLD + "Tiden är slut!");
            sb.resetScores(Bukkit.getOfflinePlayer("time"));
        }
    
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            if (!started) return;
            Player player = event.getPlayer();
            if (player == null || !playerList.contains(player.getName())) {
                return;
            }
            Integer value = blockValues.get(event.getBlock().getType());
            if (value != null) {
                @SuppressWarnings("deprecation")
                Score score = obj.getScore(Bukkit.getOfflinePlayer(player.getName()));
                score.setScore(score.getScore()+value);
            }
        }
    
    }
     
  2. Offline

    Scimiguy

    You'll have to keep track of the blockplace and blockbreak events, and give the player itemstacks marked with some itemmeta so that your plugin can tell that it is one of your blocks

    Then, you'll have to put blockmeta on the blocks you placed to identify them as blocks that have been used
    Blockmeta isn't persistent though, so you'll also have to save the locations of those blocks to a file on disable
     
  3. Offline

    tizrain

    @Scimiguy So what you're saying is that there's a lot of work behind this issue. I know that the plugin RateOfXray is using something similar to fix my issue, but I don't know how they've done it. Seems like it would be kind of much work if you want to give each and every ore a specifik itemmeta?
     
  4. Offline

    Scimiguy

    It is a fair bit of work, yes
    If you want to include gravel and sand, then you'll have to handle gravity tracking too, it gets very complicated

    Take it step by step, if you need help just make another post
     
  5. Offline

    tizrain

    @Scimiguy I only need to track redstone ore, lapis ore, gold ore, diamond ore and emerald ore. So it wont be that much.
     
  6. Offline

    Scimiguy

    Sounds good

    Well I've said everything you need to do, so give it a try and come back if you have any issues?
     
  7. Offline

    tizrain

    @Scimiguy I was thinking. While they're in the Abbarules event they could be blocked completely when they try to place the certain blocks in the blockValues list. I'm completely stuck atm though on how to do this..

    My code so far
    Code:
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            if (!started) return;
            Player player = event.getPlayer();
            if (player == null || !playerList.contains(player.getName())) {
                return;
            }
            Integer value = blockValues.get(event.getBlock().getType());
            if (value != null) {
                @SuppressWarnings("deprecation")
                Score score = obj.getScore(Bukkit.getOfflinePlayer(player.getName()));
                score.setScore(score.getScore()+value);
            }
        }
       
        @EventHandler
        public void onBlockPlace(BlockPlaceEvent event) {
            if (!started) return;
            Player player = event.getPlayer();
            if (player == null || !playerList.contains(player.getName())) {
                return;
            }
            Integer value = blockValues.get(event.getBlock().getType());
            if (????????????????????) {
                player.sendMessage("test!");
                event.setCancelled(true);
            } else {
                event.setCancelled(false);
            }
        }
    @Scimiguy Hello again. I found a solution, but it's not very accurate, since I'd like to check if the block placed is in the blockValues map or not. For now it looks like this, which is very unefficient

    Code:
    @EventHandler
        public void onBlockPlace(BlockPlaceEvent event) {
            if (!started) return;
            Player player = event.getPlayer();
            if (player == null || !playerList.contains(player.getName())) {
                return;
            }
            if (event.getBlockPlaced().getType() == Material.GLOWING_REDSTONE_ORE ||
                    event.getBlockPlaced().getType() == Material.REDSTONE_ORE ||
                    event.getBlockPlaced().getType() == Material.GLOWING_REDSTONE_ORE ||
                    event.getBlockPlaced().getType() == Material.LAPIS_ORE ||
                    event.getBlockPlaced().getType() == Material.GOLD_ORE ||
                    event.getBlockPlaced().getType() == Material.DIAMOND_ORE ||
                    event.getBlockPlaced().getType() == Material.EMERALD_ORE) {
                player.sendMessage(ChatColor.RED + "Du kan inte placera detta block under eventets gång.");
                event.setCancelled(true);
            } else {
                event.setCancelled(false);
            }
        }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Nov 19, 2015
  8. Offline

    Scimiguy

    When you enable your plugin, create a HashSet<Material>
    Add the block types you want to block to that Set, and when it comes to the actual event, just do an
    if (HashSet#contains(Material))
     
  9. Offline

    tizrain

    @Scimiguy I will still have to do HashSet#Contains(Material) for every single block?
     
  10. Offline

    Scimiguy

    No you won't.

    if (HashMap#contains(event.getBlockPlaced().getType())) {
    }
     
  11. Offline

    tizrain

    @Scimiguy Thank you very much. It worked perfectly! One last question though, when you're still here.

    I'm trying to save swedish characters into a config. It works perfectly and it does it correctly, because the comments in the yaml file has no trouble with the Swedish characters, but my messages keeps getting messed up.

    I.E: Swedish letter Ä = \xc3\xa4 in a message while it's normal in a comment in the same file.

    It is coded in UTF-8 without BOM so it should support the swedish characters..

    Do you have any idea of why it does this?

    Nevermind, I found the issue. I used: saveConfig(); and that apparently messed everything up. I now use saveDefaultConfig(); instead and it works like a charm.

    I now found that it doesn't show the letters ingame instead. The config looks fine, but ingame it's messed up.

    EDIT: Written in new thread
     
    Last edited: Nov 20, 2015
  12. Offline

    Scimiguy

    Do some debugging
    Print to console what the message is when:
    • You get it from config
    • Right before you send it
    • What it shows up as in chat
     
Thread Status:
Not open for further replies.

Share This Page