1.16.5 Loop runs once and then stops

Discussion in 'Spigot Plugin Development' started by JusticeKing, Jul 11, 2021.

  1. This void is supposed to build a structure randomly around a villager. It only fires once when the server starts up and then it stops working. The xyz loop just doesn't work, but I found out it is still running using console, but the loop just doesn't do anything.
    Code (Text):
    public void HouseTick() {
            Random r = new Random();
            for(Player p : getServer().getOnlinePlayers()) {
                Building building = buildings.get(r.nextInt(buildings.size()));
                Villager v = getRandomVillager(p);
                if(v != null) {
                    Location loc = v.getLocation().add(new Vector(r.nextInt(100) - 50, 0, r.nextInt(100) - 50));
                    loc = loc.getWorld().getHighestBlockAt(loc).getLocation().add(0, 1, 0);
                   
                    Location a = loc.add(new Vector().subtract(building.origin));
                    Location b = loc.add(building.size.subtract(building.origin));
                    if(FreeSpace(a, b)) {
                       
                        int i = 0;
                        for(int y = 0; y < building.size.getY(); y++) {
                            for(int z = 0; z < building.size.getZ(); z++) {
                                for(int x = 0; x < building.size.getX(); x++) {
                                    ConsoleLog("block");
                                    loc.getWorld().getBlockAt(new Location(loc.getWorld(), x + loc.getX(), y + loc.getY(), z + loc.getZ()).subtract(building.origin)).setType(building.blocks[i]);
                                    i++;
                                }
                            }
                        }
                    }
                }
            }
        }
     
  2. Can you give us more context, or how the Building and Villager classes look like?
    Also, the code looks pretty messy with all vectors and add stuff. Give us some commentaries on what is doing every part of the code.
     
  3. I added explanations for each part.

    Here is the BuildTick
    Code (Text):
    public void HouseTick() {
            Random r = new Random();
            //loop all players
            for(Player p : getServer().getOnlinePlayers()) {
                //get random building
                Building building = buildings.get(r.nextInt(buildings.size()));
                //get random villager
                Villager v = getRandomVillager(p);
                if(v != null) {
                    //get random location around villager
                    Location loc = v.getLocation().add(new Vector(r.nextInt(100) - 50, 0, r.nextInt(100) - 50));
                    loc = loc.getWorld().getHighestBlockAt(loc).getLocation().add(0, 1, 0);
                    //get corners based off origin
                    Location a = loc.add(new Vector().subtract(building.origin));
                    Location b = loc.add(building.size.subtract(building.origin));
                    //get if space is free
                    if(FreeSpace(a, b)) {
                       
                        //loop all blocks
                        int i = 0;
                        for(int y = 0; y < building.size.getY(); y++) {
                            for(int z = 0; z < building.size.getZ(); z++) {
                                for(int x = 0; x < building.size.getX(); x++) {
                                    ConsoleLog(new Location(loc.getWorld(), x + loc.getX(), y + loc.getY(), z + loc.getZ()).subtract(building.origin));
                                    //place blocks
                                    loc.getWorld().getBlockAt(new Location(loc.getWorld(), x + loc.getX(), y + loc.getY(), z + loc.getZ()).subtract(building.origin)).setType(building.blocks[i]);
                                    i++;
                                }
                            }
                        }
                    }
                }
            }
        }

    Here is the Freespace
    Code (Text):
    public boolean FreeSpace(Location a, Location b) {
            int x1 = a.getBlockX();
            int y1 = a.getBlockY();
            int z1 = a.getBlockZ();
            int x2 = b.getBlockX();
            int y2 = b.getBlockY();
            int z2 = b.getBlockZ();
           
            int xMin, yMin, zMin;
            int xMax, yMax, zMax;
           
            int x,y,z;
           
            if(x1 > x2) {
                xMin = x2;
                xMax = x1;
            } else {
                xMin = x1;
                xMax = x2;
            }
            if(y1 > y2) {
                yMin = y2;
                yMax = y1;
            } else {
                yMin = y1;
                yMax = y2;
            }
            if(z1 > z2) {
                zMin = z2;
                zMax = z1;
            } else {
                zMin = z1;
                zMax = z2;
            }
           
            for(x = xMin; x <= xMax; x ++){
                for(y = yMin; y <= yMax; y ++){
                    for(z = zMin; z <= zMax; z ++){
                        Block block = new Location(a.getWorld(), x, y, z).getBlock();
                        if(block.getType() != Material.AIR && block.getType() != Material.GRASS  && block.getType() != Material.TALL_GRASS) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    Here is the building class
    Code (Text):
    public class Building {
            public Vector size;
            public Vector origin;
            Material[] blocks;
            public Building(Vector size, Vector origin, Material[] blocks) {
                this.size = size;
                this.origin = origin;
                this.blocks = blocks;
            }
        }