diff --git a/src/org/apollo/fs/decoder/GameObjectDecoder.java b/src/org/apollo/fs/decoder/GameObjectDecoder.java index b37485e9..59bb743e 100644 --- a/src/org/apollo/fs/decoder/GameObjectDecoder.java +++ b/src/org/apollo/fs/decoder/GameObjectDecoder.java @@ -37,12 +37,12 @@ public final class GameObjectDecoder { /** * A bit flag which denotes that a specified Position is a bridge. */ - private static final int FLAG_BRIDGE = 1; + private static final int FLAG_BRIDGE = 2; /** * The sector repository. */ - private static final SectorRepository sectors = World.getWorld().getSectorRepository(); + private static final SectorRepository REPOSITORY = World.getWorld().getSectorRepository(); /** * The {@link IndexedFileSystem}. @@ -70,14 +70,14 @@ public final class GameObjectDecoder { * @throws IOException If an I/O error occurs. */ public GameObject[] decode() throws IOException { - Map definitions = MapFileDecoder.parse(fs); + Map definitions = MapFileDecoder.decode(fs); for (Entry entry : definitions.entrySet()) { MapDefinition def = entry.getValue(); - int hash = def.getHash(); - int x = (hash >> 8 & 0xFF) * 64; - int y = (hash & 0xFF) * 64; + int packed = def.getPacketCoordinates(); + int x = (packed >> 8 & 0xFF) * 64; + int y = (packed & 0xFF) * 64; ByteBuffer gameObjectData = fs.getFile(4, def.getObjectFile()); ByteBuffer gameObjectBuffer = ByteBuffer.wrap(CompressionUtil.degzip(gameObjectData)); @@ -95,12 +95,12 @@ public final class GameObjectDecoder { for (int deltaId, id = -1; (deltaId = BufferUtil.readSmart(buffer)) != 0;) { id += deltaId; - for (int deltaPos, hash = 0; (deltaPos = BufferUtil.readSmart(buffer)) != 0;) { - hash += deltaPos - 1; + for (int deltaPos, pos = 0; (deltaPos = BufferUtil.readSmart(buffer)) != 0;) { + pos += deltaPos - 1; - int localX = hash >> 6 & 0x3F; - int localY = hash & 0x3F; - int height = hash >> 12 & 0x3; + int localY = pos & 0x3F; + int localX = pos >> 6 & 0x3F; + int height = pos >> 12; int attributes = buffer.get() & 0xFF; int type = attributes >> 2; @@ -115,8 +115,11 @@ public final class GameObjectDecoder { private void gameObjectDecoded(int id, int orientation, int type, Position position) { ObjectDefinition definition = ObjectDefinition.lookup(id); - Sector sector = sectors.fromPosition(position); - int x = position.getLocalX(), y = position.getLocalY(), height = position.getHeight(); + Sector sector = REPOSITORY.fromPosition(position); + int x = position.getX(), y = position.getY(), height = position.getHeight(); + + if (height < 0) + return; CollisionMatrix matrix = sector.getMatrix(height); @@ -143,10 +146,20 @@ public final class GameObjectDecoder { if (block) { for (int width = 0; width < definition.getWidth(); width++) { for (int length = 0; length < definition.getLength(); length++) { - matrix.block(x + width, y + length); + int localX = (x % Sector.SECTOR_SIZE) + width, localY = (y % Sector.SECTOR_SIZE) + length; + + if (localX > 7 || localY > 7) { + Sector next = REPOSITORY.fromPosition(new Position(x + localX - 7, y + localY - 7)); + next.getMatrix(height).block(localX, localY); + continue; + } + + matrix.block(localX, localY); } } } + + objects.add(new GameObject(id, position, type, orientation)); } private void parseTerrain(ByteBuffer buffer, int x, int y) { @@ -156,7 +169,7 @@ public final class GameObjectDecoder { Position position = new Position(x + localX, y + localY, height); int flags = 0; - for (;;) { + while (true) { int attributeId = buffer.get() & 0xFF; if (attributeId == 0) { terrainDecoded(flags, position); @@ -177,15 +190,34 @@ public final class GameObjectDecoder { } private void terrainDecoded(int flags, Position position) { - Sector sector = sectors.fromPosition(position); - int x = position.getLocalX(), y = position.getLocalY(), height = position.getHeight(); + Sector sector = REPOSITORY.fromPosition(position); + int x = position.getX(), y = position.getY(), height = position.getHeight(); + if (height < 0) + return; + CollisionMatrix current = sector.getMatrix(height); + + boolean block = false; if ((flags & FLAG_BLOCKED) != 0) { - sector.getMatrix(height).block(x, y); + block = true; } if ((flags & FLAG_BRIDGE) != 0) { - // FIXME + if (--height >= 0) { + block = true; + } + } + + if (block) { + int localX = (x % Sector.SECTOR_SIZE), localY = (y % Sector.SECTOR_SIZE); + + if (localX > 7 || localY > 7) { + Sector next = REPOSITORY.fromPosition(new Position(x + localX - 7, y + localY - 7)); + next.getMatrix(height).block(localX, localY); + return; + } + + current.block(localX, localY); } } diff --git a/src/org/apollo/fs/decoder/MapFileDecoder.java b/src/org/apollo/fs/decoder/MapFileDecoder.java index 28a2498f..ee78724e 100644 --- a/src/org/apollo/fs/decoder/MapFileDecoder.java +++ b/src/org/apollo/fs/decoder/MapFileDecoder.java @@ -10,20 +10,20 @@ import org.apollo.fs.archive.Archive; import org.apollo.fs.archive.ArchiveEntry; /** - * Parses {@link MapDefinition map definitions} from the {@link IndexedFileSystem}. + * Decodes {@link MapDefinition map definitions} from the {@link IndexedFileSystem}. * * @author Ryley */ public final class MapFileDecoder { /** - * Parses {@link MapDefinition}s from the specified {@link IndexedFileSystem}. + * Decodes {@link MapDefinition}s from the specified {@link IndexedFileSystem}. * * @param fs The file system. * @return A {@link Map} of parsed map definitions. * @throws IOException If some I/O error occurs. */ - protected static Map parse(IndexedFileSystem fs) throws IOException { + protected static Map decode(IndexedFileSystem fs) throws IOException { Archive archive = Archive.decode(fs.getFile(0, 5)); ArchiveEntry entry = archive.getEntry("map_index"); ByteBuffer buffer = entry.getBuffer(); @@ -31,12 +31,12 @@ public final class MapFileDecoder { int count = buffer.capacity() / 7; for (int i = 0; i < count; i++) { - int hash = buffer.getShort() & 0xFFFF; + int packedCoordinates = buffer.getShort() & 0xFFFF; int terrainFile = buffer.getShort() & 0xFFFF; int objectFile = buffer.getShort() & 0xFFFF; boolean preload = buffer.get() == 1; - defs.put(hash, new MapDefinition(hash, terrainFile, objectFile, preload)); + defs.put(packedCoordinates, new MapDefinition(packedCoordinates, terrainFile, objectFile, preload)); } return defs; @@ -50,9 +50,9 @@ public final class MapFileDecoder { public static final class MapDefinition { /** - * The hash of the region coordinates. + * The packed coordinates. */ - private final int hash; + private final int packetCoordinates; /** * The terrain file id. @@ -70,26 +70,26 @@ public final class MapFileDecoder { private final boolean preload; /** - * Constructs a new {@link MapDefinition} with the specified hash, terrain file id, object file id and preload - * state. + * Constructs a new {@link MapDefinition} with the specified packed coordinates, terrain file id, object file id + * and preload state. * - * @param hash The hash of the region coordinates. + * @param packedCoordinates The packed coordinates. * @param terrainFile The terrain file id. * @param objectFile The object file id. * @param preload Whether or not this map is preloaded. */ - public MapDefinition(int hash, int terrainFile, int objectFile, boolean preload) { - this.hash = hash; + public MapDefinition(int packedCoordinates, int terrainFile, int objectFile, boolean preload) { + this.packetCoordinates = packedCoordinates; this.terrainFile = terrainFile; this.objectFile = objectFile; this.preload = preload; } /** - * Returns the coordinate hash. + * Returns the packed coordinates. */ - public int getHash() { - return hash; + public int getPacketCoordinates() { + return packetCoordinates; } /** diff --git a/src/org/apollo/game/model/area/collision/CollisionMatrix.java b/src/org/apollo/game/model/area/collision/CollisionMatrix.java index 8a97aa3c..28f58106 100644 --- a/src/org/apollo/game/model/area/collision/CollisionMatrix.java +++ b/src/org/apollo/game/model/area/collision/CollisionMatrix.java @@ -221,7 +221,7 @@ public final class CollisionMatrix { * @param y The y coordinate. * @param value The value. */ - private void set(int x, int y, byte value) { + public void set(int x, int y, byte value) { matrix[indexOf(x, y)] = value; }