59 private static final int CHUNK_SIZE = 8;
60 public static final int SIZE = CHUNK_SIZE * 8;
61 public static final int VIEW_DISTANCE = SIZE / 4 - 1;
62 public static final Map<Position, GameObject> ACTIVE_OBJECT =
new HashMap<>();
63 public static final Set<Position> SKIPPED_OBJECTS =
new HashSet<>();
75 private Optional<Region[]> surroundingRegions = Optional.empty();
81 this.id = ((x >> 6) << 8) + (y >> 6);
104 return getBlock(height).getFlags(x, y);
116 public void setFlags(
int height,
int x,
int y,
int flags) {
117 getBlock(height).setFlags(x, y, flags);
129 public void unsetFlags(
int height,
int x,
int y,
int flags) {
130 getBlock(height).unsetFlags(x, y, flags);
133 public Optional<Region[]> getSurroundingRegions() {
134 return surroundingRegions;
137 public void setSurroundingRegions(Optional<
Region[]> surroundingRegions) {
138 this.surroundingRegions = surroundingRegions;
143 return getBlock(height).getPlayers();
148 return getBlock(height).getNpcs();
153 return getBlock(position.getHeight()).getGroundItem(
id, position);
158 getBlock(player.
getHeight()).addPlayer(player);
163 getBlock(player.
getHeight()).removePlayer(player);
173 getBlock(npc.
getHeight()).removeNpc(npc);
178 getBlock(
object.getHeight()).addObject(
object);
183 getBlock(
object.getHeight()).removeObject(
object);
188 getBlock(item.
getHeight()).addGroundItem(item);
193 getBlock(item.
getHeight()).removeGroundItem(item);
196 public boolean containsNpc(
int height,
Npc npc) {
197 return getBlock(height).containsNpc(npc);
200 public boolean containsPlayer(
int height,
Player player) {
201 return getBlock(height).containsPlayer(player);
206 return getBlock(height).containsObject(
object);
211 return getBlock(position.getHeight()).containsObject(position);
216 return getBlock(position.getHeight()).getGroundItems(position);
221 return getBlock(position.getHeight()).getGameObject(
id, position);
225 return getBlock(position.getHeight()).getCustomObject(
id, position);
228 public List<GameObject> getObjects(
Position position) {
229 return getBlock(position.getHeight()).getGameObjects(position);
234 getBlock(player.
getHeight()).sendGroundItems(player);
239 getBlock(player.
getHeight()).sendGameObjects(player);
244 return getX() == position.getRegionX() &&
getY() == position.getRegionY();
249 return getX() == ((x >> 3) - 6) >> 3 &&
getY() == ((y >> 3) - 6) >> 3;
253 if (height > HEIGHT_LEVELS || height < 0) {
254 throw new IllegalArgumentException(
"Height is out of bounds. Received (" + height +
"), expected range [0, " + HEIGHT_LEVELS +
"].");
257 if (blocks[height] ==
null) {
258 blocks[height] =
new RegionBlock();
261 return blocks[height];
264 public static boolean reachable(Interactable source, Interactable target) {
265 return reachable(source.getPosition(), source.width(), source.length(), target.getPosition(), target.width(), target.length());
268 public static boolean reachable(Position source,
int sourceWidth,
int sourceLength, Position target,
int targetWidth,
int targetLength) {
269 if (Utility.inside(source, sourceWidth, sourceLength, target, targetWidth, targetLength)) {
270 return targetWidth == 0 || targetLength == 0;
274 int sourceTopX = source.getX() + sourceWidth - 1;
275 int sourceTopY = source.getY() + sourceLength - 1;
276 int targetTopX = target.getX() + targetWidth - 1;
277 int targetTopY = target.getY() + targetLength - 1;
279 if (sourceTopY == target.getY() - 1 && source.getX() >= target.getX() && source.getX() <= targetTopX) {
280 for (x = 0, y = sourceLength - 1; x < sourceWidth; x++)
281 if (TraversalMap.blockedNorth(source.transform(x, y)))
286 if (sourceTopX == target.getX() - 1 && source.getY() >= target.getY() && source.getY() <= targetTopY) {
287 for (x = 0, y = 0; y < sourceLength; y++)
288 if (TraversalMap.blockedEast(source.transform(x, y)))
293 if (source.getY() == targetTopY + 1 && source.getX() >= target.getX() && source.getX() <= targetTopX) {
294 for (x = 0, y = 0; x < sourceWidth; x++)
295 if (TraversalMap.blockedSouth(source.transform(x, y)))
300 if (source.getX() == targetTopX + 1 && source.getY() >= target.getY() && source.getY() <= targetTopY) {
301 for (x = sourceWidth - 1, y = 0; y < sourceLength; y++)
302 if (TraversalMap.blockedWest(source.transform(x, y)))
310 public void skip(GameObject gameObject) {
311 getBlock(gameObject.getHeight()).skip(gameObject);
315 public String toString() {
316 return "Region[" + x +
"_" + y +
"]";