diff --git a/rsc-client/.classpath b/rsc-client/.classpath
index 86065df..5d94adc 100644
--- a/rsc-client/.classpath
+++ b/rsc-client/.classpath
@@ -1,10 +1,15 @@
-
-
Based on Surface.java
from other RSC sources.
+ *
+ * Based on Surface.java
from other RSC sources.
*
* @author Dan Bryce
*/
@@ -88,10 +89,9 @@ public void drawSprite(int x, int y, int id) {
/*
* Bounds checking.
*
- * If part of the Sprite is offscreen, this ensures that we only draw
- * the visible part of the image. Attempting to draw the full image
- * would result in parts of the image wrapping onto the next row of
- * pixels.
+ * If part of the Sprite is offscreen, this ensures that we only draw the
+ * visible part of the image. Attempting to draw the full image would result in
+ * parts of the image wrapping onto the next row of pixels.
*/
if (y < 0) {
@@ -125,36 +125,37 @@ public void drawSprite(int x, int y, int id) {
return;
}
- setPixels(pixels, sprite.getPixels(),
- sourceIndex, targetIndex,
- spriteWidth, spriteHeight,
- screenRowIncrement, spriteRowIncrement);
+ setPixels(pixels, sprite.getPixels(), sourceIndex, targetIndex, spriteWidth, spriteHeight, screenRowIncrement,
+ spriteRowIncrement);
}
/**
* Copies a block of pixels from the source to the target.
*
- * @param target Target pixel data.
- * @param source Source pixel data.
- * @param sourceIndex Starting index for the source array.
- * @param targetIndex Starting index for the target array.
- * @param sourceWidth Width of the source image.
- * @param sourceHeight Height of the source image.
+ * @param target
+ * Target pixel data.
+ * @param source
+ * Source pixel data.
+ * @param sourceIndex
+ * Starting index for the source array.
+ * @param targetIndex
+ * Starting index for the target array.
+ * @param sourceWidth
+ * Width of the source image.
+ * @param sourceHeight
+ * Height of the source image.
* @param targetRowIncrement
- * Value to add to the target index after each row is copied.
+ * Value to add to the target index after each row is copied.
* @param sourceRowIncrement
- * Value to add to the source index after each row is copied.
+ * Value to add to the source index after each row is copied.
*/
- private static void setPixels(
- int target[], int source[],
- int sourceIndex, int targetIndex,
- int sourceWidth, int sourceHeight,
- int targetRowIncrement, int sourceRowIncrement) {
+ private static void setPixels(int target[], int source[], int sourceIndex, int targetIndex, int sourceWidth,
+ int sourceHeight, int targetRowIncrement, int sourceRowIncrement) {
/*
- * The original source code copied multiple pixels at a time inside the
- * loop body, presumably intended as some kind of optimisation. Here I
- * have favoured simplicity over efficiency.
+ * The original source code copied multiple pixels at a time inside the loop
+ * body, presumably intended as some kind of optimisation. Here I have favoured
+ * simplicity over efficiency.
*/
for (int y = 0; y < sourceHeight; y++) {
for (int x = 0; x < sourceWidth; x++) {
@@ -268,19 +269,8 @@ private void plotSale(int texturePixels[], int i, int j, int k, int l, int i1, i
* @param paramD
* @param paramDModifier
*/
- public void renderScanline_LargeTexture(
- int texturePixels[],
- int i,
- int j,
- int paramA,
- int paramB,
- int paramC,
- int paramAModifier,
- int paramBModifier,
- int paramCModifier,
- int length,
- int pxOffset,
- int paramD,
+ public void renderScanline_LargeTexture(int texturePixels[], int i, int j, int paramA, int paramB, int paramC,
+ int paramAModifier, int paramBModifier, int paramCModifier, int length, int pxOffset, int paramD,
int paramDModifier) {
if (length <= 0) {
@@ -424,20 +414,8 @@ public void renderScanline_LargeTexture(
}
}
- public void renderScanline_LargeTranslucentTexture(
- int texturePixels[],
- int texOffset,
- int texStart,
- int k,
- int l,
- int i1,
- int j1,
- int k1,
- int l1,
- int length,
- int pxIndex,
- int k2,
- int l2) {
+ public void renderScanline_LargeTranslucentTexture(int texturePixels[], int texOffset, int texStart, int k, int l,
+ int i1, int j1, int k1, int l1, int length, int pxIndex, int k2, int l2) {
if (length <= 0) {
return;
@@ -481,64 +459,80 @@ public void renderScanline_LargeTranslucentTexture(
texOffset += k2 & 0x600000;
colorShift = k2 >> 23;
k2 += l2;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
texOffset = (texOffset & 0x3fff) + (k2 & 0x600000);
colorShift = k2 >> 23;
k2 += l2;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
texOffset = (texOffset & 0x3fff) + (k2 & 0x600000);
colorShift = k2 >> 23;
k2 += l2;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
texOffset = (texOffset & 0x3fff) + (k2 & 0x600000);
colorShift = k2 >> 23;
k2 += l2;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset = i3;
texStart = j3;
@@ -568,27 +562,15 @@ public void renderScanline_LargeTranslucentTexture(
colorShift = k2 >> 23;
k2 += l2;
}
- pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0x3f80) + (texOffset >> 7)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
}
}
- public void renderScanline_LargeTextureWithTransparency(
- int i,
- int texOffset,
- int texStart,
- int texturePixels[],
- int l,
- int i1,
- int j1,
- int k1,
- int l1,
- int i2,
- int length,
- int pxIndex,
- int l2,
- int i3) {
+ public void renderScanline_LargeTextureWithTransparency(int i, int texOffset, int texStart, int texturePixels[],
+ int l, int i1, int j1, int k1, int l1, int i2, int length, int pxIndex, int l2, int i3) {
if (length <= 0) {
return;
@@ -788,20 +770,8 @@ public void renderScanline_LargeTextureWithTransparency(
/*
* Used for wooden floors!
*/
- public void renderScanline_SmallTexture(
- int texturePixels[],
- int texOffset,
- int texStart,
- int k,
- int l,
- int i1,
- int j1,
- int k1,
- int l1,
- int length,
- int pxIndex,
- int k2,
- int l2) {
+ public void renderScanline_SmallTexture(int texturePixels[], int texOffset, int texStart, int k, int l, int i1,
+ int j1, int k1, int l1, int length, int pxIndex, int k2, int l2) {
if (length <= 0) {
return;
@@ -912,20 +882,8 @@ public void renderScanline_SmallTexture(
}
- public void renderScanline_SmallTranslucentTexture(
- int texturePixels[],
- int texOffset,
- int texStart,
- int k,
- int l,
- int i1,
- int j1,
- int k1,
- int l1,
- int length,
- int pxIndex,
- int k2,
- int l2) {
+ public void renderScanline_SmallTranslucentTexture(int texturePixels[], int texOffset, int texStart, int k, int l,
+ int i1, int j1, int k1, int l1, int length, int pxIndex, int k2, int l2) {
if (length <= 0) {
return;
@@ -965,7 +923,8 @@ public void renderScanline_SmallTranslucentTexture(
k2 += l2;
if (i4 < 16) {
for (int k4 = 0; k4 < i4; k4++) {
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
if ((k4 & 3) == 3) {
@@ -976,78 +935,84 @@ public void renderScanline_SmallTranslucentTexture(
}
} else {
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
texOffset = (texOffset & 0xfff) + (k2 & 0xc0000);
colorShift = k2 >> 20;
k2 += l2;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
texOffset = (texOffset & 0xfff) + (k2 & 0xc0000);
colorShift = k2 >> 20;
k2 += l2;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
texOffset = (texOffset & 0xfff) + (k2 & 0xc0000);
colorShift = k2 >> 20;
k2 += l2;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
texOffset += texOffsetStride;
texStart += texStartStride;
- pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift) + (pixels[pxIndex] >> 1 & 0x7f7f7f);
+ pixels[pxIndex++] = (texturePixels[(texStart & 0xfc0) + (texOffset >> 6)] >>> colorShift)
+ + (pixels[pxIndex] >> 1 & 0x7f7f7f);
}
}
}
- public void renderScanline_SmallTextureWithTransparency(
- int texturePixels[],
- int l,
- int i1,
- int j1,
- int k1,
- int l1,
- int i2,
- int length,
- int pxIndex,
- int l2,
- int i3) {
+ public void renderScanline_SmallTextureWithTransparency(int texturePixels[], int l, int i1, int j1, int k1, int l1,
+ int i2, int length, int pxIndex, int l2, int i3) {
if (length <= 0) {
return;
@@ -1215,7 +1180,8 @@ public void renderScanline_SmallTextureWithTransparency(
/*
* No idea what this is used for.
*/
- public void renderScanline_TranslucentGradient(int length, int pxIndex, int gradient[], int gradientIndex, int stride) {
+ public void renderScanline_TranslucentGradient(int length, int pxIndex, int gradient[], int gradientIndex,
+ int stride) {
if (length < 0) {
return;
diff --git a/rsc-client/src/client/Input.java b/rsc-client/src/client/Input.java
index 26c79ab..0000d90 100644
--- a/rsc-client/src/client/Input.java
+++ b/rsc-client/src/client/Input.java
@@ -27,9 +27,11 @@ public class Input implements KeyListener, MouseListener {
/**
* Consumes all input for the current frame.
*
- *
This should be called every frame after input processing. + *
+ * This should be called every frame after input processing. * - *
Synchronized because new input could be added at any time! + *
+ * Synchronized because new input could be added at any time! */ public synchronized void consume() { leftClickReleased = false; @@ -71,10 +73,12 @@ public boolean isKeyDown(int key) { //////////////////////////////////////////////////////////////////////////// @Override - public void mouseClicked(MouseEvent e) {} + public void mouseClicked(MouseEvent e) { + } @Override - public void mousePressed(MouseEvent e) {} + public void mousePressed(MouseEvent e) { + } @Override public void mouseReleased(MouseEvent e) { @@ -86,17 +90,20 @@ public void mouseReleased(MouseEvent e) { } @Override - public void mouseEntered(MouseEvent e) {} + public void mouseEntered(MouseEvent e) { + } @Override - public void mouseExited(MouseEvent e) {} + public void mouseExited(MouseEvent e) { + } //////////////////////////////////////////////////////////////////////////// // KeyListener methods //////////////////////////////////////////////////////////////////////////// @Override - public void keyTyped(KeyEvent e) {} + public void keyTyped(KeyEvent e) { + } @Override public void keyPressed(KeyEvent e) { diff --git a/rsc-client/src/client/RuneClient.java b/rsc-client/src/client/RuneClient.java index a994c99..3bb2e23 100644 --- a/rsc-client/src/client/RuneClient.java +++ b/rsc-client/src/client/RuneClient.java @@ -1,28 +1,44 @@ package client; import java.awt.Dimension; +import java.awt.Image; import java.awt.MouseInfo; import java.awt.Point; import java.awt.Toolkit; import java.awt.image.BufferedImage; - +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; +import client.game.Game; import client.loading.LoadingScreen; +import client.login.LoginScreen; +import client.net.Connection; +import client.net.Packet; /** * Class responsible for setting up and running the game. * - *
Based on GameShell.java
from other RSC sources.
+ *
+ * Based on Based on
+ * Based on The general idea is:
+ *
+ * The general idea is:
*
* This is essentially a 3d software renderer; consider porting to OpenGL.
+ *
+ * This is essentially a 3d software renderer; consider porting to OpenGL.
*
- * This class should not be aware of the game at all, and the game should
- * not be aware of what goes on inside this class.
+ *
+ * This class should not be aware of the game at all, and the game should not be
+ * aware of what goes on inside this class.
*
- * Based on
+ * Based on The index is given by the faceTag of the selected face.
+ *
+ * The index is given by the faceTag of the selected face.
*/
private int[] tileXForFace = new int[NUM_TERRAIN_FACES];
private int[] tileZForFace = new int[NUM_TERRAIN_FACES];
@@ -90,7 +91,8 @@ public class World {
/**
* Currently-loaded Sectors.
*
- * When we load sector (x, z) we end up with the following:
+ *
+ * When we load sector (x, z) we end up with the following:
*
* Based on
+ * Based on Based on
+ * Based on GameShell.java
from other RSC sources.
*
* @author Dan Bryce
*/
public class RuneClient {
- private static final int WINDOW_WIDTH = 1280;
- private static final int WINDOW_HEIGHT = 720;
+ private final Logger logger = Logger.getLogger(getClass().getName());
+
+ private static final int WINDOW_WIDTH = 512;
+ private static final int WINDOW_HEIGHT = 346;
private static final String WINDOW_TITLE = "OpenRSC";
private static final int MS_PER_FRAME = 16; // 60fps
@@ -30,8 +46,8 @@ public class RuneClient {
/**
* Flag used to tell the game to exit.
*
- * The original RSC used an exit timer instead, to give the game time to
- * finish any outstanding operations before exiting.
+ * The original RSC used an exit timer instead, to give the game time to finish
+ * any outstanding operations before exiting.
*/
private boolean exiting;
@@ -40,14 +56,31 @@ public class RuneClient {
private Canvas canvas;
private BufferedImage screenBuffer;
+ // Client states
private State state;
+ private LoadingScreen loadingScreen;
+ private LoginScreen loginScreen;
+ private Game game;
+
+ // Network
+ private Connection connection;
+ private BlockingQueuemudclient.java
from other RSC sources.
+ * mudclient.java
from other RSC sources.
*
* @author Dan Bryce
*/
public class Game extends State {
+ private final Logger logger = Logger.getLogger(getClass().getName());
+
public static final int SPAWN_SECTOR_X = 50;
public static final int SPAWN_SECTOR_Z = 51;
- private ExecutorService executor;
- private Connection connection;
-
private WorldLoader worldLoader;
private World world;
private Scene scene;
private Mob player;
private GameRenderer renderer;
- private LoadingScreen loadingScreen;
- private LoginScreen loginScreen;
// 192 = West
// 128 = North
- // 64 = East
- // 0 = South
+ // 64 = East
+ // 0 = South
private int cameraRotation = 128;
private int cameraPositionX;
private int cameraPositionZ;
private int cameraHeight = Camera.DEFAULT_HEIGHT;
- public Game(RuneClient launcher, Connection connection) {
- super(launcher);
-
- this.connection = connection;
+ // Server session
+ private String displayName;
+ private int sessionId;
+ private int privilege;
+ public Game(RuneClient launcher) {
+ super(launcher);
scene = new Scene();
world = new World(scene);
worldLoader = new WorldLoader(world);
@@ -69,8 +64,6 @@ public Game(RuneClient launcher, Connection connection) {
@Override
public void start() {
- executor = Executors.newCachedThreadPool();
- executor.execute(connection.getPacketReaderThread());
}
@Override
@@ -143,8 +136,15 @@ private void groundTileSelected(int tileX, int tileZ) {
@Override
public void tick() {
+ // Check for unexpected disconnection.
+ if (player != null && !launcher.isConnected()) {
+ logger.log(Level.WARNING, "Connection Lost!");
+ launcher.disconnect();
+ return;
+ }
- handlePackets();
+ // Client is connected.
+ // Put any network game logic below.
if (player == null) {
// Not yet logged in
@@ -152,14 +152,24 @@ public void tick() {
}
updateCamera();
+
}
- private void handlePackets() {
- for (Packet p : connection.getPacketsReceived()) {
- PacketHandler handler = PacketHandlers.get(p.id);
- if (handler != null) {
- handler.apply(p, this);
- }
+ /**
+ * Executes an incoming packet.
+ */
+ public void executePacket(Packet packet) {
+ switch (packet.getOpcode()) {
+ case 3:
+ // Read chatbox message
+ int icon = packet.getByte();
+ String message = packet.getString();
+ System.out.println("[icon-" + icon + "]" + message);
+ break;
+ default:
+ logger.log(Level.WARNING,
+ "Unhandled Packet, opcode: " + packet.getOpcode() + ", length: " + packet.getPacketLength());
+ break;
}
}
@@ -201,7 +211,15 @@ private void loadSectors() {
}
}
- public void loggedIn() {
+ /**
+ * Executed when the server accepts our login request.
+ */
+ public void loggedIn(String displayName, int sessionId, int privilege) {
+ // Get the server variables for later.
+ this.displayName = displayName;
+ this.sessionId = sessionId;
+ this.privilege = privilege;
+
// Player position is relative to the World origin
player = new Mob();
player.x = 66 * World.TILE_WIDTH;
@@ -209,12 +227,12 @@ public void loggedIn() {
worldLoader.loadSector(SPAWN_SECTOR_X, SPAWN_SECTOR_Z);
}
- public LoadingScreen getLoadingScreen() {
- return loadingScreen;
- }
-
- public LoginScreen getLoginScreen() {
- return loginScreen;
+ @Override
+ public void reset() {
+ displayName = "";
+ sessionId = -1;
+ privilege = -1;
+ player = null;
}
public Scene getScene() {
diff --git a/rsc-client/src/client/game/render/GameRenderer.java b/rsc-client/src/client/game/render/GameRenderer.java
index b6ffdbb..4fb8887 100644
--- a/rsc-client/src/client/game/render/GameRenderer.java
+++ b/rsc-client/src/client/game/render/GameRenderer.java
@@ -9,12 +9,13 @@
/**
* Class responsible for rendering the game.
*
- *
- *
*
* @author Dan Bryce
@@ -43,9 +44,7 @@ public GameRenderer(Game game) {
scene = game.getScene();
sceneBuilder = new SceneBuilder(scene, world);
- softwareRenderer = new SoftwareRenderer(scene,
- game.getLauncher().getWidth(),
- game.getLauncher().getHeight());
+ softwareRenderer = new SoftwareRenderer(scene, game.getLauncher().getWidth(), game.getLauncher().getHeight());
mousePicker = softwareRenderer.getMousePicker();
}
@@ -77,17 +76,11 @@ private void renderUi(Canvas canvas) {
}
private void renderMenus(Canvas canvas) {
- canvas.drawSprite(
- game.getLauncher().getWidth() - MENUS_OFFSET_X,
- MENUS_OFFSET_Y,
- SPRITE_ID_MENUS);
+ canvas.drawSprite(game.getLauncher().getWidth() - MENUS_OFFSET_X, MENUS_OFFSET_Y, SPRITE_ID_MENUS);
}
private void renderInventoryMenu(Canvas canvas) {
- canvas.drawSprite(
- game.getLauncher().getWidth() - INVENTORY_MENU_OFFSET_X,
- MENUS_OFFSET_Y,
- SPRITE_ID_INVENTORY);
+ canvas.drawSprite(game.getLauncher().getWidth() - INVENTORY_MENU_OFFSET_X, MENUS_OFFSET_Y, SPRITE_ID_INVENTORY);
}
}
diff --git a/rsc-client/src/client/game/render/MousePicker.java b/rsc-client/src/client/game/render/MousePicker.java
index ee05d9e..0dad076 100644
--- a/rsc-client/src/client/game/render/MousePicker.java
+++ b/rsc-client/src/client/game/render/MousePicker.java
@@ -8,9 +8,9 @@ public class MousePicker {
private int mouseX;
private int mouseY;
-
+
private int baseX;
-
+
private int mousePickedCount;
private Model mousePickedModels[] = new Model[MAX_MOUSE_PICKS];
private int mousePickedFaces[] = new int[MAX_MOUSE_PICKS];
@@ -28,19 +28,19 @@ public void add(Model gameModel, int faceId) {
public int getMousePickedCount() {
return mousePickedCount;
}
-
+
public Model[] getMousePickedModels() {
return mousePickedModels;
}
-
+
public int[] getMousePickedFaces() {
return mousePickedFaces;
}
-
+
public int getMouseX() {
return mouseX;
}
-
+
public int getMouseY() {
return mouseY;
}
diff --git a/rsc-client/src/client/game/render/SoftwareRenderer.java b/rsc-client/src/client/game/render/SoftwareRenderer.java
index 7aa34a3..a0f8c42 100644
--- a/rsc-client/src/client/game/render/SoftwareRenderer.java
+++ b/rsc-client/src/client/game/render/SoftwareRenderer.java
@@ -13,12 +13,15 @@
/**
* Class responsible for rendering a scene.
*
- * client.Scene
from EasyRSC.
+ * client.Scene
from EasyRSC.
*/
public class SoftwareRenderer {
@@ -87,11 +90,7 @@ public SoftwareRenderer(Scene scene, int width, int height) {
visiblePolygons[l] = new Polygon();
}
- setBounds(
- width / 2, height / 2,
- width / 2, height / 2,
- width,
- VIEW_DISTANCE);
+ setBounds(width / 2, height / 2, width / 2, height / 2, width, VIEW_DISTANCE);
}
public void render(Canvas canvas) {
@@ -106,8 +105,7 @@ public void render(Canvas canvas) {
scene.getModels()[i].project(camera, viewDistance, clipNear);
}
- scene.getModels()[scene.getNumModels()]
- .project(camera, viewDistance, clipNear);
+ scene.getModels()[scene.getNumModels()].project(camera, viewDistance, clipNear);
visiblePolygonCount = 0;
// Draw each model in the scene
@@ -287,7 +285,6 @@ public void render(Canvas canvas) {
}
}
-
if (polygonModel.verticesProjected[vertexIndexInModel].z >= clipNear) {
planeX[plane] = polygonModel.verticesView[vertexIndexInModel].x;
@@ -295,7 +292,8 @@ public void render(Canvas canvas) {
vertexShade[plane] = light;
if (polygonModel.verticesProjected[vertexIndexInModel].z > scene.fogZDistance) {
- vertexShade[plane] += (polygonModel.verticesProjected[vertexIndexInModel].z - scene.fogZDistance) / scene.fogZFalloff;
+ vertexShade[plane] += (polygonModel.verticesProjected[vertexIndexInModel].z
+ - scene.fogZDistance) / scene.fogZFalloff;
}
plane++;
@@ -310,12 +308,15 @@ public void render(Canvas canvas) {
}
if (polygonModel.verticesProjected[vertEnd].z >= clipNear) {
- int k7 = polygonModel.verticesProjected[vertexIndexInModel].z - polygonModel.verticesProjected[vertEnd].z;
+ int k7 = polygonModel.verticesProjected[vertexIndexInModel].z
+ - polygonModel.verticesProjected[vertEnd].z;
int i5 = polygonModel.verticesProjected[vertexIndexInModel].x
- - ((polygonModel.verticesProjected[vertexIndexInModel].x - polygonModel.verticesProjected[vertEnd].x)
+ - ((polygonModel.verticesProjected[vertexIndexInModel].x
+ - polygonModel.verticesProjected[vertEnd].x)
* (polygonModel.verticesProjected[vertexIndexInModel].z - clipNear)) / k7;
int j6 = polygonModel.verticesProjected[vertexIndexInModel].y
- - ((polygonModel.verticesProjected[vertexIndexInModel].y - polygonModel.verticesProjected[vertEnd].y)
+ - ((polygonModel.verticesProjected[vertexIndexInModel].y
+ - polygonModel.verticesProjected[vertEnd].y)
* (polygonModel.verticesProjected[vertexIndexInModel].z - clipNear)) / k7;
planeX[plane] = (i5 << viewDistance) / clipNear;
planeY[plane] = (j6 << viewDistance) / clipNear;
@@ -330,12 +331,15 @@ public void render(Canvas canvas) {
}
if (polygonModel.verticesProjected[vertEnd].z >= clipNear) {
- int l7 = polygonModel.verticesProjected[vertexIndexInModel].z - polygonModel.verticesProjected[vertEnd].z;
+ int l7 = polygonModel.verticesProjected[vertexIndexInModel].z
+ - polygonModel.verticesProjected[vertEnd].z;
int j5 = polygonModel.verticesProjected[vertexIndexInModel].x
- - ((polygonModel.verticesProjected[vertexIndexInModel].x - polygonModel.verticesProjected[vertEnd].x)
+ - ((polygonModel.verticesProjected[vertexIndexInModel].x
+ - polygonModel.verticesProjected[vertEnd].x)
* (polygonModel.verticesProjected[vertexIndexInModel].z - clipNear)) / l7;
int k6 = polygonModel.verticesProjected[vertexIndexInModel].y
- - ((polygonModel.verticesProjected[vertexIndexInModel].y - polygonModel.verticesProjected[vertEnd].y)
+ - ((polygonModel.verticesProjected[vertexIndexInModel].y
+ - polygonModel.verticesProjected[vertEnd].y)
* (polygonModel.verticesProjected[vertexIndexInModel].z - clipNear)) / l7;
planeX[plane] = (j5 << viewDistance) / clipNear;
planeY[plane] = (k6 << viewDistance) / clipNear;
@@ -370,8 +374,7 @@ public void render(Canvas canvas) {
}
}
- private void renderSprite(Model polygonModel, int polyFace,
- Canvas canvas) {
+ private void renderSprite(Model polygonModel, int polyFace, Canvas canvas) {
SpriteEntity spriteEntity = scene.getSpriteEntities()[polyFace];
int faceverts[] = polygonModel.faceVertices[polyFace];
int face0 = faceverts[0];
@@ -515,17 +518,8 @@ private boolean polygonsOrder(Polygon[] polygons, int start, int end) {
} while (true);
}
- private void generateScanlines(
- int startX,
- int endX,
- int y,
- int startS,
- int plane,
- int planeX[],
- int planeY[],
- int vertexShade[],
- Model gameModel,
- int faceId) {
+ private void generateScanlines(int startX, int endX, int y, int startS, int plane, int planeX[], int planeY[],
+ int vertexShade[], Model gameModel, int faceId) {
if (plane == 3) {
@@ -1124,16 +1118,15 @@ private void generateScanlines(
if (mouseY >= minY && mouseY < maxY) {
Scanline scanline = scanlines[mouseY];
- if (mouseX >= scanline.startX >> 8 &&
- mouseX <= scanline.endX >> 8 &&
- scanline.startX <= scanline.endX &&
- !gameModel.unpickable) {
+ if (mouseX >= scanline.startX >> 8 && mouseX <= scanline.endX >> 8 && scanline.startX <= scanline.endX
+ && !gameModel.unpickable) {
mousePicker.add(gameModel, faceId);
}
}
}
- private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[], int vertexZ[], int textureId, Model gameModel) {
+ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[], int vertexZ[], int textureId,
+ Model gameModel) {
if (textureId == -2) {
// Transparent
@@ -1211,20 +1204,9 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
int l17 = clipX;
k20 = l17 - scanlineStartX;
}
- canvas.renderScanline_LargeTranslucentTexture(
- tex.pixels,
- 0,
- 0,
- l9 + k14 * scanlineStartX,
- k11 + i15 * scanlineStartX,
- i13 + k15 * scanlineStartX,
- k10,
- i12,
- k13,
- k20,
- i17 + scanlineStartX,
- i22,
- k23 << 2);
+ canvas.renderScanline_LargeTranslucentTexture(tex.pixels, 0, 0, l9 + k14 * scanlineStartX,
+ k11 + i15 * scanlineStartX, i13 + k15 * scanlineStartX, k10, i12, k13, k20,
+ i17 + scanlineStartX, i22, k23 << 2);
l9 += i11;
k11 += k12;
i13 += i14;
@@ -1262,20 +1244,9 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
int j18 = clipX;
l20 = j18 - scanlineStartX;
}
- canvas.renderScanline_LargeTexture(
- tex.pixels,
- 0,
- 0,
- l9 + k14 * scanlineStartX,
- k11 + i15 * scanlineStartX,
- i13 + k15 * scanlineStartX,
- k10,
- i12,
- k13,
- l20,
- i17 + scanlineStartX,
- j22,
- l23 << 2);
+ canvas.renderScanline_LargeTexture(tex.pixels, 0, 0, l9 + k14 * scanlineStartX,
+ k11 + i15 * scanlineStartX, i13 + k15 * scanlineStartX, k10, i12, k13, l20,
+ i17 + scanlineStartX, j22, l23 << 2);
l9 += i11;
k11 += k12;
i13 += i14;
@@ -1312,21 +1283,9 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
int l18 = clipX;
i21 = l18 - scanlineStartX;
}
- canvas.renderScanline_LargeTextureWithTransparency(
- 0,
- 0,
- 0,
- tex.pixels,
- l9 + k14 * scanlineStartX,
- k11 + i15 * scanlineStartX,
- i13 + k15 * scanlineStartX,
- k10,
- i12,
- k13,
- i21,
- i17 + scanlineStartX,
- k22,
- i24);
+ canvas.renderScanline_LargeTextureWithTransparency(0, 0, 0, tex.pixels,
+ l9 + k14 * scanlineStartX, k11 + i15 * scanlineStartX, i13 + k15 * scanlineStartX, k10,
+ i12, k13, i21, i17 + scanlineStartX, k22, i24);
l9 += i11;
k11 += k12;
i13 += i14;
@@ -1387,20 +1346,9 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
int j19 = clipX;
j21 = j19 - scanlineStartX;
}
- canvas.renderScanline_SmallTranslucentTexture(
- tex.pixels,
- 0,
- 0,
- i10 + l14 * scanlineStartX,
- l11 + j15 * scanlineStartX,
- j13 + l15 * scanlineStartX,
- l10,
- j12,
- l13,
- j21,
- j17 + scanlineStartX,
- l22,
- j24);
+ canvas.renderScanline_SmallTranslucentTexture(tex.pixels, 0, 0, i10 + l14 * scanlineStartX,
+ l11 + j15 * scanlineStartX, j13 + l15 * scanlineStartX, l10, j12, l13, j21,
+ j17 + scanlineStartX, l22, j24);
i10 += j11;
l11 += l12;
j13 += j14;
@@ -1441,20 +1389,9 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
k21 = l19 - scanlineStartX;
}
- canvas.renderScanline_SmallTexture(
- tex.pixels,
- 0,
- 0,
- i10 + l14 * scanlineStartX,
- l11 + j15 * scanlineStartX,
- j13 + l15 * scanlineStartX,
- l10,
- j12,
- l13,
- k21,
- j17 + scanlineStartX,
- i23,
- k24);
+ canvas.renderScanline_SmallTexture(tex.pixels, 0, 0, i10 + l14 * scanlineStartX,
+ l11 + j15 * scanlineStartX, j13 + l15 * scanlineStartX, l10, j12, l13, k21,
+ j17 + scanlineStartX, i23, k24);
i10 += j11;
l11 += l12;
@@ -1490,18 +1427,9 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
int j20 = clipX;
l21 = j20 - scanlineStartX;
}
- canvas.renderScanline_SmallTextureWithTransparency(
- tex.pixels,
- i10 + l14 * scanlineStartX,
- l11 + j15 * scanlineStartX,
- j13 + l15 * scanlineStartX,
- l10,
- j12,
- l13,
- l21,
- j17 + scanlineStartX,
- j23,
- l24);
+ canvas.renderScanline_SmallTextureWithTransparency(tex.pixels, i10 + l14 * scanlineStartX,
+ l11 + j15 * scanlineStartX, j13 + l15 * scanlineStartX, l10, j12, l13, l21,
+ j17 + scanlineStartX, j23, l24);
i10 += j11;
l11 += l12;
j13 += j14;
@@ -1559,12 +1487,8 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
if (k4 > clipX) {
length = clipX - scanlineStartX;
}
- canvas.renderScanline_TranslucentGradient(
- length,
- rowStart + scanlineStartX,
- currentGradientRamps,
- gradientIndex,
- stride * 4);
+ canvas.renderScanline_TranslucentGradient(length, rowStart + scanlineStartX, currentGradientRamps,
+ gradientIndex, stride * 4);
rowStart += width;
}
}
@@ -1592,11 +1516,7 @@ private void rasterize(Canvas canvas, int numFaces, int vertexX[], int vertexY[]
length = l5 - scanlineStartX;
}
- canvas.renderScanline_Gradient(
- length,
- rowStart + scanlineStartX,
- currentGradientRamps,
- gradientIndex,
+ canvas.renderScanline_Gradient(length, rowStart + scanlineStartX, currentGradientRamps, gradientIndex,
stride * 4);
rowStart += width;
@@ -1632,7 +1552,8 @@ private void initialisePolygon3d(int i) {
}
gameModel.faceCameraNormalScale[face] = faceCameraNormalScale;
- gameModel.faceCameraNormalMagnitude[face] = (int) (normalMagnitude * Math.sqrt(k3 * k3 + l3 * l3 + i4 * i4));
+ gameModel.faceCameraNormalMagnitude[face] = (int) (normalMagnitude
+ * Math.sqrt(k3 * k3 + l3 * l3 + i4 * i4));
} else {
k3 >>= faceCameraNormalScale;
l3 >>= faceCameraNormalScale;
diff --git a/rsc-client/src/client/game/scene/Model.java b/rsc-client/src/client/game/scene/Model.java
index 24147ea..24f34e1 100644
--- a/rsc-client/src/client/game/scene/Model.java
+++ b/rsc-client/src/client/game/scene/Model.java
@@ -21,9 +21,7 @@ public class Model {
private static final int DEFAULT_SCALE = 256;
public enum TransformState {
- CLEAN,
- PENDING,
- BILLBOARD
+ CLEAN, PENDING, BILLBOARD
}
private static int sine9[] = new int[512];
@@ -276,8 +274,7 @@ public Model(String path) {
}
/**
- * Copies the Model at the given index of the given array, and sets some
- * flags.
+ * Copies the Model at the given index of the given array, and sets some flags.
*
* @param models
* @param i
@@ -325,13 +322,7 @@ public Model(int maxVertices, int maxFaces) {
* @param unpickable
* @param projected
*/
- public Model(
- int maxVertices,
- int maxFaces,
- boolean autoCommit,
- boolean isolated,
- boolean unlit,
- boolean unpickable,
+ public Model(int maxVertices, int maxFaces, boolean autoCommit, boolean isolated, boolean unlit, boolean unpickable,
boolean projected) {
this.autoCommit = autoCommit;
this.isolated = isolated;
@@ -448,16 +439,11 @@ public void merge(Model models[], int numModels) {
int vertices[] = gameModel.faceVertices[faceId];
for (int vertId = 0; vertId < gameModel.numVerticesPerFace[faceId]; vertId++) {
- faces[vertId] = addUniqueVertex(
- gameModel.vertices[vertices[vertId]].x,
- gameModel.vertices[vertices[vertId]].y,
- gameModel.vertices[vertices[vertId]].z);
+ faces[vertId] = addUniqueVertex(gameModel.vertices[vertices[vertId]].x,
+ gameModel.vertices[vertices[vertId]].y, gameModel.vertices[vertices[vertId]].z);
}
- int faceIndex = addFace(
- gameModel.numVerticesPerFace[faceId],
- faces,
- gameModel.faceFillFront[faceId],
+ int faceIndex = addFace(gameModel.numVerticesPerFace[faceId], faces, gameModel.faceFillFront[faceId],
gameModel.faceFillBack[faceId]);
faceIntensity[faceIndex] = gameModel.faceIntensity[faceId];
@@ -561,10 +547,7 @@ public Model[] split(int pieceDx, int pieceDz, int rows, int count, int maxVerti
if (numVerticesInPiece[i] > maxVertices) {
numVerticesInPiece[i] = maxVertices;
}
- models[i] = new Model(
- numVerticesInPiece[i],
- numFacesInPiece[i],
- true, true, true, unpickable, true);
+ models[i] = new Model(numVerticesInPiece[i], numFacesInPiece[i], true, true, true, unpickable, true);
models[i].lightDiffuse = lightDiffuse;
models[i].lightAmbience = lightAmbience;
}
@@ -590,17 +573,11 @@ public Model[] split(int pieceDx, int pieceDz, int rows, int count, int maxVerti
return models;
}
- public void copyModelData(
- Model gameModel,
- int srcVertices[],
- int count,
- int faceId) {
+ public void copyModelData(Model gameModel, int srcVertices[], int count, int faceId) {
int destVertices[] = new int[count];
for (int i = 0; i < count; i++) {
- int l = destVertices[i] = gameModel.addUniqueVertex(
- vertices[srcVertices[i]].x,
- vertices[srcVertices[i]].y,
+ int l = destVertices[i] = gameModel.addUniqueVertex(vertices[srcVertices[i]].x, vertices[srcVertices[i]].y,
vertices[srcVertices[i]].z);
gameModel.vertexIntensity[l] = vertexIntensity[srcVertices[i]];
gameModel.vertexAmbience[l] = vertexAmbience[srcVertices[i]];
@@ -615,12 +592,7 @@ public void copyModelData(
gameModel.faceCameraNormalMagnitude[nextIndex] = faceCameraNormalMagnitude[faceId];
}
- public void setLighting(
- boolean useGouraud,
- int ambient,
- int diffuse,
- int lightDirectionX,
- int lightDirectionY,
+ public void setLighting(boolean useGouraud, int ambient, int diffuse, int lightDirectionX, int lightDirectionY,
int lightDirectionZ) {
lightAmbience = 256 - ambient * 4;
@@ -644,12 +616,7 @@ public void setLighting(
light();
}
- public void setLighting(
- int ambient,
- int diffuse,
- int lightDirectionX,
- int lightDirectionY,
- int lightDirectionZ) {
+ public void setLighting(int ambient, int diffuse, int lightDirectionX, int lightDirectionY, int lightDirectionZ) {
lightAmbience = 256 - ambient * 4;
lightDiffuse = (64 - diffuse) * 16 + 128;
@@ -664,10 +631,7 @@ public void setLighting(
light();
}
- public void setLighting(
- int lightDirectionX,
- int lightDirectionY,
- int lightDirectionZ) {
+ public void setLighting(int lightDirectionX, int lightDirectionY, int lightDirectionZ) {
if (unlit) {
return;
@@ -708,8 +672,7 @@ public void setTranslate(int translateX, int translateY, int translateZ) {
}
private void determineTransformType() {
- if (shearXY != 256 || shearXZ != 256 || shearYX != 256 || shearYZ != 256
- || shearZX != 256 || shearZY != 256) {
+ if (shearXY != 256 || shearXZ != 256 || shearYX != 256 || shearYZ != 256 || shearZX != 256 || shearZY != 256) {
transformType = 4;
return;
}
@@ -765,13 +728,7 @@ private void applyRotation(int rotX, int rotY, int rotZ) {
}
- private void applyShear(
- int xy,
- int xz,
- int yx,
- int yz,
- int zx,
- int zy) {
+ private void applyShear(int xy, int xz, int yx, int yz, int zx, int zy) {
for (int i = 0; i < numVertices; i++) {
if (xy != 0) {
verticesTransformed[i].x += verticesTransformed[i].y * xy >> 8;
@@ -880,9 +837,7 @@ public void light() {
int i = lightDiffuse * VectorUtils.magnitude(lightDirection) >> 8;
for (int j = 0; j < numFaces; j++) {
if (faceIntensity[j] != USE_GOURAUD_LIGHTING) {
- faceIntensity[j] =
- (faceNormals[j].x * lightDirection.x
- + faceNormals[j].y * lightDirection.y
+ faceIntensity[j] = (faceNormals[j].x * lightDirection.x + faceNormals[j].y * lightDirection.y
+ faceNormals[j].z * lightDirection.z) / i;
}
}
@@ -913,11 +868,8 @@ public void light() {
for (int j1 = 0; j1 < numVertices; j1++) {
if (normalMagnitude[j1] > 0) {
- vertexIntensity[j1] =
- (normalX[j1] * lightDirection.x
- + normalY[j1] * lightDirection.y
- + normalZ[j1] * lightDirection.z)
- / (i * normalMagnitude[j1]);
+ vertexIntensity[j1] = (normalX[j1] * lightDirection.x + normalY[j1] * lightDirection.y
+ + normalZ[j1] * lightDirection.z) / (i * normalMagnitude[j1]);
}
}
}
@@ -945,21 +897,13 @@ public void relight() {
int normalY = (bZ * cX) - (cZ * bX);
int normalZ;
- for (normalZ = bX * cY - cX * bY;
- normalX > 8192
- || normalY > 8192
- || normalZ > 8192
- || normalX < -8192
- || normalY < -8192
- || normalZ < -8192; normalZ >>= 1) {
+ for (normalZ = bX * cY - cX * bY; normalX > 8192 || normalY > 8192 || normalZ > 8192 || normalX < -8192
+ || normalY < -8192 || normalZ < -8192; normalZ >>= 1) {
normalX >>= 1;
normalY >>= 1;
}
- int normalMagnitude = (int) (256D * Math.sqrt(
- normalX * normalX
- + normalY * normalY
- + normalZ * normalZ));
+ int normalMagnitude = (int) (256D * Math.sqrt(normalX * normalX + normalY * normalY + normalZ * normalZ));
if (normalMagnitude <= 0) {
normalMagnitude = 1;
}
@@ -996,8 +940,7 @@ private void applyTransform() {
scale(scale.x, scale.y, scale.z);
}
if (transformType >= 4) {
- applyShear(
- shearXY, shearXZ, shearYX, shearYZ, shearZX, shearZY);
+ applyShear(shearXY, shearXZ, shearYX, shearYZ, shearZX, shearZY);
}
if (transformType >= 1) {
applyTranslate(translate.x, translate.y, translate.z);
@@ -1009,12 +952,8 @@ private void applyTransform() {
public void project(Camera camera, int viewDistance, int clipNear) {
applyTransform();
- if (z1 > camera.getFrustumNearZ() ||
- z2 < camera.getFrustumFarZ() ||
- x1 > camera.getFrustumMinX() ||
- x2 < camera.getFrustumMaxX() ||
- y1 > camera.getFrustumMaxY() ||
- y2 < camera.getFrustumMinY()) {
+ if (z1 > camera.getFrustumNearZ() || z2 < camera.getFrustumFarZ() || x1 > camera.getFrustumMinX()
+ || x2 < camera.getFrustumMaxX() || y1 > camera.getFrustumMaxY() || y2 < camera.getFrustumMinY()) {
visible = false;
return;
}
@@ -1093,11 +1032,7 @@ public Model copy() {
return gameModel;
}
- public Model copy(
- boolean autoCommit,
- boolean isolated,
- boolean unlit,
- boolean unpickable) {
+ public Model copy(boolean autoCommit, boolean isolated, boolean unlit, boolean unpickable) {
Model models[] = new Model[1];
models[0] = this;
Model gameModel = new Model(models, 1, autoCommit, isolated, unlit, unpickable);
diff --git a/rsc-client/src/client/game/scene/Scene.java b/rsc-client/src/client/game/scene/Scene.java
index 7d1ee5d..76d1952 100644
--- a/rsc-client/src/client/game/scene/Scene.java
+++ b/rsc-client/src/client/game/scene/Scene.java
@@ -22,18 +22,18 @@ public class Scene {
* Fog "density".
*/
public int fogZFalloff = 1;
-
+
public int fogZDistance = 2100 + (Camera.DEFAULT_HEIGHT * 2);
-
+
public Scene() {
for (int l = 0; l < spriteEntities.length; l++) {
spriteEntities[l] = new SpriteEntity();
}
sprites = new Model(MAX_SPRITES * 2, MAX_SPRITES);
camera = new Camera();
-
+
camera.set(0, 0, 0, 912, 0, 0, 2000);
-
+
setLight(-50, -10, -50);
}
@@ -83,13 +83,8 @@ public void reduceSprites(int i) {
public int addSpriteEntity(SpriteEntity spriteEntity, int tag) {
spriteEntities[numSprites] = spriteEntity;
- int v1 = sprites.addVertex(
- spriteEntity.getX(),
- spriteEntity.getY(),
- spriteEntity.getZ());
- int v2 = sprites.addVertex(
- spriteEntity.getX(),
- spriteEntity.getZ() - spriteEntity.getHeight(),
+ int v1 = sprites.addVertex(spriteEntity.getX(), spriteEntity.getY(), spriteEntity.getZ());
+ int v2 = sprites.addVertex(spriteEntity.getX(), spriteEntity.getZ() - spriteEntity.getHeight(),
spriteEntity.getY());
int vertices[] = { v1, v2 };
sprites.addFace(2, vertices, 0, 0);
@@ -121,19 +116,19 @@ public void setLight(int i, int j, int distX, int distY, int distZ) {
public Model getSprites() {
return sprites;
}
-
+
public Camera getCamera() {
return camera;
}
-
+
public int getNumModels() {
return numModels;
}
-
+
public Model[] getModels() {
return models;
}
-
+
public SpriteEntity[] getSpriteEntities() {
return spriteEntities;
}
diff --git a/rsc-client/src/client/game/scene/SpriteEntity.java b/rsc-client/src/client/game/scene/SpriteEntity.java
index b508cb9..31f8bf2 100644
--- a/rsc-client/src/client/game/scene/SpriteEntity.java
+++ b/rsc-client/src/client/game/scene/SpriteEntity.java
@@ -14,19 +14,19 @@ public class SpriteEntity {
private int width;
private int height;
private int translateX;
-
+
public int getId() {
return id;
}
-
+
public int getX() {
return x;
}
-
+
public int getY() {
return y;
}
-
+
public int getZ() {
return z;
}
@@ -34,13 +34,13 @@ public int getZ() {
public int getWidth() {
return width;
}
-
+
public int getHeight() {
return height;
}
-
+
public int getTranslateX() {
return translateX;
}
-
+
}
diff --git a/rsc-client/src/client/game/world/Door.java b/rsc-client/src/client/game/world/Door.java
index 037ec3d..44abf8d 100644
--- a/rsc-client/src/client/game/world/Door.java
+++ b/rsc-client/src/client/game/world/Door.java
@@ -6,7 +6,7 @@
public class Door {
private World world;
-
+
private int x;
private int z;
private int orientation;
@@ -19,7 +19,7 @@ public Door(World world, int x, int z, int orientation, int id, int entityId) {
this.z = z;
this.orientation = orientation;
this.id = id;
-
+
model = ModelUtils.createDoor(this, world, entityId);
}
@@ -28,23 +28,23 @@ public void move(int dx, int dz) {
z += dz;
model = ModelUtils.createDoor(this, world, model.entityId);
}
-
+
public int getX() {
return x;
}
-
+
public int getZ() {
return z;
}
-
+
public int getOrientation() {
return orientation;
}
-
+
public int getId() {
return id;
}
-
+
public Model getModel() {
return model;
}
diff --git a/rsc-client/src/client/game/world/GameObject.java b/rsc-client/src/client/game/world/GameObject.java
index 1c57279..98c330e 100644
--- a/rsc-client/src/client/game/world/GameObject.java
+++ b/rsc-client/src/client/game/world/GameObject.java
@@ -6,13 +6,13 @@
public class GameObject {
private World world;
-
+
private int x;
private int z;
private int type;
private int id;
private Model model;
-
+
public GameObject(World world, int x, int z, int type, int id) {
this.world = world;
this.x = x;
@@ -20,23 +20,23 @@ public GameObject(World world, int x, int z, int type, int id) {
this.type = type;
this.id = id;
}
-
+
public int getX() {
return x;
}
-
+
public int getZ() {
return z;
}
-
+
public int getType() {
return type;
}
-
+
public int getId() {
return id;
}
-
+
public Model getModel() {
return model;
}
@@ -45,10 +45,10 @@ public void move(int dx, int dz) {
x += dx;
z += dz;
-
+
int width;
int height;
-
+
if (id == 0 || id == 4) {
// Special case objects have width and height swapped?
width = Resources.getObjectDef(type).getWidth();
@@ -57,19 +57,19 @@ public void move(int dx, int dz) {
height = Resources.getObjectDef(type).getWidth();
width = Resources.getObjectDef(type).getHeight();
}
-
+
int tileX = ((x + x + width) * World.TILE_WIDTH) / 2;
int tileZ = ((z + z + height) * World.TILE_DEPTH) / 2;
-
+
// Add new models
if (world.containsTileRelativeToOrigin(x, z)) {
model.setTranslate(tileX, -world.getAveragedElevation(tileX, tileZ), tileZ);
-
+
if (type == 74) {
// Special case object needs to be higher?
model.translate(0, -480, 0);
}
}
}
-
+
}
diff --git a/rsc-client/src/client/game/world/World.java b/rsc-client/src/client/game/world/World.java
index 4d93e42..0ff4641 100644
--- a/rsc-client/src/client/game/world/World.java
+++ b/rsc-client/src/client/game/world/World.java
@@ -82,7 +82,8 @@ public class World {
/**
* Tile position corresponding to a given face of the terrain model.
*
- *
* sectors[0] = (x - 1, z - 1)
@@ -209,8 +211,7 @@ public int getAveragedElevation(int tileX, int tileZ) {
int i1 = tileX & 0x7f;
int j1 = tileZ & 0x7f;
- if (x < 0 || z < 0 ||
- x >= World.NUM_TILES_X - 1 || z >= World.NUM_TILES_Z - 1) {
+ if (x < 0 || z < 0 || x >= World.NUM_TILES_X - 1 || z >= World.NUM_TILES_Z - 1) {
return 0;
}
@@ -347,13 +348,11 @@ public int getOriginZ() {
}
public boolean containsTile(int tileX, int tileZ) {
- return tileX > mapBoundaryX1 && tileX < mapBoundaryX2 &&
- tileZ > mapBoundaryZ1 && tileZ < mapBoundaryZ2;
+ return tileX > mapBoundaryX1 && tileX < mapBoundaryX2 && tileZ > mapBoundaryZ1 && tileZ < mapBoundaryZ2;
}
public boolean containsTileRelativeToOrigin(int tileX, int tileZ) {
- return tileX >= 0 && tileZ >= 0 &&
- tileX < NUM_TILES_X && tileZ < NUM_TILES_Z;
+ return tileX >= 0 && tileZ >= 0 && tileX < NUM_TILES_X && tileZ < NUM_TILES_Z;
}
public int getNumDoors() {
diff --git a/rsc-client/src/client/game/world/WorldLoader.java b/rsc-client/src/client/game/world/WorldLoader.java
index c13a8f9..e902075 100644
--- a/rsc-client/src/client/game/world/WorldLoader.java
+++ b/rsc-client/src/client/game/world/WorldLoader.java
@@ -17,14 +17,8 @@ public class WorldLoader {
/**
* Model used when loading sectors.
*/
- private Model tmpModel = new Model(
- World.NUM_TERRAIN_FACES + 256,
- World.NUM_TERRAIN_FACES + 256,
- true,
- true,
- false,
- false,
- true);
+ private Model tmpModel = new Model(World.NUM_TERRAIN_FACES + 256, World.NUM_TERRAIN_FACES + 256, true, true, false,
+ false, true);
/**
* Ground colour palette.
@@ -50,28 +44,16 @@ public class WorldLoader {
for (int i = 0; i < 64; i++) {
// Pale Grass / Snow
- GROUND_COLOURS[i] = DataUtils.rgbToInt(
- 255 - i * 4,
- 255 - (int) (i * 1.75),
- 255 - i * 4);
+ GROUND_COLOURS[i] = DataUtils.rgbToInt(255 - i * 4, 255 - (int) (i * 1.75), 255 - i * 4);
// Grass
- GROUND_COLOURS[i + 64] = DataUtils.rgbToInt(
- i * 3,
- 144,
- 0);
+ GROUND_COLOURS[i + 64] = DataUtils.rgbToInt(i * 3, 144, 0);
// Sand
- GROUND_COLOURS[i + 128] = DataUtils.rgbToInt(
- 192 - (int) (i * 1.5),
- 144 - (int) (i * 1.5),
- 0);
+ GROUND_COLOURS[i + 128] = DataUtils.rgbToInt(192 - (int) (i * 1.5), 144 - (int) (i * 1.5), 0);
// Dark Grass / Mud
- GROUND_COLOURS[i + 192] = DataUtils.rgbToInt(
- 96 - (int) (i * 1.5),
- 48 + (int) (i * 1.5),
- 0);
+ GROUND_COLOURS[i + 192] = DataUtils.rgbToInt(96 - (int) (i * 1.5), 48 + (int) (i * 1.5), 0);
}
}
@@ -138,8 +120,7 @@ public void loadSector(int sectorX, int sectorZ) {
*/
private void loadRequiredLayers(int sectorX, int sectorZ, int currentLayer) {
- System.out.println("Loading sector: " + sectorX + ", " + sectorZ +
- " (" + currentLayer + ")");
+ System.out.println("Loading sector: " + sectorX + ", " + sectorZ + " (" + currentLayer + ")");
loadLayer(sectorX, sectorZ, currentLayer, true);
@@ -181,24 +162,22 @@ private void loadLayer(int sectorX, int sectorZ, int layer, boolean isCurrentLay
int elevation = -world.getGroundElevation(x, z);
// Flatten water under bridges
- if (world.getGroundTextureOverlay(x, z) > 0
- && Resources.getTileDef(world.getGroundTextureOverlay(x, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ if (world.getGroundTextureOverlay(x, z) > 0 && Resources
+ .getTileDef(world.getGroundTextureOverlay(x, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
elevation = 0;
- } else if (world.getGroundTextureOverlay(x - 1, z) > 0
- && Resources.getTileDef(world.getGroundTextureOverlay(x - 1, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ } else if (world.getGroundTextureOverlay(x - 1, z) > 0 && Resources
+ .getTileDef(world.getGroundTextureOverlay(x - 1, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
elevation = 0;
- } else if (world.getGroundTextureOverlay(x, z - 1) > 0
- && Resources.getTileDef(world.getGroundTextureOverlay(x, z - 1) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ } else if (world.getGroundTextureOverlay(x, z - 1) > 0 && Resources
+ .getTileDef(world.getGroundTextureOverlay(x, z - 1) - 1).getType() == TileDef.TYPE_BRIDGE) {
elevation = 0;
- } else if (world.getGroundTextureOverlay(x - 1, z - 1) > 0 &&
- Resources.getTileDef(world.getGroundTextureOverlay(x - 1, z - 1) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ } else if (world.getGroundTextureOverlay(x - 1, z - 1) > 0
+ && Resources.getTileDef(world.getGroundTextureOverlay(x - 1, z - 1) - 1)
+ .getType() == TileDef.TYPE_BRIDGE) {
elevation = 0;
}
- int vertexId = tmpModel.addUniqueVertex(
- x * World.TILE_WIDTH,
- elevation,
- z * World.TILE_DEPTH);
+ int vertexId = tmpModel.addUniqueVertex(x * World.TILE_WIDTH, elevation, z * World.TILE_DEPTH);
// Randomise vertex ambience
int ambience = (int) (Math.random() * 10D) - 5;
@@ -262,7 +241,7 @@ && getOverlayIfRequired(x, z + 1, groundColour2) != 0xbc614e) {
}
}
- // Create smooth diagonal lines for road / water edges, etc.
+ // Create smooth diagonal lines for road / water edges, etc.
} else if (tileType1 != 2 || getDiagonalWalls(x, z) > 0 && getDiagonalWalls(x, z) < 24000) {
if (getTileType(x - 1, z) != tileType2 && getTileType(x, z - 1) != tileType2) {
groundColour = groundColour2;
@@ -337,8 +316,8 @@ && getOverlayIfRequired(x, z + 1, groundColour2) != 0xbc614e) {
for (int x = 1; x < World.NUM_TILES_X - 1; x++) {
for (int z = 1; z < World.NUM_TILES_Z - 1; z++) {
- if (world.getGroundTextureOverlay(x, z) > 0
- && Resources.getTileDef(world.getGroundTextureOverlay(x, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ if (world.getGroundTextureOverlay(x, z) > 0 && Resources
+ .getTileDef(world.getGroundTextureOverlay(x, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
int l7 = Resources.getTileDef(world.getGroundTextureOverlay(x, z) - 1).getColour();
int j10 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z), z * 128);
int l12 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z), z * 128);
@@ -352,56 +331,68 @@ && getOverlayIfRequired(x, z + 1, groundColour2) != 0xbc614e) {
} else if (world.getGroundTextureOverlay(x, z) == 0
|| Resources.getTileDef(world.getGroundTextureOverlay(x, z) - 1).getType() != 3) {
- if (world.getGroundTextureOverlay(x, z + 1) > 0 && Resources
- .getTileDef(world.getGroundTextureOverlay(x, z + 1) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ if (world.getGroundTextureOverlay(x, z + 1) > 0
+ && Resources.getTileDef(world.getGroundTextureOverlay(x, z + 1) - 1)
+ .getType() == TileDef.TYPE_BRIDGE) {
int i8 = Resources.getTileDef(world.getGroundTextureOverlay(x, z + 1) - 1).getColour();
int k10 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z), z * 128);
- int i13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z), z * 128);
+ int i13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z),
+ z * 128);
int j15 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z + 1),
(z + 1) * 128);
- int k17 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1), (z + 1) * 128);
+ int k17 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1),
+ (z + 1) * 128);
int ai3[] = { k10, i13, j15, k17 };
int j20 = tmpModel.addFace(4, ai3, i8, 0xbc614e);
world.setTilePosForFace(j20, x, z);
tmpModel.faceTag[j20] = 0x30d40 + j20;
}
- if (world.getGroundTextureOverlay(x, z - 1) > 0 && Resources
- .getTileDef(world.getGroundTextureOverlay(x, z - 1) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ if (world.getGroundTextureOverlay(x, z - 1) > 0
+ && Resources.getTileDef(world.getGroundTextureOverlay(x, z - 1) - 1)
+ .getType() == TileDef.TYPE_BRIDGE) {
int j8 = Resources.getTileDef(world.getGroundTextureOverlay(x, z - 1) - 1).getColour();
int l10 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z), z * 128);
- int j13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z), z * 128);
+ int j13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z),
+ z * 128);
int k15 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z + 1),
(z + 1) * 128);
- int l17 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1), (z + 1) * 128);
+ int l17 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1),
+ (z + 1) * 128);
int ai4[] = { l10, j13, k15, l17 };
int k20 = tmpModel.addFace(4, ai4, j8, 0xbc614e);
world.setTilePosForFace(k20, x, z);
tmpModel.faceTag[k20] = 0x30d40 + k20;
}
- if (world.getGroundTextureOverlay(x + 1, z) > 0 && Resources
- .getTileDef(world.getGroundTextureOverlay(x + 1, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ if (world.getGroundTextureOverlay(x + 1, z) > 0
+ && Resources.getTileDef(world.getGroundTextureOverlay(x + 1, z) - 1)
+ .getType() == TileDef.TYPE_BRIDGE) {
int k8 = Resources.getTileDef(world.getGroundTextureOverlay(x + 1, z) - 1).getColour();
int i11 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z), z * 128);
- int k13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z), z * 128);
+ int k13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z),
+ z * 128);
int l15 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z + 1),
(z + 1) * 128);
- int i18 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1), (z + 1) * 128);
+ int i18 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1),
+ (z + 1) * 128);
int ai5[] = { i11, k13, l15, i18 };
int l20 = tmpModel.addFace(4, ai5, k8, 0xbc614e);
world.setTilePosForFace(l20, x, z);
tmpModel.faceTag[l20] = 0x30d40 + l20;
}
- if (world.getGroundTextureOverlay(x - 1, z) > 0 && Resources
- .getTileDef(world.getGroundTextureOverlay(x - 1, z) - 1).getType() == TileDef.TYPE_BRIDGE) {
+ if (world.getGroundTextureOverlay(x - 1, z) > 0
+ && Resources.getTileDef(world.getGroundTextureOverlay(x - 1, z) - 1)
+ .getType() == TileDef.TYPE_BRIDGE) {
int l8 = Resources.getTileDef(world.getGroundTextureOverlay(x - 1, z) - 1).getColour();
int j11 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z), z * 128);
- int l13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z), z * 128);
+ int l13 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z),
+ z * 128);
int i16 = tmpModel.addUniqueVertex((x + 1) * 128, -world.getGroundElevation(x + 1, z + 1),
(z + 1) * 128);
- int j18 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1), (z + 1) * 128);
+ int j18 = tmpModel.addUniqueVertex(x * 128, -world.getGroundElevation(x, z + 1),
+ (z + 1) * 128);
int ai6[] = { j11, l13, i16, j18 };
int i21 = tmpModel.addFace(4, ai6, l8, 0xbc614e);
world.setTilePosForFace(i21, x, z);
@@ -521,26 +512,22 @@ && getOverlayIfRequired(x, z + 1, groundColour2) != 0xbc614e) {
if (j24 < 0x13880) {
world.setElevation(l11, i14, l23);
} else {
- world.setElevation(l11, i14,
- world.getElevation(l11, i14) - 0x13880);
+ world.setElevation(l11, i14, world.getElevation(l11, i14) - 0x13880);
}
if (l24 < 0x13880) {
world.setElevation(j16, k18, l23);
} else {
- world.setElevation(j16, k18,
- world.getElevation(j16, k18) - 0x13880);
+ world.setElevation(j16, k18, world.getElevation(j16, k18) - 0x13880);
}
if (j25 < 0x13880) {
world.setElevation(j19, j21, l23);
} else {
- world.setElevation(j19, j21,
- world.getElevation(j19, j21) - 0x13880);
+ world.setElevation(j19, j21, world.getElevation(j19, j21) - 0x13880);
}
if (l25 < 0x13880) {
world.setElevation(l22, j23, l23);
} else {
- world.setElevation(l22, j23,
- world.getElevation(l22, j23) - 0x13880);
+ world.setElevation(l22, j23, world.getElevation(l22, j23) - 0x13880);
}
}
}
@@ -861,28 +848,22 @@ private int getOverlayIfRequired(int x, int z, int underlay) {
}
private boolean isCentreRoof(int x, int z) {
- return getRoofTexture(x, z) > 0 &&
- getRoofTexture(x - 1, z) > 0 &&
- getRoofTexture(x - 1, z - 1) > 0 &&
- getRoofTexture(x, z - 1) > 0;
+ return getRoofTexture(x, z) > 0 && getRoofTexture(x - 1, z) > 0 && getRoofTexture(x - 1, z - 1) > 0
+ && getRoofTexture(x, z - 1) > 0;
}
private boolean isCornerRoof(int x, int z) {
- return getRoofTexture(x, z) > 0 ||
- getRoofTexture(x - 1, z) > 0 ||
- getRoofTexture(x - 1, z - 1) > 0 ||
- getRoofTexture(x, z - 1) > 0;
+ return getRoofTexture(x, z) > 0 || getRoofTexture(x - 1, z) > 0 || getRoofTexture(x - 1, z - 1) > 0
+ || getRoofTexture(x, z - 1) > 0;
}
private void setDoorElevation(int doorIndex, int x1, int z1, int x2, int z2) {
int heightIncrement = Resources.getDoorDef(doorIndex).getHeight();
if (world.getElevation(x1, z1) < 0x13880) {
- world.setElevation(x1, z1,
- world.getElevation(x1, z1) + 0x13880 + heightIncrement);
+ world.setElevation(x1, z1, world.getElevation(x1, z1) + 0x13880 + heightIncrement);
}
if (world.getElevation(x2, z2) < 0x13880) {
- world.setElevation(x2, z2,
- world.getElevation(x2, z2) + 0x13880 + heightIncrement);
+ world.setElevation(x2, z2, world.getElevation(x2, z2) + 0x13880 + heightIncrement);
}
}
diff --git a/rsc-client/src/client/loading/LoadingScreen.java b/rsc-client/src/client/loading/LoadingScreen.java
index b974ec1..7aed9b7 100644
--- a/rsc-client/src/client/loading/LoadingScreen.java
+++ b/rsc-client/src/client/loading/LoadingScreen.java
@@ -19,7 +19,6 @@
import client.entityhandling.defs.SpellDef;
import client.entityhandling.defs.TextureDef;
import client.entityhandling.defs.TileDef;
-import client.login.LoginScreen;
import client.res.ResourceLoader;
import client.res.Resources;
import client.res.Sprite;
@@ -107,7 +106,9 @@ public void continueLoading() {
updateProgress(100, "Starting game...");
}
- launcher.changeState(new LoginScreen(launcher));
+ // Finished loading.
+ // Update the launcher state.
+ launcher.onLoaded();
}
private void generateExperienceTable() {
@@ -124,16 +125,16 @@ private void loadGameData() {
Resources.tileArchive = ResourceLoader.loadZipData(LANDSCAPE_FILENAME);
- Resources.animations = (AnimationDef[]) ResourceLoader.loadGzipData("Animations.xml.gz");
- Resources.doors = (DoorDef[]) ResourceLoader.loadGzipData("Doors.xml.gz");
- Resources.elevation = (ElevationDef[]) ResourceLoader.loadGzipData("Elevation.xml.gz");
- Resources.items = (ItemDef[]) ResourceLoader.loadGzipData("Items.xml.gz");
- Resources.npcs = (NpcDef[]) ResourceLoader.loadGzipData("NPCs.xml.gz");
- Resources.objects = (GameObjectDef[]) ResourceLoader.loadGzipData("Objects.xml.gz");
- Resources.prayers = (PrayerDef[]) ResourceLoader.loadGzipData("Prayers.xml.gz");
- Resources.spells = (SpellDef[]) ResourceLoader.loadGzipData("Spells.xml.gz");
- Resources.textureDefs = (TextureDef[]) ResourceLoader.loadGzipData("Textures.xml.gz");
- Resources.tiles = (TileDef[]) ResourceLoader.loadGzipData("Tiles.xml.gz");
+ Resources.animations = (AnimationDef[]) ResourceLoader.loadGzipData("Animations.xml.gz");
+ Resources.doors = (DoorDef[]) ResourceLoader.loadGzipData("Doors.xml.gz");
+ Resources.elevation = (ElevationDef[]) ResourceLoader.loadGzipData("Elevation.xml.gz");
+ Resources.items = (ItemDef[]) ResourceLoader.loadGzipData("Items.xml.gz");
+ Resources.npcs = (NpcDef[]) ResourceLoader.loadGzipData("NPCs.xml.gz");
+ Resources.objects = (GameObjectDef[]) ResourceLoader.loadGzipData("Objects.xml.gz");
+ Resources.prayers = (PrayerDef[]) ResourceLoader.loadGzipData("Prayers.xml.gz");
+ Resources.spells = (SpellDef[]) ResourceLoader.loadGzipData("Spells.xml.gz");
+ Resources.textureDefs = (TextureDef[]) ResourceLoader.loadGzipData("Textures.xml.gz");
+ Resources.tiles = (TileDef[]) ResourceLoader.loadGzipData("Tiles.xml.gz");
// Initialise items
for (int id = 0; id < Resources.items.length; id++) {
@@ -144,8 +145,7 @@ private void loadGameData() {
// Initialise objects
for (int id = 0; id < Resources.objects.length; id++) {
- Resources.objects[id].modelID =
- getModelIndex(Resources.objects[id].getObjectModel());
+ Resources.objects[id].modelID = getModelIndex(Resources.objects[id].getObjectModel());
}
}
@@ -205,8 +205,8 @@ public boolean loadSprite(int id, String packageName) {
System.err.println("Missing sprite: " + id);
return false;
}
- ByteBuffer data = DataUtils.streamToBuffer(new BufferedInputStream(
- Resources.spriteArchive.getInputStream(e)));
+ ByteBuffer data = DataUtils
+ .streamToBuffer(new BufferedInputStream(Resources.spriteArchive.getInputStream(e)));
Resources.sprites[id] = Sprite.deserialise(data);
return true;
} catch (Exception e) {
@@ -285,6 +285,10 @@ protected final void updateProgress(int progress, String message) {
this.message = message;
}
+ @Override
+ public void reset() {
+ }
+
public boolean isLoaded() {
return progress >= 100;
}
diff --git a/rsc-client/src/client/loading/LoadingScreenRenderer.java b/rsc-client/src/client/loading/LoadingScreenRenderer.java
index eb0688b..179e8c6 100644
--- a/rsc-client/src/client/loading/LoadingScreenRenderer.java
+++ b/rsc-client/src/client/loading/LoadingScreenRenderer.java
@@ -42,25 +42,18 @@ public void render(Canvas canvas) {
int y = canvas.getHeight() / 2 - BAR_HEIGHT / 2;
g.setColor(BAR_COLOUR);
g.drawRect(x - 2, y - 2, OUTLINE_WIDTH, OUTLINE_HEIGHT);
- g.fillRect(x, y,
- (BAR_WIDTH * loadingScreen.getProgress()) / 100,
- BAR_HEIGHT);
+ g.fillRect(x, y, (BAR_WIDTH * loadingScreen.getProgress()) / 100, BAR_HEIGHT);
// Draw loading message
g.setColor(Color.WHITE);
- drawString(g, loadingScreen.getMessage(), LOADING_FONT,
- x + BAR_WIDTH / 2,
- y + BAR_HEIGHT / 2);
+ drawString(g, loadingScreen.getMessage(), LOADING_FONT, x + BAR_WIDTH / 2, y + BAR_HEIGHT / 2);
}
- private static void drawString(Graphics g, String s,
- Font font, int x, int y) {
+ private static void drawString(Graphics g, String s, Font font, int x, int y) {
FontMetrics fontMetrics = g.getFontMetrics(font);
fontMetrics.stringWidth(s);
g.setFont(font);
- g.drawString(s,
- x - fontMetrics.stringWidth(s) / 2,
- y + fontMetrics.getHeight() / 4);
+ g.drawString(s, x - fontMetrics.stringWidth(s) / 2, y + fontMetrics.getHeight() / 4);
}
}
diff --git a/rsc-client/src/client/login/LoginScreen.java b/rsc-client/src/client/login/LoginScreen.java
index cceb5c8..7e9189e 100644
--- a/rsc-client/src/client/login/LoginScreen.java
+++ b/rsc-client/src/client/login/LoginScreen.java
@@ -1,19 +1,14 @@
package client.login;
-import java.io.IOException;
-import java.net.Socket;
+import java.util.Random;
import client.RuneClient;
import client.State;
import client.StateRenderer;
-import client.game.Game;
-import client.net.Connection;
+import client.net.Packet;
public class LoginScreen extends State {
- private static final String SERVER_ADDRESS = "localhost";
- private static final int SERVER_PORT = 7780;
-
private LoginScreenRenderer renderer;
public LoginScreen(RuneClient launcher) {
@@ -31,24 +26,41 @@ public StateRenderer getRenderer() {
public void pollInput() {
if (input.wasLeftClickReleased()) {
// For now, just connect to the server immediately
- connect(SERVER_ADDRESS, SERVER_PORT);
+
+ boolean connected = launcher.isConnected() || launcher.connect("localhost", 7780);
+ if (connected) {
+ sendLoginRequest("Player" + new Random().nextInt(1000), "topsecret");
+ }
}
}
- private void connect(String address, int port) {
+ @Override
+ public void tick() {
+ }
- Connection conn = null;
+ /**
+ * Sends a login request to the server.
+ */
+ private void sendLoginRequest(String name, String password) {
+ // Create a packet.
+ // Send the username and password.
+ Packet packet = new Packet(2);
- try {
- Socket socket = new Socket(address, port);
- conn = new Connection(socket);
- } catch (IOException e) {
- e.printStackTrace();
- }
+ // Send the client build.
+ packet.putDouble(0.1); // TODO Add client build value to code somewhere?
- if (conn != null) {
- launcher.changeState(new Game(launcher, conn));
- }
+ // Send name
+ packet.putString(name);
+
+ // Send password
+ packet.putString(password); // TODO Use RSA
+
+ // Send the packet.
+ launcher.sendPacket(packet);
+ }
+
+ @Override
+ public void reset() {
}
}
diff --git a/rsc-client/src/client/login/LoginScreenRenderer.java b/rsc-client/src/client/login/LoginScreenRenderer.java
index 3851c87..8c231de 100644
--- a/rsc-client/src/client/login/LoginScreenRenderer.java
+++ b/rsc-client/src/client/login/LoginScreenRenderer.java
@@ -26,13 +26,12 @@ public class LoginScreenRenderer extends StateRenderer {
*/
public static final int LOGO_SPRITE_WIDTH = 438;
- public LoginScreenRenderer(LoginScreen loginScreen) {}
+ public LoginScreenRenderer(LoginScreen loginScreen) {
+ }
@Override
public void render(Canvas canvas) {
- int x = canvas.getWidth() / 2
- - LOGO_SPRITE_WIDTH / 2
- - LOGO_SPRITE_OFFSET_X;
+ int x = canvas.getWidth() / 2 - LOGO_SPRITE_WIDTH / 2 - LOGO_SPRITE_OFFSET_X;
canvas.drawSprite(x, 50, SPRITE_ID_LOGO);
}
diff --git a/rsc-client/src/client/net/Connection.java b/rsc-client/src/client/net/Connection.java
index 524a2fe..c2cb148 100644
--- a/rsc-client/src/client/net/Connection.java
+++ b/rsc-client/src/client/net/Connection.java
@@ -1,66 +1,104 @@
-package client.net;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-
-import client.packets.Packet;
-
-public class Connection implements PacketListener {
-
- private Socket socket;
- private DataInputStream in;
- private DataOutputStream out;
- private PacketReaderThread packetReaderThread;
- private List
EntityHandler.java
from other RSC sources.
+ * EntityHandler.java
from other RSC sources.
*
* @author Dan Bryce
*/
@@ -102,8 +103,7 @@ public static Sector loadSector(int sectionX, int sectionY, int layer) {
}
}
} else {
- ByteBuffer data = DataUtils.streamToBuffer(
- new BufferedInputStream(tileArchive.getInputStream(e)));
+ ByteBuffer data = DataUtils.streamToBuffer(new BufferedInputStream(tileArchive.getInputStream(e)));
s = Sector.unpack(data);
}
} catch (Exception e) {
@@ -154,8 +154,8 @@ public static void prepareTexture(int id) {
/*
* Produce 3 additional versions of the texture.
*
- * These seem to be darker versions, which seem to be drawn over the
- * normal texture during rendering.
+ * These seem to be darker versions, which seem to be drawn over the normal
+ * texture during rendering.
*/
for (int i = 0; i < pixelIndex; i++) {
int colour = tex.pixels[i];
diff --git a/rsc-client/src/client/res/Texture.java b/rsc-client/src/client/res/Texture.java
index 2cf084e..586594b 100644
--- a/rsc-client/src/client/res/Texture.java
+++ b/rsc-client/src/client/res/Texture.java
@@ -13,19 +13,19 @@ public class Texture {
* Cleared after the Texture has been loaded.
*/
public byte colourData[];
-
+
/**
* List of colours used by this Texture.
*
* Cleared after the Texture has been loaded.
*/
public int palette[];
-
+
/**
* Pixel colours.
*/
public int pixels[];
-
+
/**
* Whether or not this texture contains any transparent pixels.
*/
@@ -47,11 +47,11 @@ public Texture(byte[] colourData, int[] palette, boolean large) {
public void setHasTransparency(boolean hasTransparency) {
this.hasTransparency = hasTransparency;
}
-
+
public boolean hasTransparency() {
return hasTransparency;
}
-
+
public boolean isLarge() {
return large;
}
diff --git a/rsc-client/src/client/util/DataUtils.java b/rsc-client/src/client/util/DataUtils.java
index b6fd9bd..aedb25b 100644
--- a/rsc-client/src/client/util/DataUtils.java
+++ b/rsc-client/src/client/util/DataUtils.java
@@ -16,8 +16,7 @@ public class DataUtils {
* @return
* @throws IOException
*/
- public static final ByteBuffer streamToBuffer(BufferedInputStream in)
- throws IOException {
+ public static final ByteBuffer streamToBuffer(BufferedInputStream in) throws IOException {
byte[] buffer = new byte[in.available()];
in.read(buffer, 0, buffer.length);
return ByteBuffer.wrap(buffer);
diff --git a/rsc-server/.classpath b/rsc-server/.classpath
index 0c0bd07..ae8052e 100644
--- a/rsc-server/.classpath
+++ b/rsc-server/.classpath
@@ -1,9 +1,14 @@
-
-x
,z
+ */
+ public Location(int x, int z) {
+ this.x = x;
+ this.z = z;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public void setZ(int z) {
+ this.z = z;
+ }
+
+ public void set(int x, int z) {
+ setX(x);
+ setZ(z);
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public int getZ() {
+ return z;
+ }
+
+ public int getDistance(Location location) {
+ return Math.abs(location.getX() - location.getX()) + Math.abs(location.getZ() - location.getZ());
+ }
+
+ public boolean inBounds(Location location, int distance) {
+ return getDistance(location) <= distance;
+ }
+
+}
\ No newline at end of file
diff --git a/rsc-server/src/org/openrsc/model/Mob.java b/rsc-server/src/org/openrsc/model/Mob.java
new file mode 100644
index 0000000..63c1e9c
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/Mob.java
@@ -0,0 +1,178 @@
+package org.openrsc.model;
+
+/**
+ * A dynamic mobile entity with combat attributes.
+ */
+public abstract class Mob {
+
+ /**
+ * A unique id generated for the mob's current session.
+ */
+ private final int sessionId;
+
+ /**
+ * The mob's current location.
+ */
+ private Location location;
+
+ /**
+ * The mob's last known location.
+ */
+ private Location travelBack = new Location(-1, -1);
+
+ // Combat mob
+ private Mob opponent = null;
+
+ // Number of ticks before next attack.
+ private int combatDelay = 0;
+
+ // Current health.
+ private int healthCurrent = 10;
+
+ // Maximum health.
+ private int healthMaximum = 10;
+
+ // Combat level.
+ private int combatLevel = 0;
+
+ // Create appropriate replacement variables.
+ public int currentSprite;// TODO
+ public int nextAnimation;// TODO
+ public int animationCount[] = new int[12];// TODO
+
+ // TODO A* PATH FINDER
+ public int stepCount;// TODO
+ public int movingStep;// TODO
+ public int waypointCurrent;// TODO
+ public int waypointsX[] = new int[10];// TODO
+ public int waypointsZ[] = new int[10];// TODO
+
+ public Mob(int sessionId) {
+ this(sessionId, 0, 0);
+ }
+
+ public Mob(int sessionId, int x, int z) {
+ this.sessionId = sessionId;
+ this.location = new Location(x, z);
+ this.travelBack = new Location(x, z);
+ }
+
+ /**
+ * We use this to keep the Mob's last known location.
+ */
+ public void setTravelBack() {
+ travelBack.set(getX(), getZ());
+ }
+
+ /**
+ * Executed every 600 ms.
+ */
+ public abstract void tick(long currentTime);
+
+ /**
+ * @return True, if the mob is dead.
+ */
+ public abstract boolean isDead();
+
+ public int getLastX() {
+ return travelBack.getX();
+ }
+
+ public int getLastZ() {
+ return travelBack.getZ();
+ }
+
+ /**
+ * A unique id generated for the mob's current session. This value is
+ * incremental and does not get stored.
+ */
+ public int getSessionId() {
+ return sessionId;
+ }
+
+ /**
+ * The entity's location.
+ */
+ public Location getLocation() {
+ return location;
+ }
+
+ /**
+ * The x coordinate of the entity's location.
+ */
+ public int getX() {
+ return location.getX();
+ }
+
+ /**
+ * The z coordinate of the entity's location.
+ */
+ public int getZ() {
+ return location.getZ();
+ }
+
+ /**
+ * Sets the entity's location.
+ *
+ * @param x
+ * The new x coordinate.
+ * @param z
+ * The new z coordinate.
+ */
+ public void setLocation(int x, int z) {
+ this.setTravelBack();
+ location.set(x, z);
+ }
+
+ /**
+ * Sets the entity's location.
+ *
+ * @param location
+ * The new location.
+ */
+ public void setLocation(Location location) {
+ setLocation(location.getX(), location.getZ());
+ }
+
+ public Mob getOpponent() {
+ return opponent;
+ }
+
+ public int getCombatDelay() {
+ return combatDelay;
+ }
+
+ public void setCombatDelay(int combatDelay) {
+ this.combatDelay = combatDelay;
+ }
+
+ public int getHealthCurrent() {
+ return healthCurrent;
+ }
+
+ public void setHealthCurrent(int healthCurrent) {
+ this.healthCurrent = healthCurrent;
+ }
+
+ public int getHealthMaximum() {
+ return healthMaximum;
+ }
+
+ public void setHealthMaximum(int healthMaximum) {
+ this.healthMaximum = healthMaximum;
+ }
+
+ public int getCombatLevel() {
+ return combatLevel;
+ }
+
+ public void setCombatLevel(int combatLevel) {
+ this.combatLevel = combatLevel;
+ }
+
+ // TODO
+ public int getProjectileRange() {
+ return 0;
+ }
+
+}
diff --git a/rsc-server/src/org/openrsc/model/Npc.java b/rsc-server/src/org/openrsc/model/Npc.java
new file mode 100644
index 0000000..a46d960
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/Npc.java
@@ -0,0 +1,182 @@
+package org.openrsc.model;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+
+import org.openrsc.model.data.Resources;
+import org.openrsc.model.player.Player;
+
+/**
+ * Represents a non-player game character.
+ *
+ */
+public class Npc extends Mob {
+
+ private int type;
+
+ /**
+ * Where the Npc was spawned. Used for respawn, and retreating.
+ */
+ private Location origin;
+
+ /**
+ * How far the npc can walk from their origin location.
+ */
+ private int movementRadius = 0;
+
+ /**
+ * A retreat flag.
+ */
+ private boolean retreatToOrigin = false;
+
+ /**
+ * A list of nearby players. The npc will only have information for these
+ * entities.
+ */
+ private final SetsessionId
.matching
+ * sessionId
.matching sessionId
.
+ */
+ public Npc getForSessionId(int sessionId) {
+ for (Npc npc : currentList) {
+ if (npc.getSessionId() == sessionId) {
+ return npc;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return A lost of registered npcs. This does not include npcs from the login
+ * queue.
+ */
+ public SetaccountId
.
+ */
+ public Player getForAccountId(int accountId) {
+ for (Player player : currentList) {
+ if (player.getAccountId() == accountId) {
+ return player;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return The player with the matching sessionId
.
+ */
+ public Player getForSessionId(int sessionId) {
+ for (Player player : currentList) {
+ if (player.getSessionId() == sessionId) {
+ return player;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return A list of registered players. This does not include players from the
+ * login queue.
+ */
+ public SetEntityHandler.java
from other RSC sources.
+ * EntityHandler.java
from other RSC sources.
*
* @author Dan Bryce
*/
diff --git a/rsc-server/src/server/entityhandling/defs/DoorDef.java b/rsc-server/src/org/openrsc/model/data/definitions/DoorDef.java
similarity index 95%
rename from rsc-server/src/server/entityhandling/defs/DoorDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/DoorDef.java
index e8f8935..575bd1e 100644
--- a/rsc-server/src/server/entityhandling/defs/DoorDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/DoorDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
/**
* The definition wrapper for doors
diff --git a/rsc-server/src/server/entityhandling/defs/EntityDef.java b/rsc-server/src/org/openrsc/model/data/definitions/EntityDef.java
similarity index 93%
rename from rsc-server/src/server/entityhandling/defs/EntityDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/EntityDef.java
index 0a06207..d1c918c 100644
--- a/rsc-server/src/server/entityhandling/defs/EntityDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/EntityDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
/**
* The abstract class EntityDef implements methods for return values which are
diff --git a/rsc-server/src/server/entityhandling/defs/GameObjectDef.java b/rsc-server/src/org/openrsc/model/data/definitions/GameObjectDef.java
similarity index 96%
rename from rsc-server/src/server/entityhandling/defs/GameObjectDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/GameObjectDef.java
index 8b5ed0a..85d4dab 100644
--- a/rsc-server/src/server/entityhandling/defs/GameObjectDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/GameObjectDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
/**
* The definition wrapper for game objects
diff --git a/rsc-server/src/server/entityhandling/defs/ItemDef.java b/rsc-server/src/org/openrsc/model/data/definitions/ItemDef.java
similarity index 95%
rename from rsc-server/src/server/entityhandling/defs/ItemDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/ItemDef.java
index 75d9bd7..2ff4693 100644
--- a/rsc-server/src/server/entityhandling/defs/ItemDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/ItemDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
/**
* The definition wrapper for items
diff --git a/rsc-server/src/server/entityhandling/defs/ItemDropDef.java b/rsc-server/src/org/openrsc/model/data/definitions/ItemDropDef.java
similarity index 85%
rename from rsc-server/src/server/entityhandling/defs/ItemDropDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/ItemDropDef.java
index ececdc0..9c75ff8 100644
--- a/rsc-server/src/server/entityhandling/defs/ItemDropDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/ItemDropDef.java
@@ -1,6 +1,7 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
public class ItemDropDef {
+
public int id;
public int amount;
public int weight;
@@ -16,4 +17,5 @@ public int getAmount() {
public int getWeight() {
return weight;
}
+
}
\ No newline at end of file
diff --git a/rsc-server/src/server/entityhandling/defs/NpcDef.java b/rsc-server/src/org/openrsc/model/data/definitions/NpcDef.java
similarity index 98%
rename from rsc-server/src/server/entityhandling/defs/NpcDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/NpcDef.java
index 8ba8cc5..ee97b63 100644
--- a/rsc-server/src/server/entityhandling/defs/NpcDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/NpcDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
/**
* The definition wrapper for npcs
diff --git a/rsc-server/src/server/entityhandling/defs/PrayerDef.java b/rsc-server/src/org/openrsc/model/data/definitions/PrayerDef.java
similarity index 69%
rename from rsc-server/src/server/entityhandling/defs/PrayerDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/PrayerDef.java
index dcec74c..20496cf 100644
--- a/rsc-server/src/server/entityhandling/defs/PrayerDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/PrayerDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
/**
* The definition wrapper for prayers
@@ -10,7 +10,8 @@ public class PrayerDef extends EntityDef {
*/
public int reqLevel;
/**
- * The drain rate of the prayer (perhaps points per min?)
+ * The drain rate of the prayer (perhaps points per min?) This is likely per
+ * game tick - morgue
*/
public int drainRate;
diff --git a/rsc-server/src/server/entityhandling/defs/SpellDef.java b/rsc-server/src/org/openrsc/model/data/definitions/SpellDef.java
similarity index 95%
rename from rsc-server/src/server/entityhandling/defs/SpellDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/SpellDef.java
index b661a11..6ca4a27 100644
--- a/rsc-server/src/server/entityhandling/defs/SpellDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/SpellDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
import java.util.HashMap;
import java.util.Map.Entry;
diff --git a/rsc-server/src/server/entityhandling/defs/TileDef.java b/rsc-server/src/org/openrsc/model/data/definitions/TileDef.java
similarity index 86%
rename from rsc-server/src/server/entityhandling/defs/TileDef.java
rename to rsc-server/src/org/openrsc/model/data/definitions/TileDef.java
index 7eabecf..79945de 100644
--- a/rsc-server/src/server/entityhandling/defs/TileDef.java
+++ b/rsc-server/src/org/openrsc/model/data/definitions/TileDef.java
@@ -1,4 +1,4 @@
-package server.entityhandling.defs;
+package org.openrsc.model.data.definitions;
public class TileDef {
public int colour;
diff --git a/rsc-server/src/server/entityhandling/locs/GameObjectLoc.java b/rsc-server/src/org/openrsc/model/data/locations/GameObjectLoc.java
similarity index 87%
rename from rsc-server/src/server/entityhandling/locs/GameObjectLoc.java
rename to rsc-server/src/org/openrsc/model/data/locations/GameObjectLoc.java
index a35d052..68dca74 100644
--- a/rsc-server/src/server/entityhandling/locs/GameObjectLoc.java
+++ b/rsc-server/src/org/openrsc/model/data/locations/GameObjectLoc.java
@@ -1,5 +1,8 @@
-package server.entityhandling.locs;
+package org.openrsc.model.data.locations;
+/**
+ * Represents a static game object location.
+ */
public class GameObjectLoc {
/**
* The id of the gameObject
diff --git a/rsc-server/src/server/entityhandling/locs/ItemLoc.java b/rsc-server/src/org/openrsc/model/data/locations/ItemLoc.java
similarity index 87%
rename from rsc-server/src/server/entityhandling/locs/ItemLoc.java
rename to rsc-server/src/org/openrsc/model/data/locations/ItemLoc.java
index 2752ebe..a401f3b 100644
--- a/rsc-server/src/server/entityhandling/locs/ItemLoc.java
+++ b/rsc-server/src/org/openrsc/model/data/locations/ItemLoc.java
@@ -1,5 +1,8 @@
-package server.entityhandling.locs;
+package org.openrsc.model.data.locations;
+/**
+ * Represents a static ground item spawn.
+ */
public class ItemLoc {
/**
* The id of the gameObject
diff --git a/rsc-server/src/server/entityhandling/locs/NpcLoc.java b/rsc-server/src/org/openrsc/model/data/locations/NpcLoc.java
similarity index 90%
rename from rsc-server/src/server/entityhandling/locs/NpcLoc.java
rename to rsc-server/src/org/openrsc/model/data/locations/NpcLoc.java
index 1649053..275b744 100644
--- a/rsc-server/src/server/entityhandling/locs/NpcLoc.java
+++ b/rsc-server/src/org/openrsc/model/data/locations/NpcLoc.java
@@ -1,5 +1,8 @@
-package server.entityhandling.locs;
+package org.openrsc.model.data.locations;
+/**
+ * Represents a static npc item spawn.
+ */
public class NpcLoc {
/**
* The id of the Npc
diff --git a/rsc-server/src/org/openrsc/model/event/Event.java b/rsc-server/src/org/openrsc/model/event/Event.java
new file mode 100644
index 0000000..90300a4
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/event/Event.java
@@ -0,0 +1,76 @@
+package org.openrsc.model.event;
+
+import org.openrsc.task.TaskEngine;
+
+/**
+ * Represents a task that is executed in the future, once, or periodically.
+ */
+public abstract class Event {
+
+ /**
+ * The delay (in milliseconds).
+ */
+ private long delay;
+
+ /**
+ * The running flag.
+ */
+ private boolean running = true;
+
+ /**
+ * Creates an event with the specified delay.
+ *
+ * @param delay
+ * The delay.
+ */
+ public Event(long delay) {
+ this.delay = delay;
+ }
+
+ /**
+ * Gets the event delay.
+ *
+ * @return The delay, in milliseconds.
+ */
+ public long getDelay() {
+ return delay;
+ }
+
+ /**
+ * Sets the event delay.
+ *
+ * @param delay
+ * The delay to set.
+ * @throws IllegalArgumentException
+ * if the delay is negative.
+ */
+ public void setDelay(long delay) {
+ if (delay < 0) {
+ throw new IllegalArgumentException("Delay must be positive.");
+ }
+ this.delay = delay;
+ }
+
+ /**
+ * Checks if the event is running.
+ *
+ * @return True, if the event is still running.
+ */
+ public boolean isRunning() {
+ return running;
+ }
+
+ /**
+ * Stops the event from running in the future.
+ */
+ public void stop() {
+ running = false;
+ }
+
+ /**
+ * The execute method is called when the event is run. The general contract of
+ * the execute method is that it may take any action whatsoever.
+ */
+ public abstract void execute(TaskEngine context);
+
+}
diff --git a/rsc-server/src/org/openrsc/model/event/EventManager.java b/rsc-server/src/org/openrsc/model/event/EventManager.java
new file mode 100644
index 0000000..1f7ce87
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/event/EventManager.java
@@ -0,0 +1,51 @@
+package org.openrsc.model.event;
+
+import java.util.concurrent.TimeUnit;
+
+import org.openrsc.task.TaskEngine;
+
+/**
+ */
+public class EventManager {
+
+ private final TaskEngine engine;
+
+ public EventManager(TaskEngine engine) {
+ this.engine = engine;
+ }
+
+ /**
+ * Submits a new event.
+ *
+ * @param event
+ * The event to submit.
+ */
+ public void submit(Event event) {
+ submit(event, event.getDelay());
+ }
+
+ /**
+ * Schedules an event to run after the specified delay.
+ *
+ * @param event
+ * The event.
+ * @param delay
+ * The delay.
+ */
+ private void submit(Event event, long delay) {
+ engine.scheduleLogic(new Runnable() {
+ @Override
+ public void run() {
+ if (!event.isRunning()) {
+ return;
+ }
+ long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
+ event.execute(engine);
+ long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start;
+ long remaining = event.getDelay() - elapsed;
+ submit(event, remaining < 0 ? 0 : remaining);
+ }
+ }, delay, TimeUnit.MILLISECONDS);
+ }
+
+}
\ No newline at end of file
diff --git a/rsc-server/src/org/openrsc/model/event/impl/GameTickTaskEvent.java b/rsc-server/src/org/openrsc/model/event/impl/GameTickTaskEvent.java
new file mode 100644
index 0000000..028c0fe
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/event/impl/GameTickTaskEvent.java
@@ -0,0 +1,40 @@
+package org.openrsc.model.event.impl;
+
+import java.util.concurrent.TimeUnit;
+
+import org.openrsc.model.NpcManager;
+import org.openrsc.model.PlayerManager;
+import org.openrsc.model.event.Event;
+import org.openrsc.task.Task;
+import org.openrsc.task.TaskEngine;
+
+/**
+ * The game tick event task.
+ */
+public class GameTickTaskEvent extends Event {
+
+ public GameTickTaskEvent() {
+ super(600);
+ }
+
+ @Override
+ public void execute(TaskEngine context) {
+ context.pushTask(new UpdateTask());
+ }
+
+}
+
+class UpdateTask implements Task {
+
+ @Override
+ public void execute(TaskEngine context) {
+ context.submitTask(new Runnable() {
+ public void run() {
+ long currentTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
+ PlayerManager.getInstance().tick(currentTime);
+ NpcManager.getInstance().tick(currentTime);
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/rsc-server/src/org/openrsc/model/net/GameLoginHandler.java b/rsc-server/src/org/openrsc/model/net/GameLoginHandler.java
new file mode 100644
index 0000000..7a2804e
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/net/GameLoginHandler.java
@@ -0,0 +1,226 @@
+package org.openrsc.model.net;
+
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.Random;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelFutureListener;
+import org.openrsc.Config;
+import org.openrsc.model.Constants;
+import org.openrsc.model.PlayerManager;
+import org.openrsc.model.Privilege;
+import org.openrsc.model.player.Player;
+import org.openrsc.net.packet.Packet;
+import org.openrsc.util.GameUtils;
+
+/**
+ * Handles a client login request. Validates the account credentials and checks
+ * for special world parameters, etc.
+ */
+public class GameLoginHandler {
+
+ public GameLoginHandler() {
+ // ..
+ }
+
+ private String usernameErrorReport = null;
+ private String passwordErrorReport = null;
+
+ public void execute(Channel channel, Packet packet) {
+
+ // Check the client build.
+ double clientBuild = packet.getDouble();
+
+ // Read account credentials from the client.
+ String username = packet.getString();
+
+ // Read the secure password from the client.
+ String password = packet.getString(); // TODO Use RSA
+
+ // Invalid client build.
+ if (clientBuild != Constants.CLIENT_BUILD) {
+ sendLoginError(channel, "Please update your client");
+ return;
+ }
+
+ // Server is full.
+ if (PlayerManager.getInstance().getCount() >= Config.USER_LIMIT) {
+ sendLoginError(channel, "Server is full");
+ return;
+ }
+
+ // Username is not allowed.
+ if (!isUsernameValid(username)) {
+ sendLoginError(channel, usernameErrorReport);
+ return;
+ }
+
+ // Password is not allowed.
+ if (!isPasswordValid(password)) {
+ sendLoginError(channel, passwordErrorReport);
+ return;
+ }
+
+ // Account is not registered.
+ if (!doesUserExist(username)) {
+ sendLoginError(channel, "Account does not exist");
+ return;
+ }
+
+ // Account is registered.
+ // Get the database uuid.
+ final int databaseId = new Random().nextInt(9999); // TODO load from database
+
+ // Invalid username or password.
+ if (!validateCredentials(databaseId, password)) {
+ sendLoginError(channel, "Invalid username or password");
+ return;
+ }
+
+ // The client's password is correct.
+ // Get the display name.
+ final String displayName = username; // TODO could be used for display name
+
+ // Account is already logged in.
+ if (isLoggedIn(databaseId)) {
+ sendLoginError(channel, "Account is already logged in");
+ return;
+ }
+
+ // Credentials are valid. Load the account privileges.
+ Privilege privilege = getPrivilege(databaseId);
+ // System.out.println("Login->privilege=" + privilege);
+
+ // Account is banned.
+ if (isBanned(databaseId)) {
+ sendLoginError(channel, "Account is banned");
+ return;
+ }
+
+ /*
+ * Successful login.
+ */
+
+ // Create the player instance.
+ final Player player = PlayerManager.getInstance().create(channel, databaseId, displayName);
+ player.setPrivileges(privilege);
+
+ // Send the login response to the client.
+ Packet success = new Packet(2).putBoolean(true).putBase37(displayName).putInt(player.getSessionId())
+ .putByte(player.getPrivileges().toInteger());
+ channel.write(success).addListener(new ChannelFutureListener() {
+ @Override
+ public void operationComplete(ChannelFuture future) {
+ // Register the player.
+ PlayerManager.getInstance().queueLogin(player);
+ }
+ });
+
+ }
+
+ /**
+ * The login request has been denied. Tell the client which error, then close
+ * the connection.
+ */
+ private void sendLoginError(Channel channel, String message) {
+ Packet packet = new Packet(2).putBoolean(false).putString(message);
+ channel.write(packet).addListener(new ChannelFutureListener() {
+ @Override
+ public void operationComplete(ChannelFuture future) {
+ channel.close();
+ }
+ });
+ }
+
+ /**
+ * Checks if the username String is valid.
+ */
+ private boolean isUsernameValid(String username) {
+ username = username.replaceAll("_", " ");
+ CharacterIterator iterator = new StringCharacterIterator(username);
+ for (char ch = iterator.first(); ch != CharacterIterator.DONE; ch = iterator.next()) {
+ if (!GameUtils.isValidCharacter(ch)) {
+ usernameErrorReport = "Username can only contain a-z 0-9.";
+ return false;
+ }
+ }
+ if (username.startsWith(" ")) {
+ usernameErrorReport = "Username cannot start with spaces.";
+ return false;
+ }
+ if (username.endsWith(" ")) {
+ usernameErrorReport = "Username cannot end with spaces.";
+ return false;
+ }
+ if (username.contains(" ")) {
+ usernameErrorReport = "Cannot contain back to back spaces.";
+ return false;
+ }
+ if (username.length() < 3) {
+ usernameErrorReport = "Username too short.";
+ return false;
+ }
+ if (username.length() > 12) {
+ usernameErrorReport = "Username too long.";
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Checks if the password String is valid.
+ */
+ private boolean isPasswordValid(String password) {
+ CharacterIterator iterator = new StringCharacterIterator(password);
+ for (char ch = iterator.first(); ch != CharacterIterator.DONE; ch = iterator.next()) {
+ if (!GameUtils.isValidCharacter(ch)) {
+ passwordErrorReport = "Password contains invalid characters.";
+ return false;
+ }
+ }
+ if (password.length() < 5) {
+ passwordErrorReport = "Password too short.";
+ return false;
+ }
+ if (password.length() > 25) {
+ passwordErrorReport = "Password too long.";
+ return false;
+ }
+ return true;
+ }
+
+ // Check if account has completed registration.
+ private boolean doesUserExist(String username) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ // Check if username password combination is valid.
+ private boolean validateCredentials(int databaseId, String password) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ // Check if user is already logged in.
+ private boolean isLoggedIn(int databaseId) {
+ boolean connected = PlayerManager.getInstance().getForAccountId(databaseId) != null;
+
+ // TODO : Check if player is logged in to a different server
+ return connected;
+ }
+
+ // Check if account is banned.
+ private boolean isBanned(int databaseId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ // Get user privilege.
+ private Privilege getPrivilege(int databaseId) {
+ // TODO Auto-generated method stub
+ return Privilege.GITHUB_CONTRIBUTOR;
+ }
+
+}
\ No newline at end of file
diff --git a/rsc-server/src/org/openrsc/model/net/packet/SilentPacket.java b/rsc-server/src/org/openrsc/model/net/packet/SilentPacket.java
new file mode 100644
index 0000000..b4e34cb
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/net/packet/SilentPacket.java
@@ -0,0 +1,46 @@
+package org.openrsc.model.net.packet;
+
+import org.openrsc.model.player.Player;
+import org.openrsc.net.packet.Packet;
+import org.openrsc.net.packet.PacketHandler;
+
+/**
+ * There is no server reaction, no events, no response, etc. The client only
+ * sends these packets to prevent an idle logout.
+ */
+public class SilentPacket implements PacketHandler {
+
+ /**
+ * Sent from the client once per second, if the user has touched a keyboard key
+ * while the game window is in the foreground.
+ */
+ private final int KEYBOARD_TOUCH = 0;
+
+ /**
+ * Sent from the client once per second, if the mouse cursor has moved, or if a
+ * mouse button has been clicked, while inside of the game window.
+ */
+ private final int MOUSE_MOVEMENT = 1;
+
+ /**
+ * Sent from client once per second, if the camera has moved.
+ */
+ private final int CAMERA_UPDATE = 2;
+
+ @Override
+ public void execute(Player player, Packet packet) {
+ int resetIndex = packet.getByte();
+ switch (resetIndex) {
+ case KEYBOARD_TOUCH:
+ case MOUSE_MOVEMENT:
+ case CAMERA_UPDATE:
+ break;
+ }
+ }
+
+ @Override
+ public boolean addToQueue() {
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/rsc-server/src/org/openrsc/model/player/PacketDispatcher.java b/rsc-server/src/org/openrsc/model/player/PacketDispatcher.java
new file mode 100644
index 0000000..4e780a3
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/player/PacketDispatcher.java
@@ -0,0 +1,27 @@
+package org.openrsc.model.player;
+
+import org.openrsc.net.packet.Packet;
+
+/**
+ * Contains the outgoing packets. Each packet can be be given specific
+ * parameters.
+ */
+public class PacketDispatcher {
+
+ /**
+ * The player who receives the outgoing packet.
+ */
+ private final Player player;
+
+ public PacketDispatcher(final Player player) {
+ this.player = player;
+ }
+
+ public void sendMessage(String string) {
+ Packet packet = new Packet(3);
+ packet.putByte(player.getPrivileges().toInteger());
+ packet.putString(string);
+ player.getChannel().write(packet);
+ }
+
+}
\ No newline at end of file
diff --git a/rsc-server/src/org/openrsc/model/player/Player.java b/rsc-server/src/org/openrsc/model/player/Player.java
new file mode 100644
index 0000000..7e25c5b
--- /dev/null
+++ b/rsc-server/src/org/openrsc/model/player/Player.java
@@ -0,0 +1,246 @@
+package org.openrsc.model.player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.jboss.netty.channel.Channel;
+import org.openrsc.Config;
+import org.openrsc.model.Constants;
+import org.openrsc.model.GameMode;
+import org.openrsc.model.Mob;
+import org.openrsc.model.Npc;
+import org.openrsc.model.NpcManager;
+import org.openrsc.model.PlayerManager;
+import org.openrsc.model.Privilege;
+import org.openrsc.net.packet.Packet;
+import org.openrsc.net.packet.PacketManager;
+import org.openrsc.util.GameUtils;
+
+public class Player extends Mob {
+
+ // Packet Handling / Network
+ private final Channel channel;
+ private final BlockingQueueConnectionHandler
handles incoming packet data.
+ */
+public class ConnectionHandler extends SimpleChannelHandler {
+
+ private ArrayListExecutorService
. This service is scheduled which means
+ * Event
s are also submitted to it.
+ */
+public class TaskEngine implements Runnable {
+
+ /**
+ * A queue of pending tasks.
+ */
+ private final BlockingQueueParallelTask
s.
+ */
+ private final BlockingExecutorService taskService;
+
+ /**
+ * Running flag.
+ */
+ private boolean running = false;
+
+ /**
+ * Thread instance.
+ */
+ private Thread thread;
+
+ @SuppressWarnings("unused")
+ public TaskEngine() {
+ this.taskService = Config.TASK_ENGINE_THREAD_COUNT == 1
+ ? new BlockingExecutorService(Executors.newSingleThreadExecutor())
+ : new BlockingExecutorService(Executors.newFixedThreadPool(Config.TASK_ENGINE_THREAD_COUNT));
+ }
+
+ /**
+ * Submits a new task which is processed on the scheduled thread as soon as
+ * possible.
+ *
+ * @param task
+ * The task to submit.
+ */
+ public void pushTask(Task task) {
+ tasks.offer(task);
+ }
+
+ /**
+ * Starts the thread.
+ */
+ public void start() {
+ if (running) {
+ throw new IllegalStateException(getClass().getName() + " already running..");
+ }
+ running = true;
+ thread = new Thread(this);
+ thread.start();
+ }
+
+ /**
+ * Stops the Engine
's thread.
+ */
+ public void stop() {
+ if (!running) {
+ throw new IllegalStateException(getClass().getName() + " already stopped..");
+ }
+ running = false;
+ thread.interrupt();
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (running) {
+ try {
+ final Task task = tasks.take();
+ submitLogic(new Runnable() {
+ @Override
+ public void run() {
+ task.execute(TaskEngine.this);
+ }
+ });
+ } catch (InterruptedException e) {
+ continue;
+ }
+ }
+ } finally {
+ scheduledService.shutdown();
+ taskService.shutdown();
+ }
+ }
+
+ /**
+ * Schedules a task to run in the scheduled service.
+ *
+ * @param runnable
+ * The runnable.
+ * @param delay
+ * The delay.
+ * @param unit
+ * The time unit.
+ * @return The ScheduledFuture
of the scheduled logic.
+ */
+ public ScheduledFuture> scheduleLogic(final Runnable runnable, long delay, TimeUnit unit) {
+ return scheduledService.schedule(new Runnable() {
+ public void run() {
+ try {
+ runnable.run();
+ } catch (Throwable t) {
+ handleError(t);
+ }
+ }
+ }, delay, unit);
+ }
+
+ /**
+ * Submits a task to run in the parallel task service.
+ *
+ * @param runnable
+ * The runnable.
+ */
+ public void submitTask(final Runnable runnable) {
+ taskService.submit(new Runnable() {
+ public void run() {
+ try {
+ runnable.run();
+ } catch (Throwable t) {
+ handleError(t);
+ }
+ }
+ });
+ }
+
+ /**
+ * Submits a task to run in the scheduled service.
+ *
+ * @param runnable
+ * The runnable.
+ */
+ public void submitLogic(final Runnable runnable) {
+ scheduledService.submit(new Runnable() {
+ public void run() {
+ try {
+ runnable.run();
+ } catch (Throwable t) {
+ handleError(t);
+ }
+ }
+ });
+ }
+
+ /**
+ * Waits for pending parallel tasks.
+ *
+ * @throws ExecutionException
+ * If an error occurred during a task.
+ */
+ public void waitForPendingParallelTasks() throws ExecutionException {
+ taskService.waitForPendingTasks();
+ }
+
+ /**
+ * Handles an exception in any of the pools.
+ *
+ * @param t
+ * The exception.
+ */
+ private void handleError(Throwable t) {
+ Logger.getLogger(getClass().getName()).log(Level.SEVERE, "An error has occured in an executor service.", t);
+ Server.getInstance().shutdown(true);
+ }
+
+}
diff --git a/rsc-server/src/org/openrsc/task/impl/ConsecutiveTask.java b/rsc-server/src/org/openrsc/task/impl/ConsecutiveTask.java
new file mode 100644
index 0000000..224181f
--- /dev/null
+++ b/rsc-server/src/org/openrsc/task/impl/ConsecutiveTask.java
@@ -0,0 +1,44 @@
+package org.openrsc.task.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.openrsc.task.Task;
+import org.openrsc.task.TaskEngine;
+
+/**
+ * A task which executes a group of tasks in a guaranteed sequence.
+ *
+ * @author Graham Edgecombe
+ */
+public class ConsecutiveTask implements Task {
+
+ /**
+ * The tasks.
+ */
+ private CollectionExecutorService
that waits for all its events to finish
+ * executing.
+ */
+public class BlockingExecutorService implements ExecutorService {
+
+ /**
+ * The service backing this service.
+ */
+ private ExecutorService service;
+
+ /**
+ * A list of pending tasks.
+ */
+ private BlockingQueueMonth ##, ####
+ */
+ public static String getCalendarDate() {
+ return Calendar.getInstance().getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()) + " "
+ + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + ", " + Calendar.getInstance().get(Calendar.YEAR);
+ }
+
+ /**
+ * @return The current calendar time, formatted as HH:MM.SS
+ */
+ public static String getCalendarTime() {
+ return Calendar.getInstance().get(Calendar.HOUR) + ":" + Calendar.getInstance().get(Calendar.MINUTE) + "."
+ + (Calendar.getInstance().get(Calendar.SECOND) + 1);
+ }
+
+ /**
+ * @return The current time in milliseconds (using nanosecond precision).
+ */
+ public static long getCurrentTimeMillis() {
+ return TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
+ }
+
+ /**
+ * Request a garbage collection, to free unallocated memory.
+ */
+ public static String gc() {
+ long usage = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+ Runtime.getRuntime().runFinalization();
+ Runtime.getRuntime().gc();
+ long cleanup = usage - (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
+ if (cleanup > 0) {
+ return formatSize(cleanup);
+ }
+ return "0";
+ }
+
+ /**
+ * aA-zZ, 0-9, and VALID_CHARS[] are THE ONLY usable chat characters.
+ */
+ public static boolean isValidCharacter(char character) {
+ if (Character.isLetterOrDigit(character)) {
+ return true;
+ }
+ for (int i = 0; i < VALID_CHARS.length; i++) {
+ if (character == VALID_CHARS[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Replaces the input string with asterisks.
+ */
+ public static String replaceWithAsterisks(String string) {
+ StringBuilder asterisks = new StringBuilder();
+ int l = string.length();
+ for (int i = 0; i < l; i++) {
+ asterisks.append("*");
+ }
+ return asterisks.toString();
+ }
+
+ /**
+ * Formats the given number with a more readable output, example: 9001 becomes
+ * 9,001.
+ */
+ public static String formatNumber(int number) {
+ return NumberFormat.getInstance().format(number);
+ }
+
+ /**
+ * @param millis
+ * The millisecond time to be formatted.
+ * @return Returns the given millisecond time value as HH:MM:SS
+ */
+ public static String formatTimeMillis(long millis) {
+ if (millis < 1000) {
+ return millis + "ms";
+ }
+ int s = (int) (millis / 1000) % 60;
+ int m = (int) ((millis / (1000 * 60)) % 60);
+ int h = (int) ((millis / (1000 * 60 * 60)) % 24);
+ return h + ":" + m + ":" + s;
+ }
+
+ /**
+ * Formats the supplied size value from bytes to a more readable value.
+ */
+ public static String formatSize(long bytes) {
+ double kb = bytes / 1024.0;
+ double mb = (kb / 1024.0);
+ double gb = (mb / 1024.0);
+ if (gb > 1) {
+ return DECIMAL_FORMAT.format(gb).concat("GB");
+ } else if (mb > 1) {
+ return DECIMAL_FORMAT.format(mb).concat("MB");
+ } else if (kb > 1) {
+ return DECIMAL_FORMAT.format(kb).concat("KB");
+ } else {
+ return DECIMAL_FORMAT.format(bytes).concat("B");
+ }
+ }
+
+ /**
+ * @see #formatSize(long)
+ */
+ public static String formatSize(File file) {
+ return formatSize(file.length());
+ }
+
+}
\ No newline at end of file
diff --git a/rsc-server/src/server/RuneServer.java b/rsc-server/src/server/RuneServer.java
deleted file mode 100644
index 566f0a0..0000000
--- a/rsc-server/src/server/RuneServer.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package server;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import server.entityhandling.defs.DoorDef;
-import server.entityhandling.defs.GameObjectDef;
-import server.entityhandling.defs.ItemDef;
-import server.entityhandling.defs.NpcDef;
-import server.entityhandling.defs.PrayerDef;
-import server.entityhandling.defs.SpellDef;
-import server.entityhandling.defs.TileDef;
-import server.game.world.World;
-import server.game.world.WorldLoader;
-import server.net.AcceptThread;
-import server.net.Client;
-import server.net.SendPacketTask;
-import server.net.SocketUtils;
-import server.packets.Packet;
-import server.packets.builders.LoginSuccessPacketBuilder;
-import server.packets.from_server.KickPacket;
-import server.res.ResourceLoader;
-import server.res.Resources;
-
-public class RuneServer {
-
- public static final int SERVER_PORT = 7780;
-
- // Kick reasons
- public static final byte SKIP_REASON = 0;
- public static final byte SERVER_CLOSED = 1;
-
- /**
- * Time to wait for all clients to get kicked before shutting down.
- */
- private static final long SHUTDOWN_TIME = 0;
-
- private ExecutorService executor;
-
- private ServerSocket serverSocket;
-
- private boolean exiting;
- private volatile boolean dead;
-
- private List