diff --git a/src/org/apollo/fs/decoder/GameObjectDecoder.java b/src/org/apollo/fs/decoder/GameObjectDecoder.java index 13f95f9a..b37485e9 100644 --- a/src/org/apollo/fs/decoder/GameObjectDecoder.java +++ b/src/org/apollo/fs/decoder/GameObjectDecoder.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.function.Predicate; import org.apollo.fs.IndexedFileSystem; import org.apollo.fs.decoder.MapFileDecoder.MapDefinition; @@ -14,6 +15,7 @@ import org.apollo.game.model.World; import org.apollo.game.model.area.Sector; import org.apollo.game.model.area.SectorRepository; import org.apollo.game.model.area.collision.CollisionMatrix; +import org.apollo.game.model.def.ObjectDefinition; import org.apollo.game.model.entity.GameObject; import org.apollo.util.BufferUtil; import org.apollo.util.CompressionUtil; @@ -111,7 +113,40 @@ 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(); + + CollisionMatrix matrix = sector.getMatrix(height); + + boolean block = false; + + // Ground decoration, signs, water fountains, etc + if (type == 22 && definition.isInteractive()) { + block = true; + } + + Predicate walls = (value) -> value >= 0 && value < 4 || value == 9; + Predicate roofs = (value) -> value >= 12 && value < 22; + + // Walls and roofs that intercept may intercept a mob when moving + if (walls.test(type) || roofs.test(type)) { + block = true; + } + + // General objects, trees, statues, etc + if (type == 10 && definition.isSolid()) { + block = true; + } + + if (block) { + for (int width = 0; width < definition.getWidth(); width++) { + for (int length = 0; length < definition.getLength(); length++) { + matrix.block(x + width, y + length); + } + } + } } private void parseTerrain(ByteBuffer buffer, int x, int y) { @@ -143,11 +178,14 @@ 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(); + if ((flags & FLAG_BLOCKED) != 0) { + sector.getMatrix(height).block(x, y); } - - if((flags & FLAG_BRIDGE) != 0) { + + if ((flags & FLAG_BRIDGE) != 0) { + // FIXME } } diff --git a/src/org/apollo/game/model/area/Sector.java b/src/org/apollo/game/model/area/Sector.java index 3c0b3e89..3f9dfcd9 100644 --- a/src/org/apollo/game/model/area/Sector.java +++ b/src/org/apollo/game/model/area/Sector.java @@ -174,9 +174,7 @@ public final class Sector { Set local = entities.get(old); - if (local == null || !local.remove(entity)) { - throw new IllegalArgumentException("Entity belongs in this sector but does not exist."); - } + Preconditions.checkArgument(local != null && local.remove(entity), "Entity belongs in this sector but does not exist."); local = entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE)); @@ -207,9 +205,7 @@ public final class Sector { Set local = entities.get(position); - if (local == null || !local.remove(entity)) { - throw new IllegalArgumentException("Entity belongs in this sector but does not exist."); - } + Preconditions.checkArgument(local != null && local.remove(entity), "Entity belongs in this sector but does not exist."); notifyListeners(entity, SectorOperation.REMOVE); } diff --git a/src/org/apollo/game/model/area/collision/CollisionMatrix.java b/src/org/apollo/game/model/area/collision/CollisionMatrix.java index 075c49a8..9630ad45 100644 --- a/src/org/apollo/game/model/area/collision/CollisionMatrix.java +++ b/src/org/apollo/game/model/area/collision/CollisionMatrix.java @@ -208,9 +208,9 @@ public final class CollisionMatrix { return any(x, y, flags[north], flags[east]); case WEST: return flagged(x, y, flags[east]); + default: + throw new IllegalArgumentException("Unrecognised direction " + direction + "."); } - - throw new IllegalArgumentException("Unrecognised direction " + direction + "."); } /**