diff --git a/game/src/main/org/apollo/game/model/area/Region.java b/game/src/main/org/apollo/game/model/area/Region.java index d9095c04..49f0df8c 100644 --- a/game/src/main/org/apollo/game/model/area/Region.java +++ b/game/src/main/org/apollo/game/model/area/Region.java @@ -21,6 +21,7 @@ import org.apollo.game.model.entity.EntityType; 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. @@ -169,7 +170,8 @@ public final class Region { */ public Set encode(int height) { Set additions = entities.values().stream() - .flatMap(Set::stream).filter(entity -> entity instanceof GroupableEntity) + .flatMap(Set::stream) // TODO fix this to work for ground items + projectiles + .filter(entity -> entity instanceof DynamicGameObject && entity.getPosition().getHeight() == height) .map(entity -> ((GroupableEntity) entity).toUpdateOperation(this, EntityUpdateType.ADD).toMessage()) .collect(Collectors.toSet()); @@ -241,7 +243,11 @@ public final class Region { * @return The Set of RegionUpdateMessages. */ public Set getUpdates(int height) { - return ImmutableSet.copyOf(updates.get(height)); + Set updates = this.updates.get(height); + Set copy = ImmutableSet.copyOf(updates); + + updates.clear(); + return copy; } /** @@ -309,20 +315,26 @@ public final class Region { * Records the specified {@link GroupableEntity} as being updated this pulse. * * @param entity The GroupableEntity. - * @param type The {@link EntityUpdateType}. + * @param update The {@link EntityUpdateType}. * @throws UnsupportedOperationException If the specified Entity cannot be operated on in this manner. */ - private void record(T entity, EntityUpdateType type) { - UpdateOperation operation = entity.toUpdateOperation(this, type); + private void record(T entity, EntityUpdateType update) { + UpdateOperation operation = entity.toUpdateOperation(this, update); RegionUpdateMessage message = operation.toMessage(), inverse = operation.inverse(); int height = entity.getPosition().getHeight(); Set updates = this.updates.get(height); - if (entity.getEntityType() == EntityType.STATIC_OBJECT && type == EntityUpdateType.REMOVE) { - removedObjects.get(height).add(message); + EntityType type = entity.getEntityType(); + + if (type == EntityType.STATIC_OBJECT) { + if (update == EntityUpdateType.REMOVE) { + removedObjects.get(height).add(message); + } else { // TODO should this really be possible? + removedObjects.get(height).remove(inverse); + } + updates.add(message); - updates.remove(inverse); } else { updates.add(message); updates.remove(inverse); diff --git a/game/src/main/org/apollo/game/sync/task/PrePlayerSynchronizationTask.java b/game/src/main/org/apollo/game/sync/task/PrePlayerSynchronizationTask.java index 0770115d..889319d8 100644 --- a/game/src/main/org/apollo/game/sync/task/PrePlayerSynchronizationTask.java +++ b/game/src/main/org/apollo/game/sync/task/PrePlayerSynchronizationTask.java @@ -2,6 +2,7 @@ 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; @@ -140,20 +141,24 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask { RegionRepository repository = player.getWorld().getRegionRepository(); int height = position.getHeight(); - differences.stream().map(coordinates -> { + for (RegionCoordinates coordinates : differences) { Set messages = updates.computeIfAbsent(coordinates, coords -> repository.get(coords).getUpdates(height)); - return new GroupedRegionUpdateMessage(position, coordinates, messages); - }).forEach(player::send); + if (!messages.isEmpty()) { + player.send(new GroupedRegionUpdateMessage(position, coordinates, messages)); + } + } - full.stream().map(coordinates -> { + for (RegionCoordinates coordinates : full) { Set messages = encodes.computeIfAbsent(coordinates, coords -> repository.get(coords).encode(height)); - player.send(new ClearRegionMessage(position, coordinates)); - return new GroupedRegionUpdateMessage(position, coordinates, messages); - }).forEach(player::send); + if (!messages.isEmpty()) { + player.send(new ClearRegionMessage(position, coordinates)); + player.send(new GroupedRegionUpdateMessage(position, coordinates, messages)); + } + } } } \ No newline at end of file