Rolling back an arena [Spleff]

Discussion in 'Plugin Development' started by gamemster2468, Jun 8, 2014.

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

    gamemster2468

    Hi,

    I'm working on a Spleff plugin and I'm having a bit of trouble with rolling back the blocks broken.

    So far this is my code:
    Code:
    public static void unloadMap(String mapname){
            if(Bukkit.getServer().unloadWorld(Bukkit.getServer().getWorld(mapname), false)){
                plugin.getLogger().info("Successfully unloaded " + mapname);
            }else{
                plugin.getLogger().severe("COULD NOT UNLOAD " + mapname);
            }
        }
        //Loading maps (MUST BE CALLED AFTER UNLOAD MAPS TO FINISH THE ROLLBACK PROCESS)
        public static void loadMap(String mapname){
            Bukkit.getServer().createWorld(new WorldCreator(mapname));
        }
     
        //Maprollback method, because were too lazy to type 2 lines
        public static void rollback(String mapname){
            unloadMap(mapname);
            loadMap(mapname);
        }
       
        public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
            if (command.getName().equalsIgnoreCase("Reset")) {
                unloadMap("Spleff");
                loadMap("Spleff");
                sender.sendMessage("Map rolled back!");
            }
            return false;
        }
    
    Any help would be great.
    Thanks! <3
     
  2. Offline

    ResultStatic

    gamemster2468 why dont you store all the blocks broken in a list<Blocks> when they are broken with the block break event and loop through them to fix it. its not very many blocks so it shouldnt cause lag. basically what worldedit does only much more complex.
     
  3. Offline

    gamemster2468

    I tried that here but it failed, I used a Hashmap.

    If you wouldn't mind giving me an example, that would be great :)
    ResultStatic

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

    ResultStatic

    gamemster2468
    here is how u would store the broken blocks. then make a method to reset those effected blocks

    Code:
    List<Block> blocks = new ArrayList<Block>();
    @EventHandler
    public void blockbreak(BlockBreakEvent e){
    // might also want to check if they are in that event.
    // but since you were going to reset the world it doesnt matter
    if (e.getPlayer().getWorld().getName().equals(worldname)){
    blocks.add(e.getBlock());
    }
    }
    you can loop thru list with

    Code:
    for (Block brokenblocks: blocks){
     
  5. Offline

    gamemster2468

    With the for loop, should I do update blocks?

    Edit: Basically how would I roll it back with this data?

    ResultStatic

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

    ResultStatic

    gamemster2468 try this. i thought using a list would work but you would end up with blocks.setType()(blocks.getType()); which doesnt seem right. this should work tho try it
    Code:
    HashMap<Location, Material> blocks = new HashMap<Location, Material>();
    @EventHandler
    public void blockbreak(BlockBreakEvent e){
     
    if (e.getPlayer().getWorld().getName().equals(worldname)){
    //store the location and the material
    blocks.put(e.getBlock().getLocation(),e.getBlock().getType());
    }
     
    }
     
    public void reset(){
    //loop thru the first value/locations stored. get the current block at that location and set it to //the material stored for that location
    for (Location loc : blocks.keySet()){
    loc.getBlock().setType(blocks.get(loc));
    }
    }
     
  7. Offline

    gamemster2468

    It worked! Thanks so much! <3

    The code worked great for breaking blocks, but I'm using bow spleff, so it doesn't roll back the tnt that was fired off.

    Do you or anyone know how I could register it as a block break?

    Thanks ResultStatic

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

    NathanWolf

    You can catch that with the EntityExplodeEvent, it will give you the list of blocks exploded.
     
  9. Offline

    gamemster2468

    So I would replace the onBreak(BlockBreakEvent event) with onExplode(EntiyExplodeEvent Event)? NathanWolf

    I'm gettting some errors with that Event, mind giving me an example? <3

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

    ResultStatic

    gamemster2468
    Code:
    //same list as before
    HashMap<Location, Material> blocks = new HashMap<Location, Material>();
    @EventHandler
    public void onexplode(EntityExplodeEvent e){
    //loop through every block that is blown up. this event is called before it breaks the blocks and puts  the effected blocks in e.getblockList()
    //then for everyblock effected put its location and material in the reset list
    for (Block block : e.blockList()){
    blocks.put(block.getLocation(), block.getType());
    }
    }
     
  11. Offline

    Garris0n

    1. You can't just store Blocks, you have to store BlockStates and call update() to roll them back.
    2. You have to delete the entire world folder, you can't just unload the world. The createWorld method will load a world if the folder already exists.
     
  12. Offline

    gamemster2468

    So I would put for (Block block : e.getblockList()) {
    blocks.put(block.getLocation(), block.getType();
    }
    Once the command is run?

    I'm not doing the first way with uploading the world anymore.

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

    Garris0n

    That's the safest way.

    Regardless, see the first point.
     
  14. Offline

    NathanWolf


    You need both events, if players can also break blocks other than via explosion.

    It's not just a swap-out, though- look at the event. It has a method to retrieve the list of blocks destroyed, so you'll get more than one block per event- but otherwise it's the same.

    And, also, yes to what Garris0n said- you need to store BlockState, not Block. The Block object doesn't "remember" its state, so it won't help you here.
     
  15. Offline

    gamemster2468

    The only way the tnt will fall is by a bow with flame one NathanWolf
     
  16. Offline

    NathanWolf


    Oh okay... Uh sorry I'm actually not sure what event that is.
     
  17. Offline

    gamemster2468

    This is my problem:

    When the tnt falls, how do I reset it back?

    NathanWolf

    Bump

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

    spy_1134

    So you're trying to get the TNT that has been primed back into it's original location?
    You're looking for ExplosionPrimeEvent I think. The problem is, I think it returns the TNTPrimed entity from the event, in which case you may not be able to get the block state of the TNT block that was originally there. Maybe you could try setting the block's material back to TNT temporarily then saving the block state and changing it back to air?
     
  19. Offline

    gamemster2468

  20. Offline

    spy_1134

    If I understand you correctly, your players shoot at a block of TNT with a bow and it comes down flashing, right? That primes the TNT block which is a different event from breaking a block or having it blown up. You would need 3 different event handlers then, but I don't know how to get the block state of the TNT block before it falls.
     
  21. Offline

    gamemster2468

    Bump, does anyone know how I would revert the arena back with tnt? <3
     
Thread Status:
Not open for further replies.

Share This Page