mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-06 08:40:03 +00:00
Improve MapFileDecoder decode, add ObjectGroup and ObjectType.
This commit is contained in:
@@ -11,10 +11,10 @@ import java.util.function.Predicate;
|
|||||||
import org.apollo.fs.IndexedFileSystem;
|
import org.apollo.fs.IndexedFileSystem;
|
||||||
import org.apollo.fs.decoder.MapFileDecoder.MapDefinition;
|
import org.apollo.fs.decoder.MapFileDecoder.MapDefinition;
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
import org.apollo.game.model.World;
|
|
||||||
import org.apollo.game.model.area.Sector;
|
import org.apollo.game.model.area.Sector;
|
||||||
import org.apollo.game.model.area.SectorRepository;
|
import org.apollo.game.model.area.SectorRepository;
|
||||||
import org.apollo.game.model.area.collision.CollisionMatrix;
|
import org.apollo.game.model.area.collision.CollisionMatrix;
|
||||||
|
import org.apollo.game.model.area.obj.ObjectType;
|
||||||
import org.apollo.game.model.def.ObjectDefinition;
|
import org.apollo.game.model.def.ObjectDefinition;
|
||||||
import org.apollo.game.model.entity.GameObject;
|
import org.apollo.game.model.entity.GameObject;
|
||||||
import org.apollo.util.BufferUtil;
|
import org.apollo.util.BufferUtil;
|
||||||
@@ -26,23 +26,19 @@ import com.google.common.collect.Iterables;
|
|||||||
* Parses static object definitions, which include map tiles and landscapes.
|
* Parses static object definitions, which include map tiles and landscapes.
|
||||||
*
|
*
|
||||||
* @author Ryley
|
* @author Ryley
|
||||||
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class GameObjectDecoder {
|
public final class GameObjectDecoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bit flag which denotes that a specified Position is blocked.
|
* A bit flag that indicates that the tile at the current Position is blocked.
|
||||||
*/
|
*/
|
||||||
private static final int FLAG_BLOCKED = 1;
|
private static final int BLOCKED_TILE = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bit flag which denotes that a specified Position is a bridge.
|
* A bit flag that indicates that the tile at the current Position is a bridge tile.
|
||||||
*/
|
*/
|
||||||
private static final int FLAG_BRIDGE = 2;
|
private static final int BRIDGE_TILE = 2;
|
||||||
|
|
||||||
/**
|
|
||||||
* The sector repository.
|
|
||||||
*/
|
|
||||||
private static final SectorRepository REPOSITORY = World.getWorld().getSectorRepository();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link IndexedFileSystem}.
|
* The {@link IndexedFileSystem}.
|
||||||
@@ -50,97 +46,85 @@ public final class GameObjectDecoder {
|
|||||||
private final IndexedFileSystem fs;
|
private final IndexedFileSystem fs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link List} of decoded game objects.
|
* A {@link List} of decoded GameObjects.
|
||||||
*/
|
*/
|
||||||
private final List<GameObject> objects = new ArrayList<>();
|
private final List<GameObject> objects = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the decoder.
|
* The SectorRepository.
|
||||||
*
|
|
||||||
* @param fs The indexed file system.
|
|
||||||
*/
|
*/
|
||||||
public GameObjectDecoder(IndexedFileSystem fs) {
|
private final SectorRepository sectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the GameObjectDecoder.
|
||||||
|
*
|
||||||
|
* @param fs The {@link IndexedFileSystem}.
|
||||||
|
* @param sectors The {@link SectorRepository}.
|
||||||
|
*/
|
||||||
|
public GameObjectDecoder(IndexedFileSystem fs, SectorRepository sectors) {
|
||||||
this.fs = fs;
|
this.fs = fs;
|
||||||
|
this.sectors = sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes all static objects and places them in the returned array.
|
* Decodes the GameObjects from their MapDefinitions.
|
||||||
*
|
*
|
||||||
* @return The decoded objects.
|
* @return The decoded objects.
|
||||||
* @throws IOException If an I/O error occurs.
|
* @throws IOException If there is an error decoding the {@link MapDefinition}s.
|
||||||
*/
|
*/
|
||||||
public GameObject[] decode() throws IOException {
|
public GameObject[] decode() throws IOException {
|
||||||
Map<Integer, MapDefinition> definitions = MapFileDecoder.decode(fs);
|
Map<Integer, MapDefinition> definitions = MapFileDecoder.decode(fs);
|
||||||
|
|
||||||
for (Entry<Integer, MapDefinition> entry : definitions.entrySet()) {
|
for (Entry<Integer, MapDefinition> entry : definitions.entrySet()) {
|
||||||
MapDefinition def = entry.getValue();
|
MapDefinition definition = entry.getValue();
|
||||||
|
|
||||||
int packed = def.getPacketCoordinates();
|
int packed = definition.getPackedCoordinates();
|
||||||
int x = (packed >> 8 & 0xFF) * 64;
|
int x = (packed >> 8 & 0xFF) * 64;
|
||||||
int y = (packed & 0xFF) * 64;
|
int y = (packed & 0xFF) * 64;
|
||||||
|
|
||||||
ByteBuffer gameObjectData = fs.getFile(4, def.getObjectFile());
|
ByteBuffer objects = fs.getFile(4, definition.getObjectFile());
|
||||||
ByteBuffer gameObjectBuffer = ByteBuffer.wrap(CompressionUtil.degzip(gameObjectData));
|
ByteBuffer decompressed = ByteBuffer.wrap(CompressionUtil.degzip(objects));
|
||||||
parseGameObject(gameObjectBuffer, x, y);
|
decodeObjects(decompressed, x, y);
|
||||||
|
|
||||||
ByteBuffer terrainData = fs.getFile(4, def.getTerrainFile());
|
ByteBuffer terrain = fs.getFile(4, definition.getTerrainFile());
|
||||||
ByteBuffer terrainBuffer = ByteBuffer.wrap(CompressionUtil.degzip(terrainData));
|
decompressed = ByteBuffer.wrap(CompressionUtil.degzip(terrain));
|
||||||
parseTerrain(terrainBuffer, x, y);
|
decodeTerrain(decompressed, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Iterables.toArray(objects, GameObject.class);
|
return Iterables.toArray(objects, GameObject.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseGameObject(ByteBuffer buffer, int x, int y) {
|
/**
|
||||||
for (int deltaId, id = -1; (deltaId = BufferUtil.readSmart(buffer)) != 0;) {
|
* Blocks tiles covered by a GameObject, if applicable.
|
||||||
id += deltaId;
|
*
|
||||||
|
* @param object The {@link GameObject}.
|
||||||
|
* @param position The position of the GameObject.
|
||||||
|
*/
|
||||||
|
private void block(GameObject object, Position position) {
|
||||||
|
ObjectDefinition definition = ObjectDefinition.lookup(object.getId());
|
||||||
|
int type = object.getType();
|
||||||
|
|
||||||
for (int deltaPos, pos = 0; (deltaPos = BufferUtil.readSmart(buffer)) != 0;) {
|
Sector sector = sectors.fromPosition(position);
|
||||||
pos += deltaPos - 1;
|
|
||||||
|
|
||||||
int localY = pos & 0x3F;
|
|
||||||
int localX = pos >> 6 & 0x3F;
|
|
||||||
int height = pos >> 12;
|
|
||||||
|
|
||||||
int attributes = buffer.get() & 0xFF;
|
|
||||||
int type = attributes >> 2;
|
|
||||||
int orientation = attributes & 0x3;
|
|
||||||
Position position = new Position(x + localX, y + localY, height);
|
|
||||||
|
|
||||||
gameObjectDecoded(id, orientation, type, position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void gameObjectDecoded(int id, int orientation, int type, Position position) {
|
|
||||||
ObjectDefinition definition = ObjectDefinition.lookup(id);
|
|
||||||
|
|
||||||
Sector sector = REPOSITORY.fromPosition(position);
|
|
||||||
int x = position.getX(), y = position.getY(), height = position.getHeight();
|
int x = position.getX(), y = position.getY(), height = position.getHeight();
|
||||||
|
|
||||||
// FIXME: For some reason the height is negative on some occasions
|
|
||||||
if (height < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CollisionMatrix matrix = sector.getMatrix(height);
|
CollisionMatrix matrix = sector.getMatrix(height);
|
||||||
|
|
||||||
boolean block = false;
|
boolean block = false;
|
||||||
|
|
||||||
// Ground decoration, signs, water fountains, etc
|
if (type == ObjectType.FLOOR_DECORATION.getValue() && definition.isInteractive()) {
|
||||||
if (type == 22 && definition.isInteractive()) {
|
|
||||||
block = true;
|
block = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Predicate<Integer> walls = (value) -> value >= 0 && value < 4 || value == 9;
|
Predicate<Integer> walls = (value) -> value >= ObjectType.LENGTHWISE_WALL.getValue()
|
||||||
Predicate<Integer> roofs = (value) -> value >= 12 && value < 22;
|
&& value <= ObjectType.RECTANGULAR_CORNER.getValue() || value == ObjectType.DIAGONAL_WALL.getValue();
|
||||||
|
|
||||||
|
Predicate<Integer> roofs = (value) -> value > ObjectType.DIAGONAL_INTERACTABLE.getValue()
|
||||||
|
&& value < ObjectType.FLOOR_DECORATION.getValue();
|
||||||
|
|
||||||
// Walls and roofs that intercept may intercept a mob when moving
|
|
||||||
if (walls.test(type) || roofs.test(type)) {
|
if (walls.test(type) || roofs.test(type)) {
|
||||||
block = true;
|
block = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// General objects, trees, statues, etc
|
|
||||||
if (type == 10 && definition.isSolid()) {
|
if (type == 10 && definition.isSolid()) {
|
||||||
block = true;
|
block = true;
|
||||||
}
|
}
|
||||||
@@ -154,11 +138,14 @@ public final class GameObjectDecoder {
|
|||||||
int nextLocalX = localX > 7 ? x + localX - 7 : x + localX;
|
int nextLocalX = localX > 7 ? x + localX - 7 : x + localX;
|
||||||
int nextLocalY = localY > 7 ? y + localY - 7 : y - localY;
|
int nextLocalY = localY > 7 ? y + localY - 7 : y - localY;
|
||||||
Position nextPosition = new Position(nextLocalX, nextLocalY);
|
Position nextPosition = new Position(nextLocalX, nextLocalY);
|
||||||
Sector next = REPOSITORY.fromPosition(nextPosition);
|
Sector next = sectors.fromPosition(nextPosition);
|
||||||
|
|
||||||
int nextX = (nextPosition.getX() % Sector.SECTOR_SIZE) + dx, nextY = (nextPosition.getY() % Sector.SECTOR_SIZE) + dy;
|
int nextX = (nextPosition.getX() % Sector.SECTOR_SIZE) + dx, nextY = (nextPosition.getY() % Sector.SECTOR_SIZE)
|
||||||
if(nextX > 7) nextX -= 7;
|
+ dy;
|
||||||
if(nextY > 7) nextY -= 7;
|
if (nextX > 7)
|
||||||
|
nextX -= 7;
|
||||||
|
if (nextY > 7)
|
||||||
|
nextY -= 7;
|
||||||
|
|
||||||
next.getMatrix(height).block(nextX, nextY);
|
next.getMatrix(height).block(nextX, nextY);
|
||||||
continue;
|
continue;
|
||||||
@@ -168,56 +155,28 @@ public final class GameObjectDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.add(new GameObject(id, position, type, orientation));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseTerrain(ByteBuffer buffer, int x, int y) {
|
/**
|
||||||
for (int height = 0; height < 4; height++) {
|
* Decodes the attributes of a terrain file, blocking the tile if necessary.
|
||||||
for (int localX = 0; localX < 64; localX++) {
|
*
|
||||||
for (int localY = 0; localY < 64; localY++) {
|
* @param attributes The terrain attributes.
|
||||||
Position position = new Position(x + localX, y + localY, height);
|
* @param position The {@link Position} of the tile whose attributes are being decoded.
|
||||||
|
*/
|
||||||
int flags = 0;
|
private void decodeAttributes(int attributes, Position position) {
|
||||||
while (true) {
|
Sector sector = sectors.fromPosition(position);
|
||||||
int attributeId = buffer.get() & 0xFF;
|
|
||||||
if (attributeId == 0) {
|
|
||||||
terrainDecoded(flags, position);
|
|
||||||
break;
|
|
||||||
} else if (attributeId == 1) {
|
|
||||||
buffer.get();
|
|
||||||
terrainDecoded(flags, position);
|
|
||||||
break;
|
|
||||||
} else if (attributeId <= 49) {
|
|
||||||
buffer.get();
|
|
||||||
} else if (attributeId <= 81) {
|
|
||||||
flags = attributeId - 49;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void terrainDecoded(int flags, Position position) {
|
|
||||||
Sector sector = REPOSITORY.fromPosition(position);
|
|
||||||
int x = position.getX(), y = position.getY(), height = position.getHeight();
|
int x = position.getX(), y = position.getY(), height = position.getHeight();
|
||||||
|
|
||||||
// FIXME: For some reason the height is negative on some occasions
|
|
||||||
if (height < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CollisionMatrix current = sector.getMatrix(height);
|
CollisionMatrix current = sector.getMatrix(height);
|
||||||
|
|
||||||
boolean block = false;
|
boolean block = false;
|
||||||
if ((flags & FLAG_BLOCKED) != 0) {
|
if ((attributes & BLOCKED_TILE) != 0) {
|
||||||
block = true;
|
block = true;
|
||||||
}
|
}
|
||||||
|
if ((attributes & BRIDGE_TILE) != 0) {
|
||||||
if ((flags & FLAG_BRIDGE) != 0) {
|
if (height > 0) {
|
||||||
if (--height >= 0) {
|
|
||||||
block = true;
|
block = true;
|
||||||
|
height--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,4 +186,78 @@ public final class GameObjectDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes object data stored in the specified {@link ByteBuffer}.
|
||||||
|
*
|
||||||
|
* @param buffer The ByteBuffer.
|
||||||
|
* @param x The x coordinate of the top left tile of the map file.
|
||||||
|
* @param y The y coordinate of the top left tile of the map file.
|
||||||
|
*/
|
||||||
|
private void decodeObjects(ByteBuffer buffer, int x, int y) {
|
||||||
|
int id = -1;
|
||||||
|
int idOffset = BufferUtil.readSmart(buffer);
|
||||||
|
|
||||||
|
while (idOffset != 0) {
|
||||||
|
id += idOffset;
|
||||||
|
|
||||||
|
int packed = 0;
|
||||||
|
int positionOffset = BufferUtil.readSmart(buffer);
|
||||||
|
|
||||||
|
while (positionOffset != 0) {
|
||||||
|
packed += positionOffset - 1;
|
||||||
|
|
||||||
|
int localY = packed & 0x3F;
|
||||||
|
int localX = packed >> 6 & 0x3F;
|
||||||
|
int height = (packed >> 12) & 0x3;
|
||||||
|
|
||||||
|
int attributes = buffer.get() & 0xFF;
|
||||||
|
int type = attributes >> 2;
|
||||||
|
int orientation = attributes & 0x3;
|
||||||
|
Position position = new Position(x + localX, y + localY, height);
|
||||||
|
|
||||||
|
GameObject object = new GameObject(id, position, type, orientation);
|
||||||
|
objects.add(object);
|
||||||
|
|
||||||
|
block(object, position);
|
||||||
|
positionOffset = BufferUtil.readSmart(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
idOffset = BufferUtil.readSmart(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes terrain data stored in the specified {@link ByteBuffer}.
|
||||||
|
*
|
||||||
|
* @param buffer The ByteBuffer.
|
||||||
|
* @param x The x coordinate of the top left tile of the map file.
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
int attributes = 0;
|
||||||
|
while (true) {
|
||||||
|
int attributeId = buffer.get() & 0xFF;
|
||||||
|
if (attributeId == 0) {
|
||||||
|
decodeAttributes(attributes, position);
|
||||||
|
break;
|
||||||
|
} else if (attributeId == 1) {
|
||||||
|
buffer.get();
|
||||||
|
decodeAttributes(attributes, position);
|
||||||
|
break;
|
||||||
|
} else if (attributeId <= 49) {
|
||||||
|
buffer.get();
|
||||||
|
} else if (attributeId <= 81) {
|
||||||
|
attributes = attributeId - 49;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,109 +8,127 @@ import java.util.Map;
|
|||||||
import org.apollo.fs.IndexedFileSystem;
|
import org.apollo.fs.IndexedFileSystem;
|
||||||
import org.apollo.fs.archive.Archive;
|
import org.apollo.fs.archive.Archive;
|
||||||
import org.apollo.fs.archive.ArchiveEntry;
|
import org.apollo.fs.archive.ArchiveEntry;
|
||||||
|
import org.apollo.game.model.area.Sector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link MapDefinition map definitions} from the {@link IndexedFileSystem}.
|
* Decodes {@link MapDefinition}s from the {@link IndexedFileSystem}.
|
||||||
*
|
*
|
||||||
* @author Ryley
|
* @author Ryley
|
||||||
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class MapFileDecoder {
|
public final class MapFileDecoder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width (and length) of a map file, in tiles.
|
||||||
|
*/
|
||||||
|
public static final int MAP_FILE_WIDTH = Sector.SECTOR_SIZE * Sector.SECTOR_SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file id of the versions archive.
|
||||||
|
*/
|
||||||
|
private static final int VERSIONS_ARCHIVE_FILE_ID = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link MapDefinition}s from the specified {@link IndexedFileSystem}.
|
* Decodes {@link MapDefinition}s from the specified {@link IndexedFileSystem}.
|
||||||
*
|
*
|
||||||
* @param fs The file system.
|
* @param fs The IndexedFileSystem.
|
||||||
* @return A {@link Map} of parsed map definitions.
|
* @return A {@link Map} of packed coordinates to their MapDefinitions.
|
||||||
* @throws IOException If some I/O error occurs.
|
* @throws IOException If there is an error reading or decoding the Archive.
|
||||||
*/
|
*/
|
||||||
protected static Map<Integer, MapDefinition> decode(IndexedFileSystem fs) throws IOException {
|
protected static Map<Integer, MapDefinition> decode(IndexedFileSystem fs) throws IOException {
|
||||||
Archive archive = Archive.decode(fs.getFile(0, 5));
|
Archive archive = Archive.decode(fs.getFile(0, VERSIONS_ARCHIVE_FILE_ID));
|
||||||
ArchiveEntry entry = archive.getEntry("map_index");
|
ArchiveEntry entry = archive.getEntry("map_index");
|
||||||
|
Map<Integer, MapDefinition> definitions = new HashMap<>();
|
||||||
|
|
||||||
ByteBuffer buffer = entry.getBuffer();
|
ByteBuffer buffer = entry.getBuffer();
|
||||||
Map<Integer, MapDefinition> defs = new HashMap<>();
|
int count = buffer.capacity() / (3 * Short.BYTES + Byte.BYTES);
|
||||||
|
|
||||||
int count = buffer.capacity() / 7;
|
for (int times = 0; times < count; times++) {
|
||||||
for (int i = 0; i < count; i++) {
|
int packed = buffer.getShort() & 0xFFFF;
|
||||||
int packedCoordinates = buffer.getShort() & 0xFFFF;
|
int terrain = buffer.getShort() & 0xFFFF;
|
||||||
int terrainFile = buffer.getShort() & 0xFFFF;
|
int objects = buffer.getShort() & 0xFFFF;
|
||||||
int objectFile = buffer.getShort() & 0xFFFF;
|
boolean members = buffer.get() == 1;
|
||||||
boolean preload = buffer.get() == 1;
|
|
||||||
|
|
||||||
defs.put(packedCoordinates, new MapDefinition(packedCoordinates, terrainFile, objectFile, preload));
|
definitions.put(packed, new MapDefinition(packed, terrain, objects, members));
|
||||||
}
|
}
|
||||||
|
|
||||||
return defs;
|
return definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a single map definition.
|
* A definition for a region.
|
||||||
*
|
|
||||||
* @author Ryley
|
|
||||||
*/
|
*/
|
||||||
public static final class MapDefinition {
|
public static final class MapDefinition {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The packed coordinates.
|
* The packed coordinates.
|
||||||
*/
|
*/
|
||||||
private final int packetCoordinates;
|
private final int packedCoordinates;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The terrain file id.
|
* The terrain file id.
|
||||||
*/
|
*/
|
||||||
private final int terrainFile;
|
private final int terrain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object file id.
|
* The object file id.
|
||||||
*/
|
*/
|
||||||
private final int objectFile;
|
private final int objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not this map is preloaded.
|
* Indicates whether or not this map is members-only.
|
||||||
*/
|
*/
|
||||||
private final boolean preload;
|
private final boolean members;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link MapDefinition} with the specified packed coordinates, terrain file id, object file id
|
* Creates the {@link MapDefinition}.
|
||||||
* and preload state.
|
|
||||||
*
|
*
|
||||||
* @param packedCoordinates The packed coordinates.
|
* @param packedCoordinates The packed coordinates.
|
||||||
* @param terrainFile The terrain file id.
|
* @param terrain The terrain file id.
|
||||||
* @param objectFile The object file id.
|
* @param objects The object file id.
|
||||||
* @param preload Whether or not this map is preloaded.
|
* @param members Indicates whether or not this map is members-only.
|
||||||
*/
|
*/
|
||||||
public MapDefinition(int packedCoordinates, int terrainFile, int objectFile, boolean preload) {
|
public MapDefinition(int packedCoordinates, int terrain, int objects, boolean members) {
|
||||||
this.packetCoordinates = packedCoordinates;
|
this.packedCoordinates = packedCoordinates;
|
||||||
this.terrainFile = terrainFile;
|
this.terrain = terrain;
|
||||||
this.objectFile = objectFile;
|
this.objects = objects;
|
||||||
this.preload = preload;
|
this.members = members;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the packed coordinates.
|
* Gets the packed coordinates.
|
||||||
|
*
|
||||||
|
* @return The packed coordinates.
|
||||||
*/
|
*/
|
||||||
public int getPacketCoordinates() {
|
public int getPackedCoordinates() {
|
||||||
return packetCoordinates;
|
return packedCoordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the terrain file id.
|
* Gets the id of the file containing the terrain data.
|
||||||
|
*
|
||||||
|
* @return The file id.
|
||||||
*/
|
*/
|
||||||
public int getTerrainFile() {
|
public int getTerrainFile() {
|
||||||
return terrainFile;
|
return terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the object file id.
|
* Gets the id of the file containing the object data.
|
||||||
|
*
|
||||||
|
* @return The file id.
|
||||||
*/
|
*/
|
||||||
public int getObjectFile() {
|
public int getObjectFile() {
|
||||||
return objectFile;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not this map is preloaded.
|
* Returns whether or not this MapDefinition is for a members-only area of the world.
|
||||||
|
*
|
||||||
|
* @return {@code true} if this MapDefinition is for a members-only area, {@code false} if not.
|
||||||
*/
|
*/
|
||||||
public boolean isPreload() {
|
public boolean isMembersOnly() {
|
||||||
return preload;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ public final class World {
|
|||||||
ObjectDefinition.init(objectDefs);
|
ObjectDefinition.init(objectDefs);
|
||||||
logger.fine("Loaded " + objectDefs.length + " object definitions.");
|
logger.fine("Loaded " + objectDefs.length + " object definitions.");
|
||||||
|
|
||||||
GameObjectDecoder staticDecoder = new GameObjectDecoder(fs);
|
GameObjectDecoder staticDecoder = new GameObjectDecoder(fs, sectors);
|
||||||
GameObject[] objects = staticDecoder.decode();
|
GameObject[] objects = staticDecoder.decode();
|
||||||
placeEntities(objects);
|
placeEntities(objects);
|
||||||
logger.fine("Loaded " + objects.length + " static objects.");
|
logger.fine("Loaded " + objects.length + " static objects.");
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package org.apollo.game.model.area.obj;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The group of an object, which indicates its general class (e.g. if it's a wall, or a floor decoration).
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
* @author Scu11
|
||||||
|
*/
|
||||||
|
public enum ObjectGroup {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The wall object group, which may block a tile.
|
||||||
|
*/
|
||||||
|
WALL(0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The wall decoration object group, which never blocks a tile.
|
||||||
|
*/
|
||||||
|
WALL_DECORATION(1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interactable object group, for objects that can be clicked and interacted with.
|
||||||
|
*/
|
||||||
|
INTERACTABLE_OBJECT(2),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ground decoration object group, which may block a tile.
|
||||||
|
*/
|
||||||
|
GROUND_DECORATION(3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ObjectGroup with the specified integer value.
|
||||||
|
*
|
||||||
|
* @param value The integer value of the ObjectGroup.
|
||||||
|
* @return The ObjectGroup.
|
||||||
|
* @throws IllegalArgumentException If there is no ObjectGroup with the specified value.
|
||||||
|
*/
|
||||||
|
public static ObjectGroup valueOf(int value) {
|
||||||
|
return Arrays.stream(values()).filter(group -> group.value == value).findAny()
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("No ObjectGroup with a value of " + value + " exists."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The integer value of the group.
|
||||||
|
*/
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the ObjectGroup.
|
||||||
|
*
|
||||||
|
* @param value The integer value of the group.
|
||||||
|
*/
|
||||||
|
private ObjectGroup(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of this ObjectGroup.
|
||||||
|
*
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package org.apollo.game.model.area.obj;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of an object, which affects specified behaviour (such as whether it displaces existing objects). TODO
|
||||||
|
* complete this...
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
* @author Scu11
|
||||||
|
*/
|
||||||
|
public enum ObjectType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wall that is presented lengthwise with respect to the tile.
|
||||||
|
*/
|
||||||
|
LENGTHWISE_WALL(0, ObjectGroup.WALL),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A triangular object positioned in the corner of the tile.
|
||||||
|
*/
|
||||||
|
TRIANGULAR_CORNER(1, ObjectGroup.WALL),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A corner for a wall, where the model is placed on two perpendicular edges of a single tile.
|
||||||
|
*/
|
||||||
|
WALL_CORNER(2, ObjectGroup.WALL),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A rectangular object positioned in the corner of the tile.
|
||||||
|
*/
|
||||||
|
RECTANGULAR_CORNER(3, ObjectGroup.WALL),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wall joint that is presented diagonally with respect to the tile.
|
||||||
|
*/
|
||||||
|
DIAGONAL_WALL(9, ObjectGroup.INTERACTABLE_OBJECT),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object that can be interacted with by a player.
|
||||||
|
*/
|
||||||
|
INTERACTABLE(10, ObjectGroup.INTERACTABLE_OBJECT),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link #INTERACTABLE} object, rotated {@code pi / 2} radians.
|
||||||
|
*/
|
||||||
|
DIAGONAL_INTERACTABLE(11, ObjectGroup.INTERACTABLE_OBJECT),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A decoration positioned on the floor.
|
||||||
|
*/
|
||||||
|
FLOOR_DECORATION(22, ObjectGroup.GROUND_DECORATION);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ObjectGroup this type belongs in.
|
||||||
|
*/
|
||||||
|
private final ObjectGroup group;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The integer value of this ObjectType.
|
||||||
|
*/
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the ObjectType.
|
||||||
|
*
|
||||||
|
* @param value The integer value of this ObjectType.
|
||||||
|
* @param group The ObjectGroup of this type.
|
||||||
|
*/
|
||||||
|
private ObjectType(int value, ObjectGroup group) {
|
||||||
|
this.value = value;
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link ObjectGroup} of this ObjectType.
|
||||||
|
*
|
||||||
|
* @return The group.
|
||||||
|
*/
|
||||||
|
public ObjectGroup getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the integer value of this ObjectType.
|
||||||
|
*
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Contains object-related classes.
|
||||||
|
*/
|
||||||
|
package org.apollo.game.model.area.obj;
|
||||||
Reference in New Issue
Block a user