content: package com.rs2.world.clip;
  
  import java.util.ArrayList;
  
  import org.apollo.cache.def.ObjectDefinition;
  
  import com.rs2.game.objects.Objects;
  
  public class Region {
  	
  	private ArrayList<Objects> realObjects = new ArrayList<Objects>();
  	private final int id;
  	private final int[][][] clips = new int[4][][];
  	private final int[][][] projectileClips = new int[4][][];
  	private boolean members = false;
  
  	public Region(int id, boolean members) {
  		this.id = id;
  		this.members = members;
  	}
  
  	public int id() {
  		return id;
  	}
  
  	public boolean members() {
  		return members;
  	}
  
  	public static boolean isMembers(int x, int y) {
  		if (x >= 3272 && x <= 3320 && y >= 2752 && y <= 2809) {
  			return false;
  		}
  		if (x >= 2640 && x <= 2677 && y >= 2638 && y <= 2679) {
  			return false;
  		}
  		return getRegion(x, y).members();
  	}
  	
  	/**
  	 * Takes X Y coordinates, gives a region object
  	 * 
  	 * @param x coordinate X
  	 * @param y coordinate Y
  	 * @return Region object
  	 */
  	public static Region getRegion(int x, int y) {
  	    int regionId = getRegionId(x,y);
  	    for (Region region : RegionFactory.getRegions()) {
  	        if (region.id() == regionId) {
  	            return region;
  	        }
  	    }
  	    return null;
  	}
  	
  	/**
  	 * Calculates regionId from X Y coordinates
  	 * 
  	 * @param x coordinate X
  	 * @param y coordinate Y
  	 * @return ID of target region
  	 */
  	public static int getRegionId(int x, int y) {
  	    int regionX = x >> 3;
  	    int regionY = y >> 3;
  	    int regionId = (regionX / 8 << 8) + regionY / 8;
  	    return regionId;
  	}
  
  	public static Objects getObject(int id, int x, int y, int z) {
  		Region r = getRegion(x, y);
  		if (r == null)
  			return null;
  		for (Objects o : r.realObjects) {
  			if (o.objectId == id) {
  				if (o.objectX == x && o.objectY == y && o.objectHeight == z) {
  					return o;
  				}
  			}
  		}
  		return null;
  	}
  
  	public static boolean objectExists(int id, int x, int y, int z) {
  	    Region r = getRegion(x, y);
  	    if (r == null)
  	        return false;
  	    for (Objects o : r.realObjects) {
  	        if (o.objectId == id) {
  	            if (o.objectX == x && o.objectY == y && o.objectHeight == z) {
  	                return true;
  	            }
  	        }
  	    }
  	    return false;
  	}
  
  	private void addClip(int x, int y, int height, int shift) {
  		int regionAbsX = (id >> 8) * 64;
  		int regionAbsY = (id & 0xff) * 64;
  		if (clips[height] == null) {
  			clips[height] = new int[64][64];
  		}
  		clips[height][x - regionAbsX][y - regionAbsY] |= shift;
  	}
  
  	private void removeClip(int x, int y, int height) {
  		final int regionAbsX = (id >> 8) * 64;
  		final int regionAbsY = (id & 0xff) * 64;
  		if (clips[height] == null) {
  			clips[height] = new int[64][64];
  		}
  		clips[height][x - regionAbsX][y - regionAbsY] = 0;
  	}
  
  	/**
  	 * Nothing calls this...
  	 * 
  	 * @param x
  	 * @param y
  	 * @param height
  	 */
  	public void removeClipping(int x, int y, int height) {
  		for (Region r : RegionFactory.getRegions()) {
  			if (r.id() == getRegionId(x,y)) {
  				r.removeClip(x, y, height);
  				break;
  			}
  		}
  	}
  
  	private void addProjectileClip(int x, int y, int height, int shift) {
  		int regionAbsX = (id >> 8) * 64;
  		int regionAbsY = (id & 0xff) * 64;
  		if (projectileClips[height] == null) {
  			projectileClips[height] = new int[64][64];
  		}
  		projectileClips[height][x - regionAbsX][y - regionAbsY] |= shift;
  	}
  
  	public static boolean canMove(int x, int y, int z, int direction) {
  		if (direction == 6) {
  			if ((Region.getClipping(x, y - 1, z) & 0x1280102) == 0) {
  				return true;
  			}
  		} else if (direction == 3) {
  			if ((Region.getClipping(x - 1, y, z) & 0x1280108) == 0) {
  				return true;
  			}
  		} else if (direction == 1) {
  			if ((Region.getClipping(x, y + 1, z) & 0x1280120) == 0) {
  				return true;
  			}
  		} else if (direction == 4) {
  			if ((Region.getClipping(x + 1, y, z) & 0x1280180) == 0) {
  				return true;
  			}
  		} else if (direction == 5) {
  			if ((Region.getClipping(x - 1, y - 1, z) & 0x128010e) == 0
  					&& (Region.getClipping(x - 1, y, z) & 0x1280108) == 0
  					&& (Region.getClipping(x, y - 1, z) & 0x1280102) == 0) {
  				return true;
  			}
  		} else if (direction == 0) {
  			if ((Region.getClipping(x - 1, y + 1, z) & 0x1280138) == 0
  					&& (Region.getClipping(x - 1, y, z) & 0x1280108) == 0
  					&& (Region.getClipping(x, y + 1, z) & 0x1280120) == 0) {
  				return true;
  			}
  		} else if (direction == 7) {
  			if ((Region.getClipping(x + 1, y - 1, z) & 0x1280183) == 0
  					&& (Region.getClipping(x + 1, y, z) & 0x1280180) == 0
  					&& (Region.getClipping(x, y - 1, z) & 0x1280102) == 0) {
  				return true;
  			}
  		} else if (direction == 2) {
  			if ((Region.getClipping(x + 1, y + 1, z) & 0x12801e0) == 0
  					&& (Region.getClipping(x + 1, y, z) & 0x1280180) == 0
  					&& (Region.getClipping(x, y + 1, z) & 0x1280120) == 0) {
  				return true;
  			}
  		} else if (direction == -1) {
  			throw new IllegalArgumentException("Invalid direction: " + direction);
  		}
  
  		return false;
  	}
  
  	public static boolean canShoot(int x, int y, int z, int direction) {
  		if (direction == 0) {
  			return !projectileBlockedNorthWest(x, y, z) && !projectileBlockedNorth(x, y, z)
  					&& !projectileBlockedWest(x, y, z);
  		} else if (direction == 1) {
  			return !projectileBlockedNorth(x, y, z);
  		} else if (direction == 2) {
  			return !projectileBlockedNorthEast(x, y, z) && !projectileBlockedNorth(x, y, z)
  					&& !projectileBlockedEast(x, y, z);
  		} else if (direction == 3) {
  			return !projectileBlockedWest(x, y, z);
  		} else if (direction == 4) {
  			return !projectileBlockedEast(x, y, z);
  		} else if (direction == 5) {
  			return !projectileBlockedSouthWest(x, y, z) && !projectileBlockedSouth(x, y, z)
  					&& !projectileBlockedWest(x, y, z);
  		} else if (direction == 6) {
  			return !projectileBlockedSouth(x, y, z);
  		} else if (direction == 7) {
  			return !projectileBlockedSouthEast(x, y, z) && !projectileBlockedSouth(x, y, z)
  					&& !projectileBlockedEast(x, y, z);
  		}
  		return false;
  	}
  
  	public static boolean projectileBlockedNorth(int x, int y, int z) {
  		return (getProjectileClipping(x, y + 1, z) & 0x1280120) != 0;
  	}
  
  	public static boolean projectileBlockedEast(int x, int y, int z) {
  		return (getProjectileClipping(x + 1, y, z) & 0x1280180) != 0;
  	}
  
  	public static boolean projectileBlockedSouth(int x, int y, int z) {
  		return (getProjectileClipping(x, y - 1, z) & 0x1280102) != 0;
  	}
  
  	public static boolean projectileBlockedWest(int x, int y, int z) {
  		return (getProjectileClipping(x - 1, y, z) & 0x1280108) != 0;
  	}
  
  	public static boolean projectileBlockedNorthEast(int x, int y, int z) {
  		return (getProjectileClipping(x + 1, y + 1, z) & 0x12801e0) != 0;
  	}
  
  	public static boolean projectileBlockedNorthWest(int x, int y, int z) {
  		return (getProjectileClipping(x - 1, y + 1, z) & 0x1280138) != 0;
  	}
  
  	public static boolean projectileBlockedSouthEast(int x, int y, int z) {
  		return (getProjectileClipping(x + 1, y - 1, z) & 0x1280183) != 0;
  	}
  
  	public static boolean projectileBlockedSouthWest(int x, int y, int z) {
  		return (getProjectileClipping(x - 1, y - 1, z) & 0x128010e) != 0;
  	}
  
  	public static boolean canMove(int startX, int startY, int endX, int endY, int height, int xLength, int yLength) {
  		int diffX = endX - startX;
  		int diffY = endY - startY;
  		int max = Math.max(Math.abs(diffX), Math.abs(diffY));
  		for (int ii = 0; ii < max; ii++) {
  			int currentX = endX - diffX;
  			int currentY = endY - diffY;
  			for (int i = 0; i < xLength; i++) {
  				for (int i2 = 0; i2 < yLength; i2++)
  					if (diffX < 0 && diffY < 0) {
  						if ((getClipping((currentX + i) - 1,
  								(currentY + i2) - 1, height) & 0x128010e) != 0
  								|| (getClipping((currentX + i) - 1, currentY
  										+ i2, height) & 0x1280108) != 0
  								|| (getClipping(currentX + i,
  										(currentY + i2) - 1, height) & 0x1280102) != 0)
  							return false;
  					} else if (diffX > 0 && diffY > 0) {
  						if ((getClipping(currentX + i + 1, currentY + i2 + 1,
  								height) & 0x12801e0) != 0
  								|| (getClipping(currentX + i + 1,
  										currentY + i2, height) & 0x1280180) != 0
  								|| (getClipping(currentX + i,
  										currentY + i2 + 1, height) & 0x1280120) != 0)
  							return false;
  					} else if (diffX < 0 && diffY > 0) {
  						if ((getClipping((currentX + i) - 1, currentY + i2 + 1,
  								height) & 0x1280138) != 0
  								|| (getClipping((currentX + i) - 1, currentY
  										+ i2, height) & 0x1280108) != 0
  								|| (getClipping(currentX + i,
  										currentY + i2 + 1, height) & 0x1280120) != 0)
  							return false;
  					} else if (diffX > 0 && diffY < 0) {
  						if ((getClipping(currentX + i + 1, (currentY + i2) - 1,
  								height) & 0x1280183) != 0
  								|| (getClipping(currentX + i + 1,
  										currentY + i2, height) & 0x1280180) != 0
  								|| (getClipping(currentX + i,
  										(currentY + i2) - 1, height) & 0x1280102) != 0)
  							return false;
  					} else if (diffX > 0 && diffY == 0) {
  						if ((getClipping(currentX + i + 1, currentY + i2,
  								height) & 0x1280180) != 0)
  							return false;
  					} else if (diffX < 0 && diffY == 0) {
  						if ((getClipping((currentX + i) - 1, currentY + i2,
  								height) & 0x1280108) != 0)
  							return false;
  					} else if (diffX == 0 && diffY > 0) {
  						if ((getClipping(currentX + i, currentY + i2 + 1,
  								height) & 0x1280120) != 0)
  							return false;
  					} else if (diffX == 0
  							&& diffY < 0
  							&& (getClipping(currentX + i, (currentY + i2) - 1,
  									height) & 0x1280102) != 0)
  						return false;
  
  			}
  
  			if (diffX < 0)
  				diffX++;
  			else if (diffX > 0)
  				diffX--;
  			if (diffY < 0)
  				diffY++;
  			else if (diffY > 0)
  				diffY--;
  		}
  
  		return true;
  	}
  
  	private int getClip(int x, int y, int height) {
  		int regionAbsX = (id >> 8) * 64;
  		int regionAbsY = (id & 0xff) * 64;
  		if (clips[height] == null) {
  			return 0;
  		}
  		return clips[height][x - regionAbsX][y - regionAbsY];
  	}
  
  	private int getProjectileClip(int x, int y, int height) {
  		int regionAbsX = (id >> 8) * 64;
  		int regionAbsY = (id & 0xff) * 64;
  		if (projectileClips[height] == null) {
  			return 0;
  		}
  		return projectileClips[height][x - regionAbsX][y - regionAbsY];
  	}
  
  	/**
  	 * Adds clipping to whichever region matches provided XYZ.
  	 * 
  	 * @param x coordinate X
  	 * @param y coordinate Y
  	 * @param height coordinate Z
  	 * @param shift uuuuh shift?
  	 */
  	public static void addClipping(int x, int y, int height, int shift) {
  		for (Region r : RegionFactory.getRegions()) {
  			if (r.id() == getRegionId(x, y)) {
  				r.addClip(x, y, height, shift);
  				break;
  			}
  		}
  	}
  
  	private static void addProjectileClipping(int x, int y, int height, int shift) {
  		for (Region r : RegionFactory.getRegions()) {
  			if (r.id() == getRegionId(x,y)) {
  				r.addProjectileClip(x, y, height, shift);
  				break;
  			}
  		}
  	}
  
  	private static void addClippingForVariableObject(int x, int y, int height,
  			int type, int direction, boolean flag) {
  		if (type == 0) {
  			if (direction == 0) {
  				addClipping(x, y, height, 128);
  				addClipping(x - 1, y, height, 8);
  			} else if (direction == 1) {
  				addClipping(x, y, height, 2);
  				addClipping(x, y + 1, height, 32);
  			} else if (direction == 2) {
  				addClipping(x, y, height, 8);
  				addClipping(x + 1, y, height, 128);
  			} else if (direction == 3) {
  				addClipping(x, y, height, 32);
  				addClipping(x, y - 1, height, 2);
  			}
  		} else if (type == 1 || type == 3) {
  			if (direction == 0) {
  				addClipping(x, y, height, 1);
  				addClipping(x - 1, y, height, 16);
  			} else if (direction == 1) {
  				addClipping(x, y, height, 4);
  				addClipping(x + 1, y + 1, height, 64);
  			} else if (direction == 2) {
  				addClipping(x, y, height, 16);
  				addClipping(x + 1, y - 1, height, 1);
  			} else if (direction == 3) {
  				addClipping(x, y, height, 64);
  				addClipping(x - 1, y - 1, height, 4);
  			}
  		} else if (type == 2) {
  			if (direction == 0) {
  				addClipping(x, y, height, 130);
  				addClipping(x - 1, y, height, 8);
  				addClipping(x, y + 1, height, 32);
  			} else if (direction == 1) {
  				addClipping(x, y, height, 10);
  				addClipping(x, y + 1, height, 32);
  				addClipping(x + 1, y, height, 128);
  			} else if (direction == 2) {
  				addClipping(x, y, height, 40);
  				addClipping(x + 1, y, height, 128);
  				addClipping(x, y - 1, height, 2);
  			} else if (direction == 3) {
  				addClipping(x, y, height, 160);
  				addClipping(x, y - 1, height, 2);
  				addClipping(x - 1, y, height, 8);
  			}
  		}
  		if (flag) {
  			if (type == 0) {
  				if (direction == 0) {
  					addClipping(x, y, height, 65536);
  					addClipping(x - 1, y, height, 4096);
  				} else if (direction == 1) {
  					addClipping(x, y, height, 1024);
  					addClipping(x, y + 1, height, 16384);
  				} else if (direction == 2) {
  					addClipping(x, y, height, 4096);
  					addClipping(x + 1, y, height, 65536);
  				} else if (direction == 3) {
  					addClipping(x, y, height, 16384);
  					addClipping(x, y - 1, height, 1024);
  				}
  			}
  			if (type == 1 || type == 3) {
  				if (direction == 0) {
  					addClipping(x, y, height, 512);
  					addClipping(x - 1, y + 1, height, 8192);
  				} else if (direction == 1) {
  					addClipping(x, y, height, 2048);
  					addClipping(x + 1, y + 1, height, 32768);
  				} else if (direction == 2) {
  					addClipping(x, y, height, 8192);
  					addClipping(x + 1, y + 1, height, 512);
  				} else if (direction == 3) {
  					addClipping(x, y, height, 32768);
  					addClipping(x - 1, y - 1, height, 2048);
  				}
  			} else if (type == 2) {
  				if (direction == 0) {
  					addClipping(x, y, height, 66560);
  					addClipping(x - 1, y, height, 4096);
  					addClipping(x, y + 1, height, 16384);
  				} else if (direction == 1) {
  					addClipping(x, y, height, 5120);
  					addClipping(x, y + 1, height, 16384);
  					addClipping(x + 1, y, height, 65536);
  				} else if (direction == 2) {
  					addClipping(x, y, height, 20480);
  					addClipping(x + 1, y, height, 65536);
  					addClipping(x, y - 1, height, 1024);
  				} else if (direction == 3) {
  					addClipping(x, y, height, 81920);
  					addClipping(x, y - 1, height, 1024);
  					addClipping(x - 1, y, height, 4096);
  				}
  			}
  		}
  	}
  
  	private static void addProjectileClippingForVariableObject(int x, int y, int height,
  													 int type, int direction, boolean flag) {
  		if (type == 0) {
  			if (direction == 0) {
  				addProjectileClipping(x, y, height, 128);
  				addProjectileClipping(x - 1, y, height, 8);
  			} else if (direction == 1) {
  				addProjectileClipping(x, y, height, 2);
  				addProjectileClipping(x, y + 1, height, 32);
  			} else if (direction == 2) {
  				addProjectileClipping(x, y, height, 8);
  				addProjectileClipping(x + 1, y, height, 128);
  			} else if (direction == 3) {
  				addProjectileClipping(x, y, height, 32);
  				addProjectileClipping(x, y - 1, height, 2);
  			}
  		} else if (type == 1 || type == 3) {
  			if (direction == 0) {
  				addProjectileClipping(x, y, height, 1);
  				addProjectileClipping(x - 1, y, height, 16);
  			} else if (direction == 1) {
  				addProjectileClipping(x, y, height, 4);
  				addProjectileClipping(x + 1, y + 1, height, 64);
  			} else if (direction == 2) {
  				addProjectileClipping(x, y, height, 16);
  				addProjectileClipping(x + 1, y - 1, height, 1);
  			} else if (direction == 3) {
  				addProjectileClipping(x, y, height, 64);
  				addProjectileClipping(x - 1, y - 1, height, 4);
  			}
  		} else if (type == 2) {
  			if (direction == 0) {
  				addProjectileClipping(x, y, height, 130);
  				addProjectileClipping(x - 1, y, height, 8);
  				addProjectileClipping(x, y + 1, height, 32);
  			} else if (direction == 1) {
  				addProjectileClipping(x, y, height, 10);
  				addProjectileClipping(x, y + 1, height, 32);
  				addProjectileClipping(x + 1, y, height, 128);
  			} else if (direction == 2) {
  				addProjectileClipping(x, y, height, 40);
  				addProjectileClipping(x + 1, y, height, 128);
  				addProjectileClipping(x, y - 1, height, 2);
  			} else if (direction == 3) {
  				addProjectileClipping(x, y, height, 160);
  				addProjectileClipping(x, y - 1, height, 2);
  				addProjectileClipping(x - 1, y, height, 8);
  			}
  		}
  		if (flag) {
  			if (type == 0) {
  				if (direction == 0) {
  					addProjectileClipping(x, y, height, 65536);
  					addProjectileClipping(x - 1, y, height, 4096);
  				} else if (direction == 1) {
  					addProjectileClipping(x, y, height, 1024);
  					addProjectileClipping(x, y + 1, height, 16384);
  				} else if (direction == 2) {
  					addProjectileClipping(x, y, height, 4096);
  					addProjectileClipping(x + 1, y, height, 65536);
  				} else if (direction == 3) {
  					addProjectileClipping(x, y, height, 16384);
  					addProjectileClipping(x, y - 1, height, 1024);
  				}
  			}
  			if (type == 1 || type == 3) {
  				if (direction == 0) {
  					addProjectileClipping(x, y, height, 512);
  					addProjectileClipping(x - 1, y + 1, height, 8192);
  				} else if (direction == 1) {
  					addProjectileClipping(x, y, height, 2048);
  					addProjectileClipping(x + 1, y + 1, height, 32768);
  				} else if (direction == 2) {
  					addProjectileClipping(x, y, height, 8192);
  					addProjectileClipping(x + 1, y + 1, height, 512);
  				} else if (direction == 3) {
  					addProjectileClipping(x, y, height, 32768);
  					addProjectileClipping(x - 1, y - 1, height, 2048);
  				}
  			} else if (type == 2) {
  				if (direction == 0) {
  					addProjectileClipping(x, y, height, 66560);
  					addProjectileClipping(x - 1, y, height, 4096);
  					addProjectileClipping(x, y + 1, height, 16384);
  				} else if (direction == 1) {
  					addProjectileClipping(x, y, height, 5120);
  					addProjectileClipping(x, y + 1, height, 16384);
  					addProjectileClipping(x + 1, y, height, 65536);
  				} else if (direction == 2) {
  					addProjectileClipping(x, y, height, 20480);
  					addProjectileClipping(x + 1, y, height, 65536);
  					addProjectileClipping(x, y - 1, height, 1024);
  				} else if (direction == 3) {
  					addProjectileClipping(x, y, height, 81920);
  					addProjectileClipping(x, y - 1, height, 1024);
  					addProjectileClipping(x - 1, y, height, 4096);
  				}
  			}
  		}
  	}
  
  	private static void addClippingForSolidObject(int x, int y, int height,
  			int xLength, int yLength, boolean flag) {
  		int clipping = 256;
  		if (flag) {
  			clipping += 0x20000;
  		}
  		for (int i = x; i < x + xLength; i++) {
  			for (int i2 = y; i2 < y + yLength; i2++) {
  				addClipping(i, i2, height, clipping);
  			}
  		}
  	}
  
  	private static void addProjectileClippingForSolidObject(int x, int y, int height,
  												  int xLength, int yLength, boolean flag) {
  		int clipping = 256;
  		if (flag) {
  			clipping += 0x20000;
  		}
  		for (int i = x; i < x + xLength; i++) {
  			for (int i2 = y; i2 < y + yLength; i2++) {
  				addProjectileClipping(i, i2, height, clipping);
  			}
  		}
  	}
  
  	/**
  	 * 
  	 * Adds object to region
  	 * 
  	 * @param objectId
  	 * @param x
  	 * @param y
  	 * @param height
  	 * @param type
  	 * @param direction
  	 * @param startUp
  	 */
  	public static void addObject(int objectId, int x, int y, int height, int type, int direction, boolean startUp) {
  		if (ObjectDefinition.lookup(objectId) == null) {
  		}
  		int xLength;
  		int yLength;
  		if (direction != 1 && direction != 3) {
  			xLength = ObjectDefinition.lookup(objectId).getWidth();
  			yLength = ObjectDefinition.lookup(objectId).getLength();
  		} else {
  			xLength = ObjectDefinition.lookup(objectId).getLength();
  			yLength = ObjectDefinition.lookup(objectId).getWidth();
  		}
  		if (type == 22) {
  			if (ObjectDefinition.lookup(objectId).isInteractive()
  					&& ObjectDefinition.lookup(objectId).isSolid()) {
  				addClipping(x, y, height, 0x200000);
  				if (ObjectDefinition.lookup(objectId).isImpenetrable()) {
  					addProjectileClipping(x, y, height, 0x200000);
  				}
  			}
  		} else if (type >= 9) {
  			if (ObjectDefinition.lookup(objectId).isSolid()) {
  				addClippingForSolidObject(x, y, height, xLength, yLength,
  						ObjectDefinition.lookup(objectId).isClipped());
  				if (ObjectDefinition.lookup(objectId).isImpenetrable()) {
  					addProjectileClippingForSolidObject(x, y, height, xLength, yLength,
  							ObjectDefinition.lookup(objectId).isClipped());
  				}
  			}
  		} else if (type >= 0 && type <= 3) {
  			if (ObjectDefinition.lookup(objectId).isSolid()) {
  				addClippingForVariableObject(x, y, height, type, direction,
  						ObjectDefinition.lookup(objectId).isClipped());
  				if (ObjectDefinition.lookup(objectId).isImpenetrable()) {
  					addProjectileClippingForVariableObject(x, y, height, type, direction, ObjectDefinition.lookup(objectId).isClipped());
  				}
  			}
  		}
  		Region r = getRegion(x, y);
  		if (r != null) {
  		    if (startUp)
  		        r.realObjects.add(new Objects(objectId, x, y, height, direction, type, 0));
  		    else if (!objectExists(objectId, x, y, height))
  		        r.realObjects.add(new Objects(objectId, x, y, height, direction, type, 0));
  		}
  	}
  
  	public static int getClipping(int x, int y, int height) {
  		if (height > 3) {
  			height = 0; //this doesn't seem good
  		}
  		for (Region r : RegionFactory.getRegions()) {
  			if (r.id() == getRegionId(x,y)) {
  				return r.getClip(x, y, height);
  			}
  		}
  		return 0;
  	}
  
  	public static int getProjectileClipping(int x, int y, int height) {
  		if (height > 3) {
  			height = 0;
  		}
  		for (Region r : RegionFactory.getRegions()) {
  			if (r.id() == getRegionId(x,y)) {
  				return r.getProjectileClip(x, y, height);
  			}
  		}
  		return 0;
  	}
  
  	public static boolean getClipping(int x, int y, int height, int moveTypeX,
  			int moveTypeY) {
  		try {
  			if (height > 3) {
  				height = 0;
  			}
  			int checkX = x + moveTypeX;
  			int checkY = y + moveTypeY;
  			if (moveTypeX == -1 && moveTypeY == 0) {
  				return (getClipping(x, y, height) & 0x1280108) == 0;
  			} else if (moveTypeX == 1 && moveTypeY == 0) {
  				return (getClipping(x, y, height) & 0x1280180) == 0;
  			} else if (moveTypeX == 0 && moveTypeY == -1) {
  				return (getClipping(x, y, height) & 0x1280102) == 0;
  			} else if (moveTypeX == 0 && moveTypeY == 1) {
  				return (getClipping(x, y, height) & 0x1280120) == 0;
  			} else if (moveTypeX == -1 && moveTypeY == -1) {
  				return (getClipping(x, y, height) & 0x128010e) == 0
  						&& (getClipping(checkX - 1, checkY, height) & 0x1280108) == 0
  						&& (getClipping(checkX - 1, checkY, height) & 0x1280102) == 0;
  			} else if (moveTypeX == 1 && moveTypeY == -1) {
  				return (getClipping(x, y, height) & 0x1280183) == 0
  						&& (getClipping(checkX + 1, checkY, height) & 0x1280180) == 0
  						&& (getClipping(checkX, checkY - 1, height) & 0x1280102) == 0;
  			} else if (moveTypeX == -1 && moveTypeY == 1) {
  				return (getClipping(x, y, height) & 0x1280138) == 0
  						&& (getClipping(checkX - 1, checkY, height) & 0x1280108) == 0
  						&& (getClipping(checkX, checkY + 1, height) & 0x1280120) == 0;
  			} else if (moveTypeX == 1 && moveTypeY == 1) {
  				return (getClipping(x, y, height) & 0x12801e0) == 0
  						&& (getClipping(checkX + 1, checkY, height) & 0x1280180) == 0
  						&& (getClipping(checkX, checkY + 1, height) & 0x1280120) == 0;
  			} else {
  				System.out.println("[FATAL ERROR]: At getClipping: " + x + ", "
  						+ y + ", " + height + ", " + moveTypeX + ", "
  						+ moveTypeY);
  				return false;
  			}
  		} catch (Exception e) {
  			return true;
  		}
  	}
  
  }
  