mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Optimise GameObjectDecoder for faster start-up time.
This commit is contained in:
@@ -14,6 +14,7 @@ import org.apollo.cache.decoder.MapFileDecoder;
|
||||
import org.apollo.cache.decoder.MapFileDecoder.MapDefinition;
|
||||
import org.apollo.cache.decoder.ObjectDefinitionDecoder;
|
||||
import org.apollo.cache.def.ObjectDefinition;
|
||||
import org.apollo.game.io.player.PlayerSerializer;
|
||||
import org.apollo.game.model.Position;
|
||||
import org.apollo.game.model.World;
|
||||
import org.apollo.game.model.area.Region;
|
||||
@@ -65,6 +66,11 @@ public final class GameObjectDecoder implements Runnable {
|
||||
*/
|
||||
private final World world;
|
||||
|
||||
/**
|
||||
* The most-recently used Region.
|
||||
*/
|
||||
private Region previous;
|
||||
|
||||
/**
|
||||
* Creates the GameObjectDecoder.
|
||||
*
|
||||
@@ -75,6 +81,7 @@ public final class GameObjectDecoder implements Runnable {
|
||||
this.fs = fs;
|
||||
this.world = world;
|
||||
regions = world.getRegionRepository();
|
||||
previous = regions.fromPosition(PlayerSerializer.TUTORIAL_ISLAND_SPAWN); // dummy, so 'previous' is never null.
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,9 +92,7 @@ public final class GameObjectDecoder implements Runnable {
|
||||
try {
|
||||
Map<Integer, MapDefinition> definitions = MapFileDecoder.decode(fs);
|
||||
|
||||
for (Entry<Integer, MapDefinition> entry : definitions.entrySet()) {
|
||||
MapDefinition definition = entry.getValue();
|
||||
|
||||
for (MapDefinition definition : definitions.values()) {
|
||||
int packed = definition.getPackedCoordinates();
|
||||
int x = (packed >> 8 & 0xFF) * 64;
|
||||
int y = (packed & 0xFF) * 64;
|
||||
@@ -117,10 +122,13 @@ public final class GameObjectDecoder implements Runnable {
|
||||
ObjectDefinition definition = ObjectDefinition.lookup(object.getId());
|
||||
int type = object.getType();
|
||||
|
||||
Region region = regions.fromPosition(position);
|
||||
int x = position.getX(), y = position.getY(), height = position.getHeight();
|
||||
|
||||
CollisionMatrix matrix = region.getMatrix(height);
|
||||
if (!previous.contains(position)) {
|
||||
previous = regions.fromPosition(position);
|
||||
}
|
||||
|
||||
CollisionMatrix matrix = previous.getMatrix(height);
|
||||
boolean block = false;
|
||||
|
||||
if (type == ObjectType.FLOOR_DECORATION.getValue() && definition.isInteractive()) {
|
||||
@@ -140,18 +148,19 @@ public final class GameObjectDecoder implements Runnable {
|
||||
}
|
||||
|
||||
if (block) {
|
||||
for (int dx = 0; dx < definition.getWidth(); dx++) {
|
||||
for (int dy = 0; dy < definition.getLength(); dy++) {
|
||||
int width = definition.getWidth(), length = definition.getLength();
|
||||
|
||||
for (int dx = 0; dx < width; dx++) {
|
||||
for (int dy = 0; dy < length; dy++) {
|
||||
int localX = x % Region.SIZE + dx, localY = y % Region.SIZE + dy;
|
||||
|
||||
if (localX > 7 || localY > 7) {
|
||||
int nextLocalX = localX > 7 ? x + localX - 7 : x + localX;
|
||||
int nextLocalY = localY > 7 ? y + localY - 7 : y - localY;
|
||||
Position nextPosition = new Position(nextLocalX, nextLocalY);
|
||||
Region next = regions.fromPosition(nextPosition);
|
||||
Region next = regions.fromPosition(new Position(nextLocalX, nextLocalY));
|
||||
|
||||
int nextX = nextPosition.getX() % Region.SIZE + dx;
|
||||
int nextY = nextPosition.getY() % Region.SIZE + dy;
|
||||
int nextX = nextLocalX % Region.SIZE + dx;
|
||||
int nextY = nextLocalY % Region.SIZE + dy;
|
||||
|
||||
if (nextX > 7) {
|
||||
nextX -= 7;
|
||||
@@ -175,12 +184,11 @@ public final class GameObjectDecoder implements Runnable {
|
||||
* Decodes the attributes of a terrain file, blocking the tile if necessary.
|
||||
*
|
||||
* @param attributes The terrain attributes.
|
||||
* @param position The {@link Position} of the tile whose attributes are being decoded.
|
||||
* @param x The x coordinate of the tile the attributes belong to.
|
||||
* @param y The y coordinate of the tile the attributes belong to.
|
||||
* @param height The level level of the tile the attributes belong to.
|
||||
*/
|
||||
private void decodeAttributes(int attributes, Position position) {
|
||||
Region region = regions.fromPosition(position);
|
||||
int x = position.getX(), y = position.getY(), height = position.getHeight();
|
||||
|
||||
private void decodeAttributes(int attributes, int x, int y, int height) {
|
||||
boolean block = false;
|
||||
if ((attributes & BLOCKED_TILE) != 0) {
|
||||
block = true;
|
||||
@@ -195,7 +203,13 @@ public final class GameObjectDecoder implements Runnable {
|
||||
|
||||
if (block) {
|
||||
int localX = x % Region.SIZE, localY = y % Region.SIZE;
|
||||
region.getMatrix(height).block(localX, localY);
|
||||
Position position = new Position(x, y, height);
|
||||
|
||||
if (!previous.contains(position)) {
|
||||
previous = regions.fromPosition(new Position(x, y, height));
|
||||
}
|
||||
|
||||
previous.getMatrix(height).block(localX, localY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,21 +262,18 @@ public final class GameObjectDecoder implements Runnable {
|
||||
* @param y The y coordinate of the top left tile of the map file.
|
||||
*/
|
||||
private void decodeTerrain(ByteBuffer buffer, int x, int y) {
|
||||
for (int height = 0; height < 4; height++) {
|
||||
for (int localX = 0; localX < 64; localX++) {
|
||||
for (int localY = 0; localY < 64; localY++) {
|
||||
Position position = new Position(x + localX, y + localY, height);
|
||||
|
||||
for (int height = 0; height < Position.HEIGHT_LEVELS; height++) {
|
||||
for (int localX = 0; localX < Region.SIZE * Region.SIZE; localX++) {
|
||||
for (int localY = 0; localY < Region.SIZE * Region.SIZE; localY++) {
|
||||
int attributes = 0;
|
||||
|
||||
while (true) {
|
||||
int attributeId = buffer.get() & 0xFF;
|
||||
|
||||
if (attributeId == 0) {
|
||||
decodeAttributes(attributes, position);
|
||||
break;
|
||||
} else if (attributeId == 1) {
|
||||
if (attributeId == 1) {
|
||||
buffer.get();
|
||||
decodeAttributes(attributes, position);
|
||||
} else if (attributeId == 0) {
|
||||
decodeAttributes(attributes, x + localX, y + localY, height);
|
||||
break;
|
||||
} else if (attributeId <= 49) {
|
||||
buffer.get();
|
||||
|
||||
@@ -17,7 +17,7 @@ public abstract class PlayerSerializer {
|
||||
/**
|
||||
* The spawn point for Players, on Tutorial Island.
|
||||
*/
|
||||
protected static final Position TUTORIAL_ISLAND_SPAWN = new Position(3093, 3104);
|
||||
public static final Position TUTORIAL_ISLAND_SPAWN = new Position(3093, 3104);
|
||||
|
||||
/**
|
||||
* The World this PlayerSerializer is for.
|
||||
|
||||
@@ -163,6 +163,16 @@ public final class Region {
|
||||
return local != null && local.contains(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the specified {@link Position} is inside this Region.
|
||||
*
|
||||
* @param position The Position.
|
||||
* @return {@code true} iff the specified Position is inside this Region.
|
||||
*/
|
||||
public boolean contains(Position position) {
|
||||
return coordinates.equals(position.getRegionCoordinates());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the contents of this Region into a {@link Set} of {@link RegionUpdateMessage}s, to be sent to a client.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user