Store blocks in a arraylist and rollback it?

Discussion in 'Plugin Development' started by Funergy, Mar 6, 2014.

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

    Funergy

    Hey guys I'm currently stuck in the map rollback.
    I'm making 'Athena's Quil' a custom spleef minigame
    but I wanna rollback the snowblocks but I don't know how
    I've heard about store block into an arraylist and then rollback them by
    Code:
    for(Block b : brokensnow){
    //here is the rollback
    b.setType(b.getType);
    but it doesn't work.
     
  2. Offline

    Wolfey

    Make another arraylist for the material of the block.
     
  3. Offline

    Funergy

    can you please send me some code for that. I'm not understanding
     
  4. Offline

    Wolfey

    Make another arraylist for the type of block, then when you add a block to your 'brokensnow' list, also add the type to the material list. Then when you're ready to reset, run a for-loop on the both of them, and change the blocks.
     
  5. Offline

    Funergy

    do I need to set the 2 things in one for-loop?
    and for the arraylist is it ArrayList<Block> or something else
     
  6. Offline

    Wolfey

    ArrayList<Material>, and when you're adding something to your 'brokensnow' list, add one to the material ArrayList as well.
    Code:java
    1. materiallist.add(block.getType());
     
  7. Offline

    Funergy

    and for the other arraylist what do I need to add (the ArrayList<Block>)
    and how can I replace it
     
  8. Offline

    NathanWolf

    I think you can store the BlockData object that comes with each Block, and then restore the previous state using that object. This will preserve chest contents, sign lines, etc.
     
  9. Offline

    Funergy

    I tried but it didn't work. can you please send me the code for that?

    Wolfey ?

    Wolfey and NathanWolf
    this is what I have

    the map rollback
    Code:
    for(BlockState b : snowblocks){
                        b.setData(b.getData());
                        b.setType(b.getBlock().getType());
                    }
    and the block add to arraylist
    Code:
    @EventHandler
        public void onsnowbreak(PlayerInteractEvent e) {
            if (game) {
                if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                    if (e.getClickedBlock().getType().equals(Material.SNOW_BLOCK)) {
                        if (e.getPlayer().getItemInHand().getType()
                                .equals(Material.DIAMOND_SPADE)) {
                            e.getClickedBlock().setType(Material.AIR);
                            e.getClickedBlock().getDrops().clear();
                            snowblocks.add(e.getClickedBlock().getState());
                       
                        }
                    }
                }
            }
        }
    BUMP

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

    NathanWolf

    For your rollback, I think you only need to call BlockState.update. The object stores the block location as well as its state, so it is able to update the block in a contained way. Handy!

    EDIT: Note that I'm not 100% sure about this- but I think that will be the case. Personally I store my own block state kind of object for doing rollback, but to be honest that may only be because BlockState didn't exist when I first wrote my undo system. I kind of want to take a look at refactoring it....
     
  11. Offline

    Funergy

    so I need to update the state by doing b.getBlock.getState.update();
    EDIT: I tried to add b.getBlock.getState.update(); but it still didn't work
     
  12. Offline

    NathanWolf

    If "snowBlocks" contains BlockState objects, I think you can simply do

    for (BlockState block : snowBlocks) { block.update(); }
     
  13. Offline

    Funergy

    Doesn't work
     
  14. Offline

    diage

    You might consider not saving airblocks to the list of blocks you want to roll back?
     
  15. Offline

    Funergy

    I'm checking if the block is a snowblock
    Code:
    @EventHandler
        public void onsnowbreak(PlayerInteractEvent e) {
            if (game) {
                if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                    if (e.getClickedBlock().getType().equals(Material.SNOW_BLOCK)) {
                        if (e.getPlayer().getItemInHand().getType()
                                .equals(Material.DIAMOND_SPADE)) {
                            e.getClickedBlock().setType(Material.AIR);
                            e.getClickedBlock().getDrops().clear();
                            snowblocks.add(e.getClickedBlock().getState());
                     
                        }
                    }
                }
            }
        }
     
  16. Offline

    diage

    e.getClickedBlock().setType(Material.AIR);
    ...
    snowblocks.add(e.getClickedBlock().getState());
     
  17. Offline

    Barinade

    Use a map for location and material, runTaskLater to set back (clear map after)
     
  18. Offline

    diage

    That above should work.. the implementation you have now makes me wonder about the mutability of BlockState which can potentially cause errors. (And will definitely cause errors in the order yours calling the methods)
     
  19. Offline

    Funergy

    bump

    Can anyone help me why the map rollback doesn't work
    Code:
    package me.Funergy.spleef;
     
    import java.util.ArrayList;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.Sound;
    import org.bukkit.World;
    import org.bukkit.block.BlockState;
    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.EventPriority;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.event.entity.EntityDamageEvent;
    import org.bukkit.event.entity.FoodLevelChangeEvent;
    import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
    import org.bukkit.event.player.PlayerDropItemEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerKickEvent;
    import org.bukkit.event.player.PlayerLoginEvent;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.event.player.PlayerQuitEvent;
    import org.bukkit.event.weather.WeatherChangeEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class main extends JavaPlugin implements Listener {
        public int starting = 30;
        public int spread = 10;
        boolean game;
        boolean end;
        boolean spreadtime;
        int start;
        int spreadtimer;
        public ArrayList<String> online = new ArrayList<String>();
        public ArrayList<BlockState> snowblocks = new ArrayList<BlockState>();
        public void onEnable() {
            for (World world : Bukkit.getWorlds()) {
                world.setPVP(false);
                world.setMonsterSpawnLimit(0);
            }
            Bukkit.getLogger().info("Spleef is Enabled!");
            Bukkit.getLogger().info("The Spleef plugin is made by Funergy!");
            Bukkit.getLogger()
                    .warning(
                            "If you wanna build the arena please put the spleef plugin out of the plugins!");
            Bukkit.getPluginManager().registerEvents(this, this);
     
            Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
     
                @Override
                public void run() {
                    for (World world : Bukkit.getWorlds()) {
                        world.setTime(6000);
                    }
                }
            }, 0, 40);
        }
       
     
        @EventHandler
        public void onjoin(PlayerJoinEvent e) {
            online.add(e.getPlayer().getName());
            Bukkit.broadcastMessage(e.getPlayer().getDisplayName()
                    + " §6Has Joined the game! §b[" + online.size() + "/"
                    + Bukkit.getMaxPlayers() + "]");
            e.setJoinMessage(null);
            if (online.size() == 1) {
                if (!Bukkit.getScheduler().isQueued(start)) {
                    Bukkit.broadcastMessage("§7[§cAthena's Quill§7]: §6Enough Players online starting game in 30 seconds");
                    onEnoughPlayers();
                }
            }
            Player p = e.getPlayer();
            getConfig().options().copyDefaults(true);
            saveConfig();
            int xlobby = getConfig().getInt("xlobby");
            int ylobby = getConfig().getInt("ylobby");
            int zlobby = getConfig().getInt("zlobby");
            org.bukkit.World world = p.getWorld();
            p.teleport(new Location(world, xlobby, ylobby, zlobby));
        }
     
        public void onEnoughPlayers() {
            start = Bukkit.getScheduler().scheduleSyncRepeatingTask(this,
                    new Runnable() {
     
                        @Override
                        public void run() {
                            if (starting != 0) {
                                if (starting != 0) {
                                      starting--;
                                } else {
                                    for (Player p : Bukkit.getOnlinePlayers()) {
                                        getConfig().options().copyDefaults(true);
                                        saveConfig();
                                        int x1 = getConfig().getInt("x1");
                                        int y1 = getConfig().getInt("y1");
                                        int z1 = getConfig().getInt("z1");
                                        org.bukkit.World world = p.getWorld();
                                        p.teleport(new Location(world, x1, y1, z1));
     
                                    }
     
                                    starting--;
                                }
                                if (starting < 11) {
                                    Bukkit.broadcastMessage("§7[§cAthena's Quill§7]: §6Game starting in "
                                            + starting);
                                }
                                if (starting == 0) {
                                    for (Player p : Bukkit.getOnlinePlayers()) {
                                        getConfig().options().copyDefaults(true);
                                        saveConfig();
                                        int x1 = getConfig().getInt("x1");
                                        int y1 = getConfig().getInt("y1");
                                        int z1 = getConfig().getInt("z1");
                                        org.bukkit.World world = p.getWorld();
                                        p.teleport(new Location(world, x1, y1, z1));
                                        spreadout();
                                    }
                                }
                            }
                        }
                    }, 0, 20);
     
        }
     
        public void spreadout() {
            if (!Bukkit.getScheduler().isQueued(spreadtimer)) {
                spreadtime = true;
                Bukkit.broadcastMessage("§7[§cAthena's Quill§7]: §6You have 10 seconds to spread out!");
                spreadtimer = Bukkit.getScheduler().scheduleSyncRepeatingTask(this,
                        new Runnable() {
     
                            @Override
                            public void run() {
                                if (spread != -1) {
                                    if (spread != 0) {
                                        spread--;
                                    } else {
                                        spread--;
                                        ingame();
                                        spreadtime = false;
                                        game = true;
                                    }
                                    if (spread < 6) {
                                        if (spread > -1) {
                                            Bukkit.broadcastMessage("§7[§cAthena's Quill§7]: §6"
                                                    + spread);
                                            for (Player p : Bukkit
                                                    .getOnlinePlayers()) {
                                                p.playSound(p.getLocation(),
                                                        Sound.NOTE_STICKS, 1, 1);
                                            }
                                        }
                                    }
                                }
                            }
                        }, 0, 20);
     
            }
        }
     
        @EventHandler
        public void onsnowbreak(PlayerInteractEvent e) {
            if (game) {
                if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                    if (e.getClickedBlock().getType().equals(Material.SNOW_BLOCK)) {
                        if (e.getPlayer().getItemInHand().getType()
                                .equals(Material.DIAMOND_SPADE)) {
                            e.getClickedBlock().setType(Material.AIR);
                            e.getClickedBlock().getDrops().clear();
                            snowblocks.add(e.getClickedBlock().getState());
                           
                       
                        }
                    }
                }
            }
        }
     
        @EventHandler
        public void onblockbreak(BlockBreakEvent e) {
            if (!game) {
                e.setCancelled(true);
            } else {
                if (!e.getBlock().getType().equals(Material.SNOW_BLOCK)) {
                    e.setCancelled(true);
                }
            }
        }
     
        public boolean onCommand(CommandSender sender, Command cmd, String label,
                String[] args) {
            Player player = (Player) sender;
            getConfig().options().copyDefaults(true);
            saveConfig();
            if (cmd.getName().equalsIgnoreCase("setspawn")) {
                getConfig().set("x1", player.getLocation().getBlockX());
                getConfig().set("y1", player.getLocation().getBlockY());
                getConfig().set("z1", player.getLocation().getBlockZ());
                saveConfig();
                player.sendMessage("§7[§cAthena's Quill§7]: §6Ingame spawnpoint spawn set!");
     
            }
            if (cmd.getName().equalsIgnoreCase("setlobby")) {
                getConfig().set("xlobby", player.getLocation().getBlockX());
                getConfig().set("ylobby", player.getLocation().getBlockY());
                getConfig().set("zlobby", player.getLocation().getBlockZ());
                saveConfig();
                player.sendMessage("§7[§cAthena's Quill§7]: §6Lobby spawn set!");
            }
            if (cmd.getName().equalsIgnoreCase("setspectator")) {
                getConfig().set("xspec", player.getLocation().getBlockX());
                getConfig().set("yspec", player.getLocation().getBlockY());
                getConfig().set("zspec", player.getLocation().getBlockZ());
                saveConfig();
                player.sendMessage("§7[§cAthena's Quill§7]: §6Spectator spawn set!");
            }
            return false;
        }
     
        public void ingame() {
            Bukkit.broadcastMessage("§7[§cAthena's Quill§7]: §6Game started!");
            for (Player p : Bukkit.getOnlinePlayers()) {
                p.playSound(p.getLocation(), Sound.NOTE_PLING, 1, 1);
                ItemStack shovel = new ItemStack(Material.DIAMOND_SPADE, 1);
                ItemMeta shovelmeta = shovel.getItemMeta();
                shovelmeta.setDisplayName("§6Diamond Shovel");
                shovel.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
                shovel.setItemMeta(shovelmeta);
                p.getInventory().addItem(shovel);
            }
     
        }
     
        @EventHandler
        public void onmove(PlayerMoveEvent e) {
            Material m = e.getPlayer().getLocation().getBlock().getType();
            if (game) {
                if (m == Material.STATIONARY_LAVA || m == Material.LAVA) {
                    online.remove(e.getPlayer().getName());
                    e.getPlayer().getInventory().clear();
                    Bukkit.broadcastMessage("§7[§cAthena's Quill§7]: §6"
                            + e.getPlayer().getName() + " Has died §b["
                            + online.size() + "/" + Bukkit.getMaxPlayers() + "]");
                    getConfig().options().copyDefaults(true);
                    saveConfig();
                    int xspec = getConfig().getInt("xspec");
                    int yspec = getConfig().getInt("yspec");
                    int zspec = getConfig().getInt("zspec");
                    org.bukkit.World world = e.getPlayer().getWorld();
                    e.getPlayer()
                            .teleport(new Location(world, xspec, yspec, zspec));
                    check();
                }
            }
        }
     
        @EventHandler
        public void onFoodLevelChange(FoodLevelChangeEvent e) {
            e.setCancelled(true);
        }
     
        public void check() {
            if (game) {
                if (online.size() == 0) {
                    ending();
                    end = true;
                    game = false;
                    Bukkit.broadcastMessage("§c-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
                    Bukkit.broadcastMessage("§c-=-=-=-= §b" + online
                            + " §6Has won! §c-=-=-=-=");
                    Bukkit.broadcastMessage("§c-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
                    for (Player p : Bukkit.getOnlinePlayers()) {
                        p.getInventory().clear();
                        if (online.contains(p.getName())) {
                            online.remove(p.getName());
                        }
                    }
                    for(BlockState b : snowblocks){
                        b.getBlock().setType(b.getBlock().getType());
                        b.getLocation();
                        b.update();
                    }
                }
            }
        }
     
        @EventHandler
        public void onquit(PlayerQuitEvent e) {
            if (game) {
                if (online.contains(e.getPlayer().getName())) {
                    e.setQuitMessage("§7[§cAthena's Quill§7]: §6"
                            + e.getPlayer().getName() + " Has died §b["
                            + online.size() + "/" + Bukkit.getMaxPlayers() + "]");
                    online.remove(e.getPlayer().getName());
                } else {
                    e.setQuitMessage(null);
                }
            }
            e.setQuitMessage(null);
        }
     
        @EventHandler
        public void damage(EntityDamageEvent e) {
            if (e.getCause() == DamageCause.FIRE) {
                e.setCancelled(true);
            }
            if (e.getCause() == DamageCause.LAVA) {
                e.setCancelled(true);
            }
            if (e.getCause() == DamageCause.FIRE_TICK) {
                e.setCancelled(true);
            }
            if (e.getCause() == DamageCause.FALL) {
                e.setCancelled(true);
            }
        }
     
        @EventHandler
        public void weather(WeatherChangeEvent e) {
            e.setCancelled(true);
        }
     
        public void ending() {
            Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
     
                @Override
                public void run() {
                    for (Player p : Bukkit.getOnlinePlayers()) {
                        p.kickPlayer("");
                        end = false;
                        Bukkit.getScheduler().cancelAllTasks();
                        spread = 10;
                        starting = 30;
                    }
     
                }
            }, 200);
     
        }
     
        @EventHandler(priority = EventPriority.MONITOR)
        public void onJoin(PlayerLoginEvent event) {
            if (game) {
                if (!event.getPlayer().isWhitelisted()) {
                    event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST,
                            "The game has already started!");
                }
                if (end) {
                    if (!event.getPlayer().isWhitelisted()) {
                        event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST,
                                "The game is ending!");
                    }
                    if(spreadtime){
                        if (!event.getPlayer().isWhitelisted()) {
                            event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST,
                                    "The Game is already starting!");
                        }
                       
                    }
                }
            }
        }
        @EventHandler
        public void onkick(PlayerKickEvent e) {
            if (game) {
                if (online.contains(e.getPlayer().getName())) {
                    Bukkit.broadcastMessage("§7[§cAthena's Quill§7]: §6"
                            + e.getPlayer().getName() + " Has died §b["
                            + online.size() + "/" + Bukkit.getMaxPlayers() + "]");
                    online.remove(e.getPlayer().getName());
                    e.setLeaveMessage(null);
                }else{
                    e.setLeaveMessage(null);
                }
            }
            e.setLeaveMessage(null);
        }
        @EventHandler
        public void ondrop(PlayerDropItemEvent e){
            e.setCancelled(true);
        }
       
    }
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
Thread Status:
Not open for further replies.

Share This Page