mirror of
https://github.com/2006-Scape/2006Scape.git
synced 2026-07-07 16:49:07 +00:00
Region factory (#404)
* Split region loading and object population to factory class * Implement changes, disable CommandConsole * You guys don't omit /build/
This commit is contained in:
@@ -16,7 +16,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import org.apache.mina.common.IoAcceptor;
|
import org.apache.mina.common.IoAcceptor;
|
||||||
import org.apache.mina.transport.socket.nio.SocketAcceptor;
|
import org.apache.mina.transport.socket.nio.SocketAcceptor;
|
||||||
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
|
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
|
||||||
import com.rebotted.console.CommandConsole;
|
|
||||||
import com.rebotted.event.CycleEventHandler;
|
import com.rebotted.event.CycleEventHandler;
|
||||||
import com.rebotted.game.content.minigames.FightCaves;
|
import com.rebotted.game.content.minigames.FightCaves;
|
||||||
import com.rebotted.game.content.minigames.FightPits;
|
import com.rebotted.game.content.minigames.FightPits;
|
||||||
@@ -47,7 +46,7 @@ import com.rebotted.world.ItemHandler;
|
|||||||
import com.rebotted.world.ObjectHandler;
|
import com.rebotted.world.ObjectHandler;
|
||||||
import com.rebotted.world.ObjectManager;
|
import com.rebotted.world.ObjectManager;
|
||||||
import com.rebotted.world.clip.ObjectDefinition;
|
import com.rebotted.world.clip.ObjectDefinition;
|
||||||
import com.rebotted.world.clip.Region;
|
import com.rebotted.world.clip.RegionFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server.java
|
* Server.java
|
||||||
@@ -189,7 +188,7 @@ public class GameEngine {
|
|||||||
* Initialise Handlers
|
* Initialise Handlers
|
||||||
*/
|
*/
|
||||||
ObjectDefinition.loadConfig();
|
ObjectDefinition.loadConfig();
|
||||||
Region.load();
|
RegionFactory.load();
|
||||||
Doors.getSingleton().load();
|
Doors.getSingleton().load();
|
||||||
DoubleDoors.getSingleton().load();
|
DoubleDoors.getSingleton().load();
|
||||||
ItemDefinition.read();
|
ItemDefinition.read();
|
||||||
@@ -265,7 +264,11 @@ public class GameEngine {
|
|||||||
}
|
}
|
||||||
}, 0, GameConstants.CYCLE_TIME, TimeUnit.MILLISECONDS);
|
}, 0, GameConstants.CYCLE_TIME, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
CommandConsole.getInstance();
|
/*
|
||||||
|
* I'd recommend disabling this until I can be bothered to implement it
|
||||||
|
* properly.
|
||||||
|
*/
|
||||||
|
// CommandConsole.getInstance();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {
|
while (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {
|
||||||
|
|||||||
@@ -1,29 +1,70 @@
|
|||||||
package com.rebotted.world.clip;
|
package com.rebotted.world.clip;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
import com.rebotted.game.objects.Objects;
|
import com.rebotted.game.objects.Objects;
|
||||||
|
|
||||||
public class Region {
|
public class Region {
|
||||||
|
|
||||||
private ArrayList<Objects> realObjects = new ArrayList<Objects>();
|
private ArrayList<Objects> realObjects = new ArrayList<Objects>();
|
||||||
|
private final int id;
|
||||||
|
private final int[][][] clips = new int[4][][];
|
||||||
|
private final int[][][] projectileClips = new int[4][][];
|
||||||
|
private boolean members = false;
|
||||||
|
|
||||||
|
public Region(int id, boolean members) {
|
||||||
|
this.id = id;
|
||||||
|
this.members = members;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean members() {
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMembers(int x, int y) {
|
||||||
|
if (x >= 3272 && x <= 3320 && y >= 2752 && y <= 2809) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (x >= 2640 && x <= 2677 && y >= 2638 && y <= 2679) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getRegion(x, y).members();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes X Y coordinates, gives a region object
|
||||||
|
*
|
||||||
|
* @param x coordinate X
|
||||||
|
* @param y coordinate Y
|
||||||
|
* @return Region object
|
||||||
|
*/
|
||||||
public static Region getRegion(int x, int y) {
|
public static Region getRegion(int x, int y) {
|
||||||
int regionX = x >> 3;
|
int regionId = getRegionId(x,y);
|
||||||
int regionY = y >> 3;
|
for (Region region : RegionFactory.getRegions()) {
|
||||||
int regionId = (regionX / 8 << 8) + regionY / 8;
|
|
||||||
for (Region region : regions) {
|
|
||||||
if (region.id() == regionId) {
|
if (region.id() == regionId) {
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates regionId from X Y coordinates
|
||||||
|
*
|
||||||
|
* @param x coordinate X
|
||||||
|
* @param y coordinate Y
|
||||||
|
* @return ID of target region
|
||||||
|
*/
|
||||||
|
public static int getRegionId(int x, int y) {
|
||||||
|
int regionX = x >> 3;
|
||||||
|
int regionY = y >> 3;
|
||||||
|
int regionId = (regionX / 8 << 8) + regionY / 8;
|
||||||
|
return regionId;
|
||||||
|
}
|
||||||
|
|
||||||
public static Objects getObject(int id, int x, int y, int z) {
|
public static Objects getObject(int id, int x, int y, int z) {
|
||||||
Region r = getRegion(x, y);
|
Region r = getRegion(x, y);
|
||||||
@@ -71,12 +112,16 @@ public class Region {
|
|||||||
clips[height][x - regionAbsX][y - regionAbsY] = 0;
|
clips[height][x - regionAbsX][y - regionAbsY] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeClipping(int x, int y, int height) {
|
/**
|
||||||
final int regionX = x >> 3;
|
* Nothing calls this...
|
||||||
final int regionY = y >> 3;
|
*
|
||||||
final int regionId = ((regionX / 8) << 8) + (regionY / 8);
|
* @param x
|
||||||
for (Region r : regions) {
|
* @param y
|
||||||
if (r.id() == regionId) {
|
* @param height
|
||||||
|
*/
|
||||||
|
public void removeClipping(int x, int y, int height) {
|
||||||
|
for (Region r : RegionFactory.getRegions()) {
|
||||||
|
if (r.id() == getRegionId(x,y)) {
|
||||||
r.removeClip(x, y, height);
|
r.removeClip(x, y, height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -142,21 +187,25 @@ public class Region {
|
|||||||
|
|
||||||
public static boolean canShoot(int x, int y, int z, int direction) {
|
public static boolean canShoot(int x, int y, int z, int direction) {
|
||||||
if (direction == 0) {
|
if (direction == 0) {
|
||||||
return !projectileBlockedNorthWest(x, y, z) && !projectileBlockedNorth(x, y, z) && !projectileBlockedWest(x, y, z);
|
return !projectileBlockedNorthWest(x, y, z) && !projectileBlockedNorth(x, y, z)
|
||||||
|
&& !projectileBlockedWest(x, y, z);
|
||||||
} else if (direction == 1) {
|
} else if (direction == 1) {
|
||||||
return !projectileBlockedNorth(x, y, z);
|
return !projectileBlockedNorth(x, y, z);
|
||||||
} else if (direction == 2) {
|
} else if (direction == 2) {
|
||||||
return !projectileBlockedNorthEast(x, y, z) && !projectileBlockedNorth(x, y, z) && !projectileBlockedEast(x, y, z);
|
return !projectileBlockedNorthEast(x, y, z) && !projectileBlockedNorth(x, y, z)
|
||||||
|
&& !projectileBlockedEast(x, y, z);
|
||||||
} else if (direction == 3) {
|
} else if (direction == 3) {
|
||||||
return !projectileBlockedWest(x, y, z);
|
return !projectileBlockedWest(x, y, z);
|
||||||
} else if (direction == 4) {
|
} else if (direction == 4) {
|
||||||
return !projectileBlockedEast(x, y, z);
|
return !projectileBlockedEast(x, y, z);
|
||||||
} else if (direction == 5) {
|
} else if (direction == 5) {
|
||||||
return !projectileBlockedSouthWest(x, y, z) && !projectileBlockedSouth(x, y, z) && !projectileBlockedWest(x, y, z);
|
return !projectileBlockedSouthWest(x, y, z) && !projectileBlockedSouth(x, y, z)
|
||||||
|
&& !projectileBlockedWest(x, y, z);
|
||||||
} else if (direction == 6) {
|
} else if (direction == 6) {
|
||||||
return !projectileBlockedSouth(x, y, z);
|
return !projectileBlockedSouth(x, y, z);
|
||||||
} else if (direction == 7) {
|
} else if (direction == 7) {
|
||||||
return !projectileBlockedSouthEast(x, y, z) && !projectileBlockedSouth(x, y, z) && !projectileBlockedEast(x, y, z);
|
return !projectileBlockedSouthEast(x, y, z) && !projectileBlockedSouth(x, y, z)
|
||||||
|
&& !projectileBlockedEast(x, y, z);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -285,12 +334,17 @@ public class Region {
|
|||||||
return projectileClips[height][x - regionAbsX][y - regionAbsY];
|
return projectileClips[height][x - regionAbsX][y - regionAbsY];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds clipping to whichever region matches provided XYZ.
|
||||||
|
*
|
||||||
|
* @param x coordinate X
|
||||||
|
* @param y coordinate Y
|
||||||
|
* @param height coordinate Z
|
||||||
|
* @param shift uuuuh shift?
|
||||||
|
*/
|
||||||
public static void addClipping(int x, int y, int height, int shift) {
|
public static void addClipping(int x, int y, int height, int shift) {
|
||||||
int regionX = x >> 3;
|
for (Region r : RegionFactory.getRegions()) {
|
||||||
int regionY = y >> 3;
|
if (r.id() == getRegionId(x, y)) {
|
||||||
int regionId = (regionX / 8 << 8) + regionY / 8;
|
|
||||||
for (Region r : regions) {
|
|
||||||
if (r.id() == regionId) {
|
|
||||||
r.addClip(x, y, height, shift);
|
r.addClip(x, y, height, shift);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -298,55 +352,14 @@ public class Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void addProjectileClipping(int x, int y, int height, int shift) {
|
private static void addProjectileClipping(int x, int y, int height, int shift) {
|
||||||
int regionX = x >> 3;
|
for (Region r : RegionFactory.getRegions()) {
|
||||||
int regionY = y >> 3;
|
if (r.id() == getRegionId(x,y)) {
|
||||||
int regionId = (regionX / 8 << 8) + regionY / 8;
|
|
||||||
for (Region r : regions) {
|
|
||||||
if (r.id() == regionId) {
|
|
||||||
r.addProjectileClip(x, y, height, shift);
|
r.addProjectileClip(x, y, height, shift);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Region[] regions;
|
|
||||||
private final int id;
|
|
||||||
private final int[][][] clips = new int[4][][];
|
|
||||||
private final int[][][] projectileClips = new int[4][][];
|
|
||||||
private boolean members = false;
|
|
||||||
|
|
||||||
public Region(int id, boolean members) {
|
|
||||||
this.id = id;
|
|
||||||
this.members = members;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int id() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean members() {
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isMembers(int x, int y, int height) {
|
|
||||||
if (x >= 3272 && x <= 3320 && y >= 2752 && y <= 2809) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (x >= 2640 && x <= 2677 && y >= 2638 && y <= 2679) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int regionX = x >> 3;
|
|
||||||
int regionY = y >> 3;
|
|
||||||
int regionId = (regionX / 8 << 8) + regionY / 8;
|
|
||||||
for (Region r : regions) {
|
|
||||||
if (r.id() == regionId) {
|
|
||||||
return r.members();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addClippingForVariableObject(int x, int y, int height,
|
private static void addClippingForVariableObject(int x, int y, int height,
|
||||||
int type, int direction, boolean flag) {
|
int type, int direction, boolean flag) {
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
@@ -575,6 +588,18 @@ public class Region {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Adds object to region
|
||||||
|
*
|
||||||
|
* @param objectId
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param height
|
||||||
|
* @param type
|
||||||
|
* @param direction
|
||||||
|
* @param startUp
|
||||||
|
*/
|
||||||
public static void addObject(int objectId, int x, int y, int height, int type, int direction, boolean startUp) {
|
public static void addObject(int objectId, int x, int y, int height, int type, int direction, boolean startUp) {
|
||||||
if (ObjectDefinition.getObjectDef(objectId) == null) {
|
if (ObjectDefinition.getObjectDef(objectId) == null) {
|
||||||
}
|
}
|
||||||
@@ -624,13 +649,10 @@ public class Region {
|
|||||||
|
|
||||||
public static int getClipping(int x, int y, int height) {
|
public static int getClipping(int x, int y, int height) {
|
||||||
if (height > 3) {
|
if (height > 3) {
|
||||||
height = 0;
|
height = 0; //this doesn't seem good
|
||||||
}
|
}
|
||||||
int regionX = x >> 3;
|
for (Region r : RegionFactory.getRegions()) {
|
||||||
int regionY = y >> 3;
|
if (r.id() == getRegionId(x,y)) {
|
||||||
int regionId = (regionX / 8 << 8) + regionY / 8;
|
|
||||||
for (Region r : regions) {
|
|
||||||
if (r.id() == regionId) {
|
|
||||||
return r.getClip(x, y, height);
|
return r.getClip(x, y, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -641,18 +663,16 @@ public class Region {
|
|||||||
if (height > 3) {
|
if (height > 3) {
|
||||||
height = 0;
|
height = 0;
|
||||||
}
|
}
|
||||||
int regionX = x >> 3;
|
for (Region r : RegionFactory.getRegions()) {
|
||||||
int regionY = y >> 3;
|
if (r.id() == getRegionId(x,y)) {
|
||||||
int regionId = (regionX / 8 << 8) + regionY / 8;
|
|
||||||
for (Region r : regions) {
|
|
||||||
if (r.id() == regionId) {
|
|
||||||
return r.getProjectileClip(x, y, height);
|
return r.getProjectileClip(x, y, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getClipping(int x, int y, int height, int moveTypeX, int moveTypeY) {
|
public static boolean getClipping(int x, int y, int height, int moveTypeX,
|
||||||
|
int moveTypeY) {
|
||||||
try {
|
try {
|
||||||
if (height > 3) {
|
if (height > 3) {
|
||||||
height = 0;
|
height = 0;
|
||||||
@@ -694,149 +714,4 @@ public class Region {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void load() {
|
|
||||||
try {
|
|
||||||
File f = new File("./data/world/map_index");
|
|
||||||
byte[] buffer = new byte[(int) f.length()];
|
|
||||||
DataInputStream dis = new DataInputStream(new FileInputStream(f));
|
|
||||||
dis.readFully(buffer);
|
|
||||||
dis.close();
|
|
||||||
ByteStream in = new ByteStream(buffer);
|
|
||||||
int size = in.length() / 7;
|
|
||||||
regions = new Region[size];
|
|
||||||
int[] regionIds = new int[size];
|
|
||||||
int[] mapGroundFileIds = new int[size];
|
|
||||||
int[] mapObjectsFileIds = new int[size];
|
|
||||||
boolean[] isMembers = new boolean[size];
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
regionIds[i] = in.getUShort();
|
|
||||||
mapGroundFileIds[i] = in.getUShort();
|
|
||||||
mapObjectsFileIds[i] = in.getUShort();
|
|
||||||
isMembers[i] = in.getUByte() == 0;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
regions[i] = new Region(regionIds[i], isMembers[i]);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
byte[] file1 = getBuffer(new File("./data/world/map/"
|
|
||||||
+ mapObjectsFileIds[i] + ".gz"));
|
|
||||||
byte[] file2 = getBuffer(new File("./data/world/map/"
|
|
||||||
+ mapGroundFileIds[i] + ".gz"));
|
|
||||||
if (file1 == null || file2 == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
loadMaps(regionIds[i], new ByteStream(file1),
|
|
||||||
new ByteStream(file2));
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("Error loading map region: "
|
|
||||||
+ regionIds[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("[Region] DONE LOADING REGION CONFIGURATIONS");
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loadMaps(int regionId, ByteStream str1, ByteStream str2) {
|
|
||||||
int absX = (regionId >> 8) * 64;
|
|
||||||
int absY = (regionId & 0xff) * 64;
|
|
||||||
int[][][] someArray = new int[4][64][64];
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
for (int i2 = 0; i2 < 64; i2++) {
|
|
||||||
for (int i3 = 0; i3 < 64; i3++) {
|
|
||||||
while (true) {
|
|
||||||
int v = str2.getUByte();
|
|
||||||
if (v == 0) {
|
|
||||||
break;
|
|
||||||
} else if (v == 1) {
|
|
||||||
str2.skip(1);
|
|
||||||
break;
|
|
||||||
} else if (v <= 49) {
|
|
||||||
str2.skip(1);
|
|
||||||
} else if (v <= 81) {
|
|
||||||
someArray[i][i2][i3] = v - 49;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
for (int i2 = 0; i2 < 64; i2++) {
|
|
||||||
for (int i3 = 0; i3 < 64; i3++) {
|
|
||||||
if ((someArray[i][i2][i3] & 1) == 1) {
|
|
||||||
int height = i;
|
|
||||||
if ((someArray[1][i2][i3] & 2) == 2) {
|
|
||||||
height--;
|
|
||||||
}
|
|
||||||
if (height >= 0 && height <= 3) {
|
|
||||||
addClipping(absX + i2, absY + i3, height, 0x200000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int objectId = -1;
|
|
||||||
int incr;
|
|
||||||
while ((incr = str1.getUSmart()) != 0) {
|
|
||||||
objectId += incr;
|
|
||||||
int location = 0;
|
|
||||||
int incr2;
|
|
||||||
while ((incr2 = str1.getUSmart()) != 0) {
|
|
||||||
location += incr2 - 1;
|
|
||||||
int localX = location >> 6 & 0x3f;
|
|
||||||
int localY = location & 0x3f;
|
|
||||||
int height = location >> 12;
|
|
||||||
int objectData = str1.getUByte();
|
|
||||||
int type = objectData >> 2;
|
|
||||||
int direction = objectData & 0x3;
|
|
||||||
if (localX < 0 || localX >= 64 || localY < 0 || localY >= 64) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((someArray[1][localX][localY] & 2) == 2) {
|
|
||||||
height--;
|
|
||||||
}
|
|
||||||
if (height >= 0 && height <= 3) {
|
|
||||||
addObject(objectId, absX + localX, absY + localY, height,
|
|
||||||
type, direction, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] getBuffer(File f) throws Exception {
|
|
||||||
if (!f.exists()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
byte[] buffer = new byte[(int) f.length()];
|
|
||||||
DataInputStream dis = new DataInputStream(new FileInputStream(f));
|
|
||||||
dis.readFully(buffer);
|
|
||||||
dis.close();
|
|
||||||
byte[] gzipInputBuffer = new byte[999999];
|
|
||||||
int bufferlength = 0;
|
|
||||||
GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(
|
|
||||||
buffer));
|
|
||||||
do {
|
|
||||||
if (bufferlength == gzipInputBuffer.length) {
|
|
||||||
System.out
|
|
||||||
.println("Error inflating data.\nGZIP buffer overflow.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int readByte = gzip.read(gzipInputBuffer, bufferlength,
|
|
||||||
gzipInputBuffer.length - bufferlength);
|
|
||||||
if (readByte == -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bufferlength += readByte;
|
|
||||||
} while (true);
|
|
||||||
byte[] inflated = new byte[bufferlength];
|
|
||||||
System.arraycopy(gzipInputBuffer, 0, inflated, 0, bufferlength);
|
|
||||||
buffer = inflated;
|
|
||||||
if (buffer.length < 10) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,196 @@
|
|||||||
|
package com.rebotted.world.clip;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
public class RegionFactory {
|
||||||
|
|
||||||
|
private static Region[] regions;
|
||||||
|
|
||||||
|
public static Region[] getRegions() {
|
||||||
|
return regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void load() {
|
||||||
|
//GameEngine.getLogger(Region.class).info("Loading region configurations...");
|
||||||
|
try {
|
||||||
|
File f = new File("./data/world/map_index");
|
||||||
|
byte[] buffer = new byte[(int) f.length()];
|
||||||
|
DataInputStream dis = new DataInputStream(new FileInputStream(f));
|
||||||
|
dis.readFully(buffer);
|
||||||
|
dis.close();
|
||||||
|
ByteStream in = new ByteStream(buffer);
|
||||||
|
int size = in.length() / 7;
|
||||||
|
regions = new Region[size];
|
||||||
|
int[] regionIds = new int[size];
|
||||||
|
int[] mapGroundFileIds = new int[size];
|
||||||
|
int[] mapObjectsFileIds = new int[size];
|
||||||
|
boolean[] isMembers = new boolean[size];
|
||||||
|
/**
|
||||||
|
* Seems to be that regions consist of
|
||||||
|
* regionIds (16 bits)
|
||||||
|
* groundFileIds (16 bits)
|
||||||
|
* objectsFileIds (16 bits)
|
||||||
|
* isMembers (8 bits)
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
regionIds[i] = in.getUShort();
|
||||||
|
mapGroundFileIds[i] = in.getUShort();
|
||||||
|
mapObjectsFileIds[i] = in.getUShort();
|
||||||
|
isMembers[i] = in.getUByte() == 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
regions[i] = new Region(regionIds[i], isMembers[i]);
|
||||||
|
}
|
||||||
|
//GameEngine.getLogger(Region.class).info(size + " Regions created.");
|
||||||
|
//GameEngine.getLogger(Region.class).info("Populating regions...");
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
//GameEngine.getLogger(Region.class).info("Region: " + i + " RegionId: " + regionIds[i] + " ObjectsId: " + mapObjectsFileIds[i]
|
||||||
|
// + " ClippingsId: " + mapGroundFileIds[i]);
|
||||||
|
byte[] file1 = getBuffer(new File("./data/world/map/"
|
||||||
|
+ mapObjectsFileIds[i] + ".gz"));
|
||||||
|
byte[] file2 = getBuffer(new File("./data/world/map/"
|
||||||
|
+ mapGroundFileIds[i] + ".gz"));
|
||||||
|
if (file1 == null || file2 == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
loadMaps(regionIds[i], new ByteStream(file1),
|
||||||
|
new ByteStream(file2));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Error loading map region: "
|
||||||
|
+ regionIds[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//GameEngine.getLogger(Region.class).info("Region configuration done.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regions in runescape are chunks of the map.
|
||||||
|
* They are comprised of 64x64 blocks of x,y positions on 4 possibly height levels (z).
|
||||||
|
*
|
||||||
|
* This code populates those positions.
|
||||||
|
*
|
||||||
|
* @param regionId
|
||||||
|
* @param str1
|
||||||
|
* @param str2
|
||||||
|
*/
|
||||||
|
private static void loadMaps(int regionId, ByteStream str1, ByteStream str2) {
|
||||||
|
int regionX = (regionId >> 8) * 64; // Region ID is bitshifted to get X position
|
||||||
|
int regionY = (regionId & 0xff) * 64; // Region ID is bitshifted and AND'd against 0xff to get Y position
|
||||||
|
int[][][] positionArray = new int[4][64][64];
|
||||||
|
/**
|
||||||
|
* z seems to be the height (map level?) (0 through 3) (I'm told these loop for additional levels)
|
||||||
|
* x seems to be X position (of 64 possible positions)
|
||||||
|
* y seems to be Y position (of 64 possible positions)
|
||||||
|
*/
|
||||||
|
for (int localz = 0; localz < 4; localz++) { // height (z coord)
|
||||||
|
for (int localx = 0; localx < 64; localx++) { // x coord
|
||||||
|
for (int localy = 0; localy < 64; localy++) { // y coord
|
||||||
|
while (true) { // we loop through each position x,y,z
|
||||||
|
int v = str2.getUByte(); //Reading the bytestream, I guess the map is read and loaded bottom to top, left to right.
|
||||||
|
if (v == 0) {
|
||||||
|
break;
|
||||||
|
} else if (v == 1) {
|
||||||
|
str2.skip(1);
|
||||||
|
break;
|
||||||
|
} else if (v <= 49) {
|
||||||
|
str2.skip(1);
|
||||||
|
} else if (v <= 81) {
|
||||||
|
positionArray[localz][localx][localy] = v - 49; // Clipping data is gathered.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Clipping data is validated and added.
|
||||||
|
*/
|
||||||
|
for (int localz = 0; localz < 4; localz++) {
|
||||||
|
for (int localx = 0; localx < 64; localx++) {
|
||||||
|
for (int localy = 0; localy < 64; localy++) {
|
||||||
|
if ((positionArray[localz][localx][localy] & 1) == 1) {
|
||||||
|
int height = localz;
|
||||||
|
if ((positionArray[1][localx][localy] & 2) == 2) {
|
||||||
|
height--;
|
||||||
|
}
|
||||||
|
if (height >= 0 && height <= 3) {
|
||||||
|
//GameEngine.getLogger(Region.class).debug("Adding clipping at x,y " + (regionX + localx) + "," + (regionY + localy) + " at height: " + localz);
|
||||||
|
Region.addClipping(regionX + localx, regionY + localy, height, 0x200000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Object data.
|
||||||
|
*/
|
||||||
|
int objectId = -1;
|
||||||
|
int incr;
|
||||||
|
while ((incr = str1.getUSmart()) != 0) {
|
||||||
|
objectId += incr;
|
||||||
|
int location = 0;
|
||||||
|
int incr2;
|
||||||
|
while ((incr2 = str1.getUSmart()) != 0) {
|
||||||
|
location += incr2 - 1;
|
||||||
|
int objectX = location >> 6 & 0x3f;
|
||||||
|
int objectY = location & 0x3f;
|
||||||
|
int objectHeight = location >> 12;
|
||||||
|
int objectData = str1.getUByte();
|
||||||
|
int type = objectData >> 2;
|
||||||
|
int direction = objectData & 0x3;
|
||||||
|
if (objectX < 0 || objectX >= 64 || objectY < 0 || objectY >= 64) {
|
||||||
|
continue; //Checks the object position is not outside the bounds of a region (0-64)
|
||||||
|
}
|
||||||
|
if ((positionArray[1][objectX][objectY] & 2) == 2) {
|
||||||
|
objectHeight--;
|
||||||
|
}
|
||||||
|
if (objectHeight >= 0 && objectHeight <= 3) {
|
||||||
|
Region.addObject(objectId, regionX + objectX, regionY + objectY, objectHeight,
|
||||||
|
type, direction, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getBuffer(File f) throws Exception {
|
||||||
|
if (!f.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] buffer = new byte[(int) f.length()];
|
||||||
|
DataInputStream dis = new DataInputStream(new FileInputStream(f));
|
||||||
|
dis.readFully(buffer);
|
||||||
|
dis.close();
|
||||||
|
byte[] gzipInputBuffer = new byte[999999];
|
||||||
|
int bufferlength = 0;
|
||||||
|
GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(
|
||||||
|
buffer));
|
||||||
|
do {
|
||||||
|
if (bufferlength == gzipInputBuffer.length) {
|
||||||
|
System.out
|
||||||
|
.println("Error inflating data.\nGZIP buffer overflow.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int readByte = gzip.read(gzipInputBuffer, bufferlength,
|
||||||
|
gzipInputBuffer.length - bufferlength);
|
||||||
|
if (readByte == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bufferlength += readByte;
|
||||||
|
} while (true);
|
||||||
|
byte[] inflated = new byte[bufferlength];
|
||||||
|
System.arraycopy(gzipInputBuffer, 0, inflated, 0, bufferlength);
|
||||||
|
buffer = inflated;
|
||||||
|
if (buffer.length < 10) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user