Merge pull request #152 from ryleykimmel/issue150

Add Region#getEntities and Region#getSurrounding for issue #150
This commit is contained in:
Gary Tierney
2016-02-03 21:37:18 +00:00
2 changed files with 55 additions and 39 deletions
@@ -1,13 +1,14 @@
package org.apollo.game.model.area;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apollo.game.message.impl.RegionUpdateMessage;
import org.apollo.game.model.Direction;
@@ -17,11 +18,11 @@ import org.apollo.game.model.area.update.GroupableEntity;
import org.apollo.game.model.area.update.UpdateOperation;
import org.apollo.game.model.entity.Entity;
import org.apollo.game.model.entity.EntityType;
import org.apollo.game.model.entity.obj.DynamicGameObject;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import org.apollo.game.model.entity.obj.DynamicGameObject;
/**
* An 8x8 area of the map.
@@ -52,6 +53,16 @@ public final class Region {
*/
public static final int SIZE = 8;
/**
* The radius of viewable regions.
*/
public static final int VIEWABLE_REGION_RADIUS = 3;
/**
* The width of the viewport of every Player, in tiles.
*/
public static final int VIEWPORT_WIDTH = SIZE * 13;
/**
* The default size of newly-created Lists, to reduce memory usage.
*/
@@ -199,6 +210,22 @@ public final class Region {
return coordinates;
}
/**
* Gets an intermediate {@link Stream} from the {@link Set} of
* {@link Entity}s with the specified {@link EntityType} (s). Type will be
* inferred from the call, so ensure that the Entity type and the reference
* correspond, or this method will fail at runtime.
*
* @param types The {@link EntityType}s.
* @return The Stream of Entity objects.
*/
@SuppressWarnings("unchecked")
public <T extends Entity> Stream<T> getEntities(EntityType... types) {
Set<EntityType> set = ImmutableSet.copyOf(types);
return (Stream<T>) entities.values().stream().flatMap(Collection::stream)
.filter(entity -> set.contains(entity.getEntityType()));
}
/**
* Gets a shallow copy of the {@link Set} of {@link Entity} objects at the specified {@link Position}. The returned
* type will be immutable.
@@ -226,13 +253,33 @@ public final class Region {
return ImmutableSet.of();
}
Set<EntityType> set = new HashSet<>(Arrays.asList(types));
Set<EntityType> set = ImmutableSet.copyOf(types);
@SuppressWarnings("unchecked")
Set<T> filtered = (Set<T>) local.stream().filter(entity -> set.contains(entity.getEntityType()))
.collect(Collectors.toSet());
return ImmutableSet.copyOf(filtered);
}
/**
* Gets the {@link Set} of {@link RegionCoordinates} of Regions that are
* viewable from the specified {@link Position}.
*
* @return The Set of RegionCoordinates.
*/
public Set<RegionCoordinates> getSurrounding() {
int localX = coordinates.getX(), localY = coordinates.getY();
int maxX = localX + VIEWABLE_REGION_RADIUS, maxY = localY + VIEWABLE_REGION_RADIUS;
Set<RegionCoordinates> viewable = new HashSet<>();
for (int x = localX - VIEWABLE_REGION_RADIUS; x < maxX; x++) {
for (int y = localY - VIEWABLE_REGION_RADIUS; y < maxY; y++) {
viewable.add(new RegionCoordinates(x, y));
}
}
return viewable;
}
/**
* Gets the {@link CollisionMatrix} at the specified height level.
*
@@ -2,7 +2,6 @@ package org.apollo.game.sync.task;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apollo.game.message.impl.ClearRegionMessage;
@@ -23,16 +22,6 @@ import org.apollo.game.model.entity.Player;
*/
public final class PrePlayerSynchronizationTask extends SynchronizationTask {
/**
* The radius of viewable regions.
*/
private static final int VIEWABLE_REGION_RADIUS = 3;
/**
* The width of the viewport of every Player, in tiles.
*/
private static final int VIEWPORT_WIDTH = Region.SIZE * 13;
/**
* The Map of RegionCoordinates to Sets of RegionUpdateMessages, which contain all of the Entity information for a
* Region.
@@ -81,7 +70,9 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask {
player.send(new RegionChangeMessage(position));
}
Set<RegionCoordinates> oldViewable = getViewableRegions(old), newViewable = getViewableRegions(position);
RegionRepository repository = player.getWorld().getRegionRepository();
Set<RegionCoordinates> oldViewable = repository.fromPosition(old).getSurrounding();
Set<RegionCoordinates> newViewable = repository.fromPosition(position).getSurrounding();
Set<RegionCoordinates> differences = new HashSet<>(newViewable);
differences.retainAll(oldViewable);
@@ -92,28 +83,6 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask {
sendUpdates(player.getLastKnownRegion(), differences, full);
}
/**
* Gets the {@link Set} of {@link RegionCoordinates} of Regions that are viewable from the specified {@link
* Position}.
*
* @param position The Position.
* @return The Set of RegionCoordinates.
*/
private Set<RegionCoordinates> getViewableRegions(Position position) { // TODO possibly more complicated than this
RegionCoordinates local = position.getRegionCoordinates();
int localX = local.getX(), localY = local.getY();
int maxX = localX + VIEWABLE_REGION_RADIUS, maxY = localY + VIEWABLE_REGION_RADIUS;
Set<RegionCoordinates> viewable = new HashSet<>();
for (int x = localX - VIEWABLE_REGION_RADIUS; x < maxX; x++) {
for (int y = localY - VIEWABLE_REGION_RADIUS; y < maxY; y++) {
viewable.add(new RegionCoordinates(x, y));
}
}
return viewable;
}
/**
* Checks if a region update is required.
*
@@ -126,8 +95,8 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask {
int deltaX = current.getLocalX(last);
int deltaY = current.getLocalY(last);
return deltaX <= Position.MAX_DISTANCE || deltaX >= VIEWPORT_WIDTH - Position.MAX_DISTANCE - 1
|| deltaY <= Position.MAX_DISTANCE || deltaY >= VIEWPORT_WIDTH - Position.MAX_DISTANCE - 1;
return deltaX <= Position.MAX_DISTANCE || deltaX >= Region.VIEWPORT_WIDTH - Position.MAX_DISTANCE - 1
|| deltaY <= Position.MAX_DISTANCE || deltaY >= Region.VIEWPORT_WIDTH - Position.MAX_DISTANCE - 1;
}
/**