Potential way to make your own World Guard

Discussion in 'Plugin Development' started by knightidus, Mar 13, 2012.

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

    knightidus

    Hello guys!!!


    I've been coding for bukkit for a reasonable amount of time now, and there hasn't been much that has been really difficult and had me thinking for a long time. But then i tried to make my own world guard like plugin, and that was difficult. My plugin consisted of taking 2 locations given by the player (left and right clicking) and then putting them into a yml for later reference. The hard part came when i was trying to see if a point was in the region given by the two points, and then if so do what ever i wanted like block or stop the player from editing the terrain. The point of me writing this is that i wanted to help other people with this problem, and share some code, and also improve on mine with other peoples help!! im not saying that this code below is perfect by any means, but some help on it would be appreciated, and feel free to use it!!
    Code:
    import java.util.ArrayList;
     
    import org.bukkit.Location;
    import org.bukkit.World;
    import org.bukkit.entity.Player;
     
    public class Zone{
     
        private Location point1;
        private Location point2;
        private ArrayList<Group> groups;
        private ArrayList<String> players;
        private boolean isPublic = false;
        private World world;
        private String name;
     
        public Zone(Location point1, Location point2, ArrayList<Group> g, ArrayList<String> p, World world){
          this.point1 = point1;
          this.point2 = point2;
          this.groups = g;
          this.players = p;
          this.world = world;
        }
     
        public void setPoint1(Location point1) {
            this.point1 = point1;
        }
     
        public Location getPoint1() {
            return point1;
        }
     
        public void setPoint2(Location point2) {
            this.point2 = point2;
        }
     
        public Location getPoint2() {
            return point2;
        }
     
        public void setGroups(ArrayList<Group> groups) {
            this.groups = groups;
        }
        public void addGroup(Group g){
            this.groups.add(g);
        }
        public ArrayList<Group> getGroups() {
            return groups;
        }
     
        public void setPlayers(ArrayList<String> players) {
            this.players = players;
        }
     
        public ArrayList<String> getPlayers() {
            return players;
        }
        public void addPlayer(String p){
            this.players.add(p);
        }
        public void removePlayer(Player p){
            this.players.remove(p);
        }
        public void removeGroup(Group g){
            this.groups.remove(g);
        }
     
        public void setPublic(boolean isPublic) {
            this.isPublic = isPublic;
        }
     
        public boolean isPublic() {
            return isPublic;
        }
     
        public void setWorld(World world) {
            this.world = world;
        }
     
        public World getWorld() {
            return world;
        }
        public ArrayList<Location> getInnerPoints(){
            ArrayList<Location> points = new ArrayList<Location>();
            Zone z = this;         
                Location p1 = z.getPoint1();
                Location p2 = z.getPoint2();
             
                int x1 = (int) p1.getX();
                int y1 = (int) p1.getY();
                int z1 = (int) p1.getZ();
             
                int x2 = (int) p2.getX();
                int y2 = (int) p2.getY();
                int z2 = (int) p2.getZ();
             
                int xd = x1 - x2;
                int yd = y1 - y2;
                int zd = z1 - z2;
             
                int totalDone = 0;
                int total = xd * yd * zd;
                         
                if(total < 0){
                    total = total - total - total;             
                }
                for(;totalDone <= total;){
                    int tx1 = x1;
                    int ty1 = y1;
                    int tz1 = z1;
                 
                    int tx2 = x2;
                    int ty2 = y2;
                    int tz2 = z2;
                 
                    if(x1 > x2 && y1 > y2 && z1 > z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1--;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);
                                    total++;
                                }
                                ty1--;
                            }
                            tz1--;
                        }
                    }
                    if(x1 < x2 && y1 > y2 && z1 > z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1++;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);total++;
                                }
                                ty1--;
                            }
                            tz1--;
                        }
                    }
                    if(x1 > x2 && y1 < y2 && z1 > z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1--;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);total++;
                                }
                                ty1++;
                            }
                            tz1--;
                        }
                    }
                    if(x1 > x2 && y1 > y2 && z1 < z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1--;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);total++;
                                }
                                ty1--;
                            }
                            tz1++;
                        }
                    }
                    if(x1 < x2 && y1 < y2 && z1 > z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1++;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);total++;
                                }
                                ty1++;
                            }
                            tz1--;
                        }
                    }
                    if(x1 < x2 && y1 > y2 && z1 < z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1++;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);total++;
                                }
                                ty1--;
                            }
                            tz1++;
                        }
                    }
                    if(x1 < x2 && y1 < y2 && z1 < z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1++;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);total++;
                                }
                                ty1++;
                            }
                            tz1++;
                        }
                    }
                    if(x1 > x2 && y1 < y2 && z1 < z2){
                        for(;tz1 != tz2;){
                            for(;ty1 != ty2;){
                                for(;tx1 != tx2;){
                                    tx1--;
                                    Location p = new Location(z.getWorld() ,tx1, ty1, tz1);
                                    points.add(p);total++;
                                }
                                ty1++;
                            }
                            tz1++;
                        }
                    }
                 
                }
                return points;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public String getName() {
            return name;
        }
    }
    Basically what i have done he is make a Zone class, and for every new Zone i want to make i simply use this class. To check if a point is in this Zone you simply call the getInnerPoints() method and check if that point is in there. Its a fairly simple idea, but it might cause some lag if it is called and the 2 points from a zone are a long way apart, so i call it when the server starts/reloads or when a new Zone is created.
     
  2. Offline

    Sorroko

    knightidus Thats a very cpu intensive way of doing things, would it not be easier to get point 1 x value, point 2 x value. If the player x is bigger than point 1 value and less than point 2 value then the player is inside the region. Do the same for z. Just an idea ;)
     
  3. Offline

    Taco

    This would probably be much better. Simply checking to see if the x y and z are within the bounds of the 2 points would be much less CPU heavy than storing all possible inner points.
     
  4. Offline

    knightidus

    Yeah, that's much better actually, minecraft already uses a huge amount of cpu on most computers and this would probably destroy it if it's called more than a couple of times at once. But the only problem i can see with trying your method would be when you introduce negative numbers, or if the second point's x y z coords are lower than point 1, thats why i had to add so many if's in the code to determine the orientation of the coords and then do the appropriate thing. I'll give that code a try later on tonight and see how it goes, cheers!!
     
  5. Offline

    desht

    You could take a look at my cuboid implementation here: https://github.com/desht/ChessCraft.../java/me/desht/chesscraft/regions/Cuboid.java

    Sort out the co-ordinate ordering when you create your Cuboid object, and you only need to do it once - Math.min() and Math.max() are your friends. My Cuboid guarantees that x1 <= x2, y1 <= y2, z1 <= z2. Then any contains() operation is a simple arithmetic comparison. It also makes other common operations a lot simpler too.

    Also avoid using Location objects where possible, especially creating lots of them in a loop. It's a not a particularly cheap operation.
     
  6. Offline

    Taien

    Like the guy above said, definitely don't use the method you're using now. I also have a self-made protection system that handles both cubes and spheres, and used the same method (without having seen his code) as desht. When the player sets the points, automatically determine the low and high z and change the points to represent the lows and highs, and then its a simple matter of checking whether the point is between those points integer-wise.

    Here's some methods from mine:
    Code:
    public boolean isBlockInArea(Location location)
        {
            if (location.getWorld() != this.getWorld()) return false;
            int x = location.getBlockX();
            int y = location.getBlockY();
            int z = location.getBlockZ();
            if (x >= lowX && x <= highX)
                if (y >= lowY && y <= highY)
                    if (z >= lowZ && z <= highZ) return true;
                    else return false;
                else return false;
            else return false;
        }
       
        public boolean isBlockInArea(Block block)
        {
            if (block.getWorld() != this.getWorld()) return false;
            int x = block.getX();
            int y = block.getY();
            int z = block.getZ();
            if (x >= lowX && x <= highX)
                if (y >= lowY && y <= highY)
                    if (z >= lowZ && z <= highZ) return true;
                    else return false;
                else return false;
            else return false;
        }
    And here's a useful one for detecting collision on cubes and spheres if you ever get into that:
    Code:
    public Block getClosestBlock(Location loc)
        {
            if (this.getWorld() != loc.getWorld()) return null;
            int pointx = 0;
            int pointy = 0;
            int pointz = 0;
            int locx = loc.getBlockX();
            int locy = loc.getBlockY();
            int locz = loc.getBlockZ();
            if (locx >= highX) pointx = highX;
            else if (locx <= lowX) pointx = lowX;
            else pointx = locx;
            if (locy >= highY) pointy = highY;
            else if (locy <= lowY) pointy = lowY;
            else pointy = locy;
            if (locz > highZ) pointz = highZ;
            else if (locz < lowZ) pointz = lowZ;
            else pointz = locz;
            return this.world.getBlockAt(pointx, pointy, pointz);
        }
     
Thread Status:
Not open for further replies.

Share This Page