Moving Blocks Problem

Discussion in 'Plugin Development' started by MrGriefer_, Sep 25, 2019.

  1. Offline

    MrGriefer_

    Hello,

    I'm trying to do something like the mini-game Hole In The Wall, and I managed to move an entire wall like shown here:
    Moving Wall (open)
    [​IMG]


    But whenever I set couple of blocks to air, like this:
    Image (open)
    [​IMG]


    and try to move the wall it will just fill all the air blocks and move the wall. What can I do in order to move the wall with the holes?

    Another problem I'm facing is whenever I build the wall facing south or north and start moving the wall it'll start moving sideways like this:
    Moving Sideways (open)
    [​IMG]
     
  2. Offline

    timtower Moderator Moderator

    @MrGriefer_ You need to store which blocks are set and which are not, then rebuild the wall based on that information.
    And for the moving: why not use the players facing direction to set the movement direction?
     
  3. Offline

    MrGriefer_

    Okay so whenever I try to start the moving animation I set the holes and then I stored the holes location in a Set<Block>, but when moving the wall to the next new location and and setting the new location to the old holes blocks and it doesn't seem to work.
    Code (open)

    PHP:
    private Set<BlockairBlocks = new HashSet<>();

    private 
    void start() {
        
    int minX plugin.getConfig().getInt("Wall.Min.X");
        
    int minY plugin.getConfig().getInt("Wall.Min.Y");
        
    int minZ plugin.getConfig().getInt("Wall.Min.Z");
                     
        
    int maxX plugin.getConfig().getInt("Wall.Max.X");
        
    int maxY plugin.getConfig().getInt("Wall.Max.Y");
        
    int maxZ plugin.getConfig().getInt("Wall.Max.Z");
                     
        
    //..
                     
        
    for (int i 04i++) {
            
    int x = (int) (maxX Math.round(Math.random() * (minX maxX)));
            
    int y = (int) (maxY Math.round(Math.random() * (minY maxY)));
            
    int z = (int) (maxZ Math.round(Math.random() * (minZ maxZ)));
            
    Location airBlock = new Location(player.getWorld(), xyz);
            
    airBlock.getBlock().setType(Material.AIR);
            
    airBlocks.add(airBlock.getBlock());
        }

        
    startMovement();       
    }

    private 
    void startMovement() {
        
    //..
     
        
    int minX min;
        
    int maxX max;

        @
    Override
        
    public void run() {
            
    minX++;
            
    maxX++;
         
            for (
    int wX minXwX <= maxXwX wX 1) {
                for (
    int wY minYwY <= maxYwY wY 1){
                    for (
    int wZ minZwZ <= maxZwZ wZ 1){
                        
    Location tmpBlock = new Location(player.getWorld(), wXwYwZ);
                        
    tmpBlock.getBlock().setType(material);
                        for (
    Block block airBlocks) {
                            
    block.getLocation().setX(wX);
                            
    block.getLocation().setY(wY);
                            
    block.getLocation().setZ(wZ);
                            
    block.setType(Material.AIR);
                        }
                    }
                }
            }
        }
    }


    This is just an example of what I did; this problem is so confusing :mad:
     
  4. Offline

    timtower Moderator Moderator

    @MrGriefer_ It creates a new location, every time you call getLocation().
    So you are setting a temporary variable.

    Instead:
    Have a list of locations, you can modify those.
     
  5. Offline

    MrGriefer_

    Hmm... Replaced Set<Block> with List<Location> but when setting the holes to the new location it'll set it to the entire wall. The wall just disappears.
    PHP:
    for (int wX minXwX <= maxXwX wX 1) {
        for (
    int wY minYwY <= maxYwY wY 1){
            for (
    int wZ minZwZ <= maxZwZ wZ 1){
                
    Location tmpBlock = new Location(player.getWorld(), wXwYwZ);
                
    tmpBlock.getBlock().setType(Material.ORANGE_TERRACOTTA);
                for (
    Location location airBlocks) {
                    
    location.setX(wX);
                    
    location.setY(wY);
                    
    location.setZ(wZ);
                    
    location.getBlock().setType(Material.AIR);
                }
            }
        }
    }
     
  6. Offline

    timtower Moderator Moderator

    @MrGriefer_ You do realize that you are setting the location of every air block to every block in the wall right?
    My suggestion:
    Make a list of pairs, Location, Material.
    Then for every iteration: get the locations, set all blocks to air (removing the old wall)
    Increment the location with the traveling direction.
    Set the block to the material attached to it.
     
  7. Offline

    MrGriefer_

    I know this sounds stupid but can you show me an example?
     
  8. Offline

    timtower Moderator Moderator

    Pseudo code
    Code:
    list<pair<Location, Material>> blocks; // Made when you created the wall
    for(pair : blocks){
    pair.location.getBlock().setType(air);
    pair.location.add(movementDirection);
    pair.location.getBlock().setType(pair.material);
    }
     
  9. Offline

    MrGriefer_

    I used the code below to remove the old wall and then set and move the new one, but I can't figure out how to do it with the Pair class, I used your code and nothing moves nor air blocks gets set.
    Code (open)

    Code:
    for (int wX = minX; wX <= maxX; wX = wX + 1) {
        for (int wY = minY; wY <= maxY; wY = wY + 1) {
            for (int wZ = minZ; wZ <= maxZ; wZ = wZ + 1) {
                Location tmpBlock = new Location(player.getWorld(), wX, wY, wZ);
                tmpBlock.getBlock().setType(Material.AIR);
            }
        }
    }
                   
    minX++;
    maxX++;
                   
    Material material = Material.ORANGE_TERRACOTTA;
    for (int wX = minX; wX <= maxX; wX = wX + 1) {
        for (int wY = minY; wY <= maxY; wY = wY + 1){
            for (int wZ = minZ; wZ <= maxZ; wZ = wZ + 1){
                Location tmpBlock = new Location(player.getWorld(), wX, wY, wZ);
                tmpBlock.getBlock().setType(material);
            }
        }
    }
     
  10. Offline

    timtower Moderator Moderator

    @MrGriefer_ 1. You only need a single loop.
    2. Make a list of pairs. First item is the location where the wall starts, second item is what type it is when the wall starts.

    You can almost copy my code btw. Only need to fill the list.
     
  11. Offline

    MrGriefer_

    The wall just disappears. I've tried debugging the code and everything seems to work fine.
    Code (open)

    PHP:
    private List<Pair<LocationMaterial>> blocks = new ArrayList<>();

    private 
    void addBlocks() {
        
    //..
        
    BlockVector3 min sel.getMinimumPoint();
        
    BlockVector3 max sel.getMaximumPoint();
       
        
    blocks.clear();   

        for (
    int x min.getBlockX(); <= max.getBlockX(); 1) {
            for (
    int y min.getBlockY(); <= max.getBlockY(); 1) {
                for (
    int z min.getBlockZ(); <= max.getBlockZ(); 1) {
                    
    Location tmpBlock = new Location(player.getWorld(), xyz);
                    
    tmpBlock.getBlock().setType(material);
                    
    blocks.add(new Pair<LocationMaterial>(tmpBlockmaterial));
                }
            }
        }

        for (
    int i 04i++) {
            
    int x = (int) (maxX Math.round(Math.random() * (minX maxX)));
            
    int y = (int) (maxY Math.round(Math.random() * (minY maxY)));
               
    int z = (int) (maxZ Math.round(Math.random() * (minZ maxZ)));
            
    Location airBlock = new Location(player.getWorld(), xyz);
            
    airBlock.getBlock().setType(Material.AIR);
            
    blocks.add(new Pair<LocationMaterial>(airBlockMaterial.AIR));
        }
    }

    private 
    void start() {
        
    //..

            
    int minX min;
            
    int maxX max;

            @
    Override
            
    public void run() {
                
    minX++;
                
    maxX++;

                for (
    int wX minXwX <= maxXwX wX 1) {
                    for (
    int wY minYwY <= maxYwY wY 1){
                        for (
    int wZ minZwZ <= maxZwZ wZ 1){
                            for (
    Pair<LocationMaterialblock blocks) {
                                
    block.getKey().getBlock().setType(Material.AIR);
                                
    block.getKey().setX(wX);
                                
    block.getKey().setY(wY);
                                
    block.getKey().setZ(wZ);
                                
    block.getKey().getBlock().setType(block.getValue());
                            }
                        }
                    }
                }
            }
    }
     
  12. Offline

    timtower Moderator Moderator

    @MrGriefer_ Do make sure that you don't have double locations in that list, you do have that now.
    And don't use a triple loop, you don't need it, please reference my code.
    You only need the loop ovee the pairs.
     
  13. Offline

    MrGriefer_

    Double locations? You mean I should use int instead of double?
    The triple loop is used to move the wall to the next new location, in your code you did pair.getKey().add(movementDirection); I’m guessing movementDirection is the new location, and if I add the new location to the pair the wall will stay as it is.
     
  14. Offline

    timtower Moderator Moderator

    No, you are adding new items to the list, items in the wall, those locations that you are adding are already in the list but with different type.

    You don't need the triple loop, if you look at the locations then they are all the same at the end.
    movementDirection is a Vector where one of the 3 values is 1 or -1.
     
  15. Offline

    MrGriefer_

    Okay thank you I finally got it working, just one question I keep getting NoClassDefFoundError javafx.util.Pair any idea how to fix this error. I followed these steps to install JavaFX.
     
  16. Offline

    timtower Moderator Moderator

    @MrGriefer_ Use a different pair class, if there is one.
    If not: make one, wrapper class that holds two types.
     
  17. Offline

    MrGriefer_

    Okay thank you I got it working, any idea on how to set the holes on the wall to another wall but the same location, for example if the holes in the wall are 2 blocks at the top left corner it will set the same thing for another wall top left corner. Take a look at the picture below:

    Image (open)
    [​IMG]
     
  18. Offline

    timtower Moderator Moderator

    @MrGriefer_ Order of the blocks is always the same, you can pick a certain index in the list to change.
     
  19. Offline

    MrGriefer_

    Sorry to bump this thread I didn't have the time to try this, can you give an example?
     
  20. Offline

    timtower Moderator Moderator

    Have 2 lists.
    Have a random function.
    Generate a couple random numbers.
    Those numbers are air blocks in both lists.
     
  21. Offline

    MrGriefer_

    Why do I need to have 2 lists, could you show me an example code?
     
  22. Offline

    timtower Moderator Moderator

    One for each wall.
    Don't have that now
     

Share This Page