From 5583ddff51f28293a3f60099de17c4a1d987ef14 Mon Sep 17 00:00:00 2001 From: Mister Hat Date: Sun, 18 Jul 2021 21:51:38 -0500 Subject: [PATCH] threadless client (for web) --- mudclient204-threadless/BZLib.java | 513 ++ mudclient204-threadless/BZState.java | 70 + mudclient204-threadless/Buffer.java | 79 + mudclient204-threadless/ChatMessage.java | 101 + mudclient204-threadless/ClientStream.java | 130 + mudclient204-threadless/Command.java | 133 + mudclient204-threadless/GameCharacter.java | 47 + mudclient204-threadless/GameConnection.java | 544 ++ mudclient204-threadless/GameData.java | 474 ++ mudclient204-threadless/GameFrame.java | 64 + mudclient204-threadless/GameModel.java | 1031 +++ mudclient204-threadless/GameShell.java | 565 ++ mudclient204-threadless/ISAAC.java | 181 + mudclient204-threadless/Packet.java | 266 + mudclient204-threadless/Panel.java | 708 ++ mudclient204-threadless/Polygon.java | 25 + mudclient204-threadless/Scanline.java | 10 + mudclient204-threadless/Scene.java | 3127 +++++++ .../StreamAudioPlayer.java | 6 + mudclient204-threadless/Surface.java | 2016 +++++ mudclient204-threadless/SurfaceSprite.java | 32 + mudclient204-threadless/Utility.java | 238 + mudclient204-threadless/Version.java | 15 + mudclient204-threadless/WordFilter.java | 711 ++ mudclient204-threadless/World.java | 1484 ++++ mudclient204-threadless/mudclient.java | 7555 +++++++++++++++++ 26 files changed, 20125 insertions(+) create mode 100644 mudclient204-threadless/BZLib.java create mode 100644 mudclient204-threadless/BZState.java create mode 100644 mudclient204-threadless/Buffer.java create mode 100644 mudclient204-threadless/ChatMessage.java create mode 100644 mudclient204-threadless/ClientStream.java create mode 100644 mudclient204-threadless/Command.java create mode 100644 mudclient204-threadless/GameCharacter.java create mode 100644 mudclient204-threadless/GameConnection.java create mode 100644 mudclient204-threadless/GameData.java create mode 100644 mudclient204-threadless/GameFrame.java create mode 100644 mudclient204-threadless/GameModel.java create mode 100644 mudclient204-threadless/GameShell.java create mode 100644 mudclient204-threadless/ISAAC.java create mode 100644 mudclient204-threadless/Packet.java create mode 100644 mudclient204-threadless/Panel.java create mode 100644 mudclient204-threadless/Polygon.java create mode 100644 mudclient204-threadless/Scanline.java create mode 100644 mudclient204-threadless/Scene.java create mode 100644 mudclient204-threadless/StreamAudioPlayer.java create mode 100644 mudclient204-threadless/Surface.java create mode 100644 mudclient204-threadless/SurfaceSprite.java create mode 100644 mudclient204-threadless/Utility.java create mode 100644 mudclient204-threadless/Version.java create mode 100644 mudclient204-threadless/WordFilter.java create mode 100644 mudclient204-threadless/World.java create mode 100644 mudclient204-threadless/mudclient.java diff --git a/mudclient204-threadless/BZLib.java b/mudclient204-threadless/BZLib.java new file mode 100644 index 0000000..5cfc7c2 --- /dev/null +++ b/mudclient204-threadless/BZLib.java @@ -0,0 +1,513 @@ +public class BZLib { + + public static int decompress(byte out[], int outSize, byte in[], int inSize, int offset) { + BZState block = new BZState(); + block.input = in; + block.nextIn = offset; + block.output = out; + block.availOut = 0; + block.availIn = inSize; + block.decompressedSize = outSize; + block.bsLive = 0; + block.bsBuff = 0; + block.totalInLo32 = 0; + block.totalInHi32 = 0; + block.totalOutLo32 = 0; + block.totalOutHi32 = 0; + block.blockNo = 0; + decompress(block); + outSize -= block.decompressedSize; + return outSize; + } + + private static void nextHeader(BZState state) { + byte cStateOutCh = state.stateOutCh; + int cStateOutLen = state.stateOutLen; + int cNblockUsed = state.nblockUsed; + int cK0 = state.k0; + int cTt[] = state.tt; + int cTpos = state.tpos; + byte output[] = state.output; + int csNextOut = state.availOut; + int csAvailOut = state.decompressedSize; + int asdasdasd = csAvailOut; + int sSaveNblockPP = state.saveNblock + 1; + returnNotr: + do { + if (cStateOutLen > 0) { + do { + if (csAvailOut == 0) + break returnNotr; + if (cStateOutLen == 1) + break; + output[csNextOut] = cStateOutCh; + cStateOutLen--; + csNextOut++; + csAvailOut--; + } while (true); + if (csAvailOut == 0) { + cStateOutLen = 1; + break; + } + output[csNextOut] = cStateOutCh; + csNextOut++; + csAvailOut--; + } + boolean flag = true; + while (flag) { + flag = false; + if (cNblockUsed == sSaveNblockPP) { + cStateOutLen = 0; + break returnNotr; + } + cStateOutCh = (byte) cK0; + cTpos = cTt[cTpos]; + byte k1 = (byte) (cTpos & 0xff); + cTpos >>= 8; + cNblockUsed++; + if (k1 != cK0) { + cK0 = k1; + if (csAvailOut == 0) { + cStateOutLen = 1; + } else { + output[csNextOut] = cStateOutCh; + csNextOut++; + csAvailOut--; + flag = true; + continue; + } + break returnNotr; + } + if (cNblockUsed != sSaveNblockPP) + continue; + if (csAvailOut == 0) { + cStateOutLen = 1; + break returnNotr; + } + output[csNextOut] = cStateOutCh; + csNextOut++; + csAvailOut--; + flag = true; + } + cStateOutLen = 2; + cTpos = cTt[cTpos]; + byte k2 = (byte) (cTpos & 0xff); + cTpos >>= 8; + if (++cNblockUsed != sSaveNblockPP) + if (k2 != cK0) { + cK0 = k2; + } else { + cStateOutLen = 3; + cTpos = cTt[cTpos]; + byte k3 = (byte) (cTpos & 0xff); + cTpos >>= 8; + if (++cNblockUsed != sSaveNblockPP) + if (k3 != cK0) { + cK0 = k3; + } else { + cTpos = cTt[cTpos]; + byte byte3 = (byte) (cTpos & 0xff); + cTpos >>= 8; + cNblockUsed++; + cStateOutLen = (byte3 & 0xff) + 4; + cTpos = cTt[cTpos]; + cK0 = (byte) (cTpos & 0xff); + cTpos >>= 8; + cNblockUsed++; + } + } + } while (true); + int i2 = state.totalOutLo32; + state.totalOutLo32 += asdasdasd - csAvailOut; + if (state.totalOutLo32 < i2) + state.totalOutHi32++; + state.stateOutCh = cStateOutCh; + state.stateOutLen = cStateOutLen; + state.nblockUsed = cNblockUsed; + state.k0 = cK0; + state.tt = cTt; + state.tpos = cTpos; + state.output = output; + state.availOut = csNextOut; + state.decompressedSize = csAvailOut; + } + + private static void decompress(BZState state) { + /*boolean flag = false; + boolean flag1 = false; + boolean flag2 = false; + boolean flag3 = false; + boolean flag4 = false; + boolean flag5 = false; + boolean flag6 = false; + boolean flag7 = false; + boolean flag8 = false; + boolean flag9 = false; + boolean flag10 = false; + boolean flag11 = false; + boolean flag12 = false; + boolean flag13 = false; + boolean flag14 = false; + boolean flag15 = false; + boolean flag16 = false; + boolean flag17 = false; + boolean flag18 = false;*/ + int gMinLen = 0; + int gLimit[] = null; + int gBase[] = null; + int gPerm[] = null; + state.blocksize100k = 1; + if (state.tt == null) + state.tt = new int[state.blocksize100k * 100000]; + boolean goingandshit = true; + while (goingandshit) { + byte uc = getUchar(state); + if (uc == 23) + return; + uc = getUchar(state); + uc = getUchar(state); + uc = getUchar(state); + uc = getUchar(state); + uc = getUchar(state); + state.blockNo++; + uc = getUchar(state); + uc = getUchar(state); + uc = getUchar(state); + uc = getUchar(state); + uc = getBit(state); + state.blockRandomised = uc != 0; + if (state.blockRandomised) + System.out.println("PANIC! RANDOMISED BLOCK!"); + state.origPtr = 0; + uc = getUchar(state); + state.origPtr = state.origPtr << 8 | uc & 0xff; + uc = getUchar(state); + state.origPtr = state.origPtr << 8 | uc & 0xff; + uc = getUchar(state); + state.origPtr = state.origPtr << 8 | uc & 0xff; + for (int i = 0; i < 16; i++) { + uc = getBit(state); + state.inUse_16[i] = uc == 1; + } + + for (int i = 0; i < 256; i++) + state.inUse[i] = false; + + for (int i = 0; i < 16; i++) + if (state.inUse_16[i]) { + for (int j = 0; j < 16; j++) { + uc = getBit(state); + if (uc == 1) + state.inUse[i * 16 + j] = true; + } + + } + + makeMaps(state); + int alphaSize = state.nInUse + 2; + int nGroups = getBits(3, state); + int nSelectors = getBits(15, state); + for (int i = 0; i < nSelectors; i++) { + int j = 0; + do { + uc = getBit(state); + if (uc == 0) + break; + j++; + } while (true); + state.selectorMtf[i] = (byte) j; + } + + byte pos[] = new byte[6]; + for (byte v = 0; v < nGroups; v++) + pos[v] = v; + + for (int i = 0; i < nSelectors; i++) { + byte v = state.selectorMtf[i]; + byte tmp = pos[v]; + for (; v > 0; v--) + pos[v] = pos[v - 1]; + + pos[0] = tmp; + state.selector[i] = tmp; + } + + for (int t = 0; t < nGroups; t++) { + int curr = getBits(5, state); + for (int i = 0; i < alphaSize; i++) { + do { + uc = getBit(state); + if (uc == 0) + break; + uc = getBit(state); + if (uc == 0) + curr++; + else + curr--; + } while (true); + state.len[t][i] = (byte) curr; + } + + } + + for (int t = 0; t < nGroups; t++) { + byte minLen = 32; + int maxLen = 0; + for (int l1 = 0; l1 < alphaSize; l1++) { + if (state.len[t][l1] > maxLen) + maxLen = state.len[t][l1]; + if (state.len[t][l1] < minLen) + minLen = state.len[t][l1]; + } + + createDecodeTables(state.limit[t], state.base[t], state.perm[t], state.len[t], minLen, maxLen, alphaSize); + state.minLens[t] = minLen; + } + + int eob = state.nInUse + 1; + int nblockMax = 100000 * state.blocksize100k; + int groupNo = -1; + int groupPos = 0; + for (int i = 0; i <= 255; i++) + state.unzftab[i] = 0; + + int kk = 4095; // MTFASIZE-1; + for (int ii = 15; ii >= 0; ii--) { + for (int jj = 15; jj >= 0; jj--) { + state.mtfa[kk] = (byte) (ii * 16 + jj); + kk--; + } + + state.mtfbase[ii] = kk + 1; + } + + int nblock = 0; + // GETMTFVAL + if (groupPos == 0) { + groupNo++; + groupPos = 50; // BZGSIZE + byte gSel = state.selector[groupNo]; + gMinLen = state.minLens[gSel]; + gLimit = state.limit[gSel]; + gPerm = state.perm[gSel]; + gBase = state.base[gSel]; + } + groupPos--; + int zn = gMinLen; + int zvec; + byte zj; + for (zvec = getBits(zn, state); zvec > gLimit[zn]; zvec = zvec << 1 | zj) { + zn++; + zj = getBit(state); + } + + for (int nextSym = gPerm[zvec - gBase[zn]]; nextSym != eob; ) + if (nextSym == 0 || nextSym == 1) { // BZRUNA, BZRUNB + int es = -1; + int N = 1; + do { + if (nextSym == 0) + es += N; + else if (nextSym == 1) + es += 2 * N; + N *= 2; + // GETMTFVAL, y da fuk did they not subroutine this + if (groupPos == 0) { + groupNo++; + groupPos = 50; + byte gSel = state.selector[groupNo]; + gMinLen = state.minLens[gSel]; + gLimit = state.limit[gSel]; + gPerm = state.perm[gSel]; + gBase = state.base[gSel]; + } + groupPos--; + int zn_2 = gMinLen; + int zvec_2; + byte zj_2; + for (zvec_2 = getBits(zn_2, state); zvec_2 > gLimit[zn_2]; zvec_2 = zvec_2 << 1 | zj_2) { + zn_2++; + zj_2 = getBit(state); + } + + nextSym = gPerm[zvec_2 - gBase[zn_2]]; + } while (nextSym == 0 || nextSym == 1); + es++; + uc = state.setToUnseq[state.mtfa[state.mtfbase[0]] & 0xff]; + state.unzftab[uc & 0xff] += es; + for (; es > 0; es--) { + state.tt[nblock] = uc & 0xff; + nblock++; + } + + } else { + int nn = nextSym - 1; + if (nn < 16) { // MTFLSIZE + int pp = state.mtfbase[0]; + uc = state.mtfa[pp + nn]; + for (; nn > 3; nn -= 4) { + int z = pp + nn; + state.mtfa[z] = state.mtfa[z - 1]; + state.mtfa[z - 1] = state.mtfa[z - 2]; + state.mtfa[z - 2] = state.mtfa[z - 3]; + state.mtfa[z - 3] = state.mtfa[z - 4]; + } + + for (; nn > 0; nn--) + state.mtfa[pp + nn] = state.mtfa[(pp + nn) - 1]; + + state.mtfa[pp] = uc; + } else { + int lno = nn / 16; + int off = nn % 16; + int pp = state.mtfbase[lno] + off; + uc = state.mtfa[pp]; + for (; pp > state.mtfbase[lno]; pp--) + state.mtfa[pp] = state.mtfa[pp - 1]; + + state.mtfbase[lno]++; + for (; lno > 0; lno--) { + state.mtfbase[lno]--; + state.mtfa[state.mtfbase[lno]] = state.mtfa[(state.mtfbase[lno - 1] + 16) - 1]; + } + + state.mtfbase[0]--; + state.mtfa[state.mtfbase[0]] = uc; + if (state.mtfbase[0] == 0) { + kk = 4095; // MTFASIZE - 1 + for (int ii = 15; ii >= 0; ii--) { + for (int jj = 15; jj >= 0; jj--) { + state.mtfa[kk] = state.mtfa[state.mtfbase[ii] + jj]; + kk--; + } + + state.mtfbase[ii] = kk + 1; + } + + } + } + state.unzftab[state.setToUnseq[uc & 0xff] & 0xff]++; + state.tt[nblock] = state.setToUnseq[uc & 0xff] & 0xff; + nblock++; + // GETMTFVAL here we go AGAIN + if (groupPos == 0) { + groupNo++; + groupPos = 50; + byte gSel = state.selector[groupNo]; + gMinLen = state.minLens[gSel]; + gLimit = state.limit[gSel]; + gPerm = state.perm[gSel]; + gBase = state.base[gSel]; + } + groupPos--; + int zn_2 = gMinLen; + int zvec_2; + byte zj_2; + for (zvec_2 = getBits(zn_2, state); zvec_2 > gLimit[zn_2]; zvec_2 = zvec_2 << 1 | zj_2) { + zn_2++; + zj_2 = getBit(state); + } + + nextSym = gPerm[zvec_2 - gBase[zn_2]]; + } + + state.stateOutLen = 0; + state.stateOutCh = 0; + state.cftab[0] = 0; + for (int i = 1; i <= 256; i++) + state.cftab[i] = state.unzftab[i - 1]; + + for (int i = 1; i <= 256; i++) + state.cftab[i] += state.cftab[i - 1]; + + for (int i = 0; i < nblock; i++) { + uc = (byte) (state.tt[i] & 0xff); + state.tt[state.cftab[uc & 0xff]] |= i << 8; + state.cftab[uc & 0xff]++; + } + + state.tpos = state.tt[state.origPtr] >> 8; + state.nblockUsed = 0; + state.tpos = state.tt[state.tpos]; + state.k0 = (byte) (state.tpos & 0xff); + state.tpos >>= 8; + state.nblockUsed++; + state.saveNblock = nblock; + nextHeader(state); + goingandshit = state.nblockUsed == state.saveNblock + 1 && state.stateOutLen == 0; + } + } + + private static byte getUchar(BZState state) { + return (byte) getBits(8, state); + } + + private static byte getBit(BZState state) { + return (byte) getBits(1, state); + } + + private static int getBits(int i, BZState state) { + int vvv; + do { + if (state.bsLive >= i) { + int v = state.bsBuff >> state.bsLive - i & (1 << i) - 1; + state.bsLive -= i; + vvv = v; + break; + } + state.bsBuff = state.bsBuff << 8 | state.input[state.nextIn] & 0xff; + state.bsLive += 8; + state.nextIn++; + state.availIn--; + state.totalInLo32++; + if (state.totalInLo32 == 0) + state.totalInHi32++; + } while (true); + return vvv; + } + + private static void makeMaps(BZState state) { + state.nInUse = 0; + for (int i = 0; i < 256; i++) + if (state.inUse[i]) { + state.setToUnseq[state.nInUse] = (byte) i; + state.nInUse++; + } + + } + + private static void createDecodeTables(int limit[], int base[], int perm[], byte length[], int minLen, int maxLen, int alphaSize) { + int pp = 0; + for (int i = minLen; i <= maxLen; i++) { + for (int j = 0; j < alphaSize; j++) + if (length[j] == i) { + perm[pp] = j; + pp++; + } + + } + + for (int i = 0; i < 23; i++) + base[i] = 0; + + for (int i = 0; i < alphaSize; i++) + base[length[i] + 1]++; + + for (int i = 1; i < 23; i++) + base[i] += base[i - 1]; + + for (int i = 0; i < 23; i++) + limit[i] = 0; + + int vec = 0; + for (int i = minLen; i <= maxLen; i++) { + vec += base[i + 1] - base[i]; + limit[i] = vec - 1; + vec <<= 1; + } + + for (int i = minLen + 1; i <= maxLen; i++) + base[i] = (limit[i - 1] + 1 << 1) - base[i]; + + } +} diff --git a/mudclient204-threadless/BZState.java b/mudclient204-threadless/BZState.java new file mode 100644 index 0000000..74a5d9e --- /dev/null +++ b/mudclient204-threadless/BZState.java @@ -0,0 +1,70 @@ +class BZState { + + //int anIntArray488[]; // unused + public int tt[]; // this was static, wonder why? + /* unused + int anInt456 = 4096; // MTFASIZE ? + int anInt457 = 16; // MTFLSIZE + int anInt458 = 258; + int anInt459 = 23; + int anInt460 = 1; + int anInt461 = 6; // BZNGROUPS ? + int anInt462 = 50; // BZGSIZE ? + int anInt463 = 4; + int anInt464 = 18002; */ + byte input[]; + int nextIn; + int availIn; + int totalInLo32; + int totalInHi32; + byte output[]; + int availOut; + int decompressedSize; + int totalOutLo32; + int totalOutHi32; + byte stateOutCh; + int stateOutLen; + boolean blockRandomised; + int bsBuff; + int bsLive; + int blocksize100k; + int blockNo; + int origPtr; + int tpos; + int k0; + int unzftab[]; + int nblockUsed; + int cftab[]; + int nInUse; + boolean inUse[]; + boolean inUse_16[]; + byte setToUnseq[]; + byte mtfa[]; + int mtfbase[]; + byte selector[]; + byte selectorMtf[]; + byte len[][]; + int limit[][]; + int base[][]; + int perm[][]; + int minLens[]; + int saveNblock; + + BZState() { + unzftab = new int[256]; + cftab = new int[257]; + //anIntArray488 = new int[257]; // unused + inUse = new boolean[256]; + inUse_16 = new boolean[16]; + setToUnseq = new byte[256]; + mtfa = new byte[4096]; + mtfbase = new int[16]; + selector = new byte[18002]; + selectorMtf = new byte[18002]; + len = new byte[6][258]; + limit = new int[6][258]; + base = new int[6][258]; + perm = new int[6][258]; + minLens = new int[6]; + } +} diff --git a/mudclient204-threadless/Buffer.java b/mudclient204-threadless/Buffer.java new file mode 100644 index 0000000..0b4e928 --- /dev/null +++ b/mudclient204-threadless/Buffer.java @@ -0,0 +1,79 @@ +import java.math.BigInteger; + +public class Buffer { + + /*static CRC32 unusedCRC = new CRC32(); + private static int unusedArray[] = { + 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, + 1023, 2047, 4095, 8191, 16383, 32767, 65535, 0x1ffff, 0x3ffff, 0x7ffff, + 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, + 0x3fffffff, 0x7fffffff, -1 + };*/ + public byte buffer[]; + public int offset; + + public Buffer(byte buff[]) { + buffer = buff; + offset = 0; + } + + public void putByte(int i) { + buffer[offset++] = (byte) i; + } + + public void putInt(int i) { + buffer[offset++] = (byte) (i >> 24); + buffer[offset++] = (byte) (i >> 16); + buffer[offset++] = (byte) (i >> 8); + buffer[offset++] = (byte) i; + } + + public void putString(String s) { + //s.getBytes(0, s.length(), buffer, offset); + System.arraycopy(s.getBytes(), 0, buffer, offset, s.length()); + offset += s.length(); + buffer[offset++] = 10; // null terminate + } + + public void putBytes(byte src[], int srcPos, int len) { + //for (int k = srcPos; k < srcPos + len; k++) + // buffer[offset++] = src[k]; + System.arraycopy(src, srcPos, buffer, offset, len); + offset += len; + } + + public int getUnsignedByte() { + return buffer[offset++] & 0xff; + } + + public int getUnsignedShort() { + offset += 2; + return ((buffer[offset - 2] & 0xff) << 8) + (buffer[offset - 1] & 0xff); + } + + public int getUnsignedInt() { + offset += 4; + return ((buffer[offset - 4] & 0xff) << 24) + ((buffer[offset - 3] & 0xff) << 16) + ((buffer[offset - 2] & 0xff) << 8) + (buffer[offset - 1] & 0xff); + } + + public void getBytes(byte dest[], int destPos, int len) { + //for (int k = destPos; k < destPos + len; k++) + // dest[k] = buffer[offset++]; + System.arraycopy(buffer, offset, dest, destPos, len); + offset += len; + } + + public void encrypt(BigInteger exponent, BigInteger modulus) { + int i = offset; + offset = 0; + byte buf[] = new byte[i]; + getBytes(buf, 0, i); + BigInteger biginteger2 = new BigInteger(buf); + BigInteger biginteger3 = biginteger2.modPow(exponent, modulus); + byte abyte1[] = biginteger3.toByteArray(); + offset = 0; + putByte(abyte1.length); + putBytes(abyte1, 0, abyte1.length); + } + +} diff --git a/mudclient204-threadless/ChatMessage.java b/mudclient204-threadless/ChatMessage.java new file mode 100644 index 0000000..b0e99a0 --- /dev/null +++ b/mudclient204-threadless/ChatMessage.java @@ -0,0 +1,101 @@ +public class ChatMessage { + + public static byte scrambledbytes[] = new byte[100]; + public static char chars[] = new char[100]; + private static char charmap[] = { + ' ', 'e', 't', 'a', 'o', 'i', 'h', 'n', 's', 'r', + 'd', 'l', 'u', 'm', 'w', 'c', 'y', 'f', 'g', 'p', + 'b', 'v', 'k', 'x', 'j', 'q', 'z', '0', '1', '2', + '3', '4', '5', '6', '7', '8', '9', ' ', '!', '?', + '.', ',', ':', ';', '(', ')', '-', '&', '*', '\\', + '\'', '@', '#', '+', '=', '\243', '$', '%', '"', '[', + ']' + }; + + public static String descramble(byte buff[], int off, int len) { + try { + int newLen = 0; + int l = -1; + for (int idx = 0; idx < len; idx++) { + int current = buff[off++] & 0xff; + int k1 = current >> 4 & 0xf; + if (l == -1) { + if (k1 < 13) + chars[newLen++] = charmap[k1]; + else + l = k1; + } else { + chars[newLen++] = charmap[((l << 4) + k1) - 195]; + l = -1; + } + k1 = current & 0xf; + if (l == -1) { + if (k1 < 13) + chars[newLen++] = charmap[k1]; + else + l = k1; + } else { + chars[newLen++] = charmap[((l << 4) + k1) - 195]; + l = -1; + } + } + + boolean flag = true; + for (int l1 = 0; l1 < newLen; l1++) { + char c = chars[l1]; + if (l1 > 4 && c == '@') + chars[l1] = ' '; + if (c == '%') + chars[l1] = ' '; + if (flag && c >= 'a' && c <= 'z') { + chars[l1] += '\uFFE0';// ????? ¢ 65504 + flag = false; + } + if (c == '.' || c == '!') + flag = true; + } + + return new String(chars, 0, newLen); + } catch (Exception Ex) { + return "."; + } + } + + public static int scramble(String s) { + if (s.length() > 80) + s = s.substring(0, 80); + s = s.toLowerCase(); + int off = 0; + int lshift = -1; + for (int k = 0; k < s.length(); k++) { + char currentchar = s.charAt(k); + int foundcharmapidx = 0; + for (int n = 0; n < charmap.length; n++) { + if (currentchar != charmap[n]) + continue; + foundcharmapidx = n; + break; + } + + if (foundcharmapidx > 12) + foundcharmapidx += 195; + if (lshift == -1) { + if (foundcharmapidx < 13) + lshift = foundcharmapidx; + else + scrambledbytes[off++] = (byte) foundcharmapidx; + } else if (foundcharmapidx < 13) { + scrambledbytes[off++] = (byte) ((lshift << 4) + foundcharmapidx); + lshift = -1; + } else { + scrambledbytes[off++] = (byte) ((lshift << 4) + (foundcharmapidx >> 4)); + lshift = foundcharmapidx & 0xf; + } + } + + if (lshift != -1) + scrambledbytes[off++] = (byte) (lshift << 4); + return off; + } + +} diff --git a/mudclient204-threadless/ClientStream.java b/mudclient204-threadless/ClientStream.java new file mode 100644 index 0000000..b0cbba5 --- /dev/null +++ b/mudclient204-threadless/ClientStream.java @@ -0,0 +1,130 @@ +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +public class ClientStream extends Packet { + + private InputStream instream; + private OutputStream outstream; + private Socket socket; + private boolean closing; + private byte buffer[]; + private int endoffset; + private int offset; + private boolean closed; + + public ClientStream(Socket socket, GameShell applet) throws IOException { + closing = false; + closed = true; + this.socket = socket; + instream = socket.getInputStream(); + outstream = socket.getOutputStream(); + closed = false; + //applet.startThread(this); + } + + public void closeStream() { + super.closeStream(); + closing = true; + try { + if (instream != null) + instream.close(); + if (outstream != null) + outstream.close(); + if (socket != null) + socket.close(); + } catch (IOException Ex) { + System.out.println("Error closing stream"); + } + closed = true; + //synchronized (this) { + notify(); + //} + buffer = null; + } + + public int readStream() + throws IOException { + if (closing) + return 0; + else + return instream.read(); + } + + public int availableStream() + throws IOException { + if (closing) + return 0; + else + return instream.available(); + } + + public void readStreamBytes(int len, int off, byte buff[]) + throws IOException { + if (closing) + return; + int k = 0; + boolean flag = false; + int l; + for (; k < len; k += l) + if ((l = instream.read(buff, k + off, len - k)) <= 0) + throw new IOException("EOF"); + + } + + public void writeStreamBytes(byte buff[], int off, int len) + throws IOException { + if (closing) + return; + if (buffer == null) + buffer = new byte[5000]; + //synchronized (this) { + for (int l = 0; l < len; l++) { + buffer[offset] = buff[l + off]; + offset = (offset + 1) % 5000; + if (offset == (endoffset + 4900) % 5000) + throw new IOException("buffer overflow"); + } + + notify(); + //} + } + + public void run() { + while (!closed) { + int len; + int off; + //synchronized (this) { + if (offset == endoffset) + try { + wait(); + } catch (InterruptedException Ex) { + } + if (closed) + return; + off = endoffset; + if (offset >= endoffset) + len = offset - endoffset; + else + len = 5000 - endoffset; + //} + if (len > 0) { + try { + outstream.write(buffer, off, len); + } catch (IOException ioexception) { + super.socketException = true; + super.socketExceptionMessage = "Twriter:" + ioexception; + } + endoffset = (endoffset + len) % 5000; + try { + if (offset == endoffset) + outstream.flush(); + } catch (IOException ioexception1) { + super.socketException = true; + super.socketExceptionMessage = "Twriter:" + ioexception1; + } + } + } + } +} diff --git a/mudclient204-threadless/Command.java b/mudclient204-threadless/Command.java new file mode 100644 index 0000000..c4afa3b --- /dev/null +++ b/mudclient204-threadless/Command.java @@ -0,0 +1,133 @@ +public class Command { + public static final int CL_TRADE_CONFIRM_ACCEPT = 104; + public static final int CL_APPEARANCE = 235; + public static final int CL_BANK_CLOSE = 212; + public static final int CL_BANK_DEPOSIT = 23; + public static final int CL_BANK_WITHDRAW = 22; + public static final int CL_CAST_GROUND = 158; + public static final int CL_CAST_INVITEM = 4; + public static final int CL_CAST_NPC = 50; + public static final int CL_CAST_OBJECT = 99; + public static final int CL_CAST_PLAYER = 229; + public static final int CL_CAST_SELF = 137; + public static final int CL_CHAT = 216; + public static final int CL_CHOOSE_OPTION = 116; + public static final int CL_CLOSE_CONNECTION = 31; + public static final int CL_COMBAT_STYLE = 29; + public static final int CL_COMMAND = 38; + public static final int CL_DUEL_ACCEPT = 176; + public static final int CL_DUEL_CONFIRM_ACCEPT = 77; + public static final int CL_DUEL_DECLINE = 197; + public static final int CL_DUEL_ITEM_UPDATE = 33; + public static final int CL_DUEL_SETTINGS = 8; + public static final int CL_FRIEND_ADD = 195; + public static final int CL_FRIEND_REMOVE = 167; + public static final int CL_CAST_GROUNDITEM = 249; + public static final int CL_GROUNDITEM_TAKE = 247; + public static final int CL_IGNORE_ADD = 132; + public static final int CL_IGNORE_REMOVE = 241; + public static final int CL_INV_CMD = 90; + public static final int CL_INV_DROP = 246; + public static final int CL_INV_UNEQUIP = 170; + public static final int CL_INV_WEAR = 169; + public static final int CL_KNOWN_PLAYERS = 163; + public static final int CL_LOGIN = 0; + public static final int CL_LOGOUT = 102; + public static final int CL_NPC_ATTACK = 190; + public static final int CL_NPC_CMD = 202; + public static final int CL_NPC_TALK = 153; + public static final int CL_OBJECT_CMD1 = 136; + public static final int CL_OBJECT_CMD2 = 79; + public static final int CL_PACKET_EXCEPTION = 3; + public static final int CL_PING = 67; + public static final int CL_PLAYER_ATTACK = 171; + public static final int CL_PLAYER_DUEL = 103; + public static final int CL_PLAYER_FOLLOW = 165; + public static final int CL_PLAYER_TRADE = 142; + public static final int CL_PM = 218; + public static final int CL_PRAYER_OFF = 254; + public static final int CL_PRAYER_ON = 60; + public static final int CL_REPORT_ABUSE = 206; + public static final int CL_SESSION = 32; + public static final int CL_SETTINGS_GAME = 111; + public static final int CL_SETTINGS_PRIVACY = 64; + public static final int CL_SHOP_BUY = 236; + public static final int CL_SHOP_CLOSE = 166; + public static final int CL_SHOP_SELL = 221; + public static final int CL_SLEEP_WORD = 45; + public static final int CL_TRADE_ACCEPT = 55; + public static final int CL_TRADE_DECLINE = 230; + public static final int CL_TRADE_ITEM_UPDATE = 46; + public static final int CL_USEWITH_GROUNDITEM = 53; + public static final int CL_USEWITH_INVITEM = 91; + public static final int CL_USEWITH_NPC = 135; + public static final int CL_USEWITH_OBJECT = 115; + public static final int CL_USEWITH_PLAYER = 113; + public static final int CL_WALK = 187; + public static final int CL_WALK_ACTION = 16; + public static final int CL_WALL_OBJECT_COMMAND1 = 14; + public static final int CL_WALL_OBJECT_COMMAND2 = 127; + public static final int CL_CAST_WALLOBJECT = 180; + public static final int CL_USEWITH_WALLOBJECT = 161; + + public static final int SV_APPEARANCE = 59; + public static final int SV_BANK_CLOSE = 203; + public static final int SV_BANK_OPEN = 42; + public static final int SV_BANK_UPDATE = 249; + public static final int SV_CLOSE_CONNECTION = 4; + public static final int SV_DUEL_ACCEPTED = 210; + public static final int SV_DUEL_CLOSE = 225; + public static final int SV_DUEL_CONFIRM_OPEN = 172; + public static final int SV_DUEL_OPEN = 176; + public static final int SV_DUEL_OPPONENT_ACCEPTED = 253; + public static final int SV_DUEL_SETTINGS = 30; + public static final int SV_DUEL_UPDATE = 6; + public static final int SV_FRIEND_LIST = 71; + public static final int SV_FRIEND_MESSAGE = 120; + public static final int SV_FRIEND_STATUS_CHANGE = 149; + public static final int SV_GAME_SETTINGS = 240; + public static final int SV_IGNORE_LIST = 109; + public static final int SV_INVENTORY_ITEMS = 53; + public static final int SV_INVENTORY_ITEM_REMOVE = 123; + public static final int SV_INVENTORY_ITEM_UPDATE = 90; + public static final int SV_LOGOUT_DENY = 183; + public static final int SV_MESSAGE = 131; + public static final int SV_OPTION_LIST = 245; + public static final int SV_OPTION_LIST_CLOSE = 252; + public static final int SV_PLAYER_DIED = 83; + public static final int SV_PLAYER_QUEST_LIST = 5; + public static final int SV_PLAYER_STAT_EQUIPMENT_BONUS = 153; + public static final int SV_PLAYER_STAT_EXPERIENCE_UPDATE = 33; + public static final int SV_PLAYER_STAT_FATIGUE = 114; + public static final int SV_PLAYER_STAT_FATIGUE_ASLEEP = 244; + public static final int SV_PLAYER_STAT_LIST = 156; + public static final int SV_PLAYER_STAT_UPDATE = 159; + public static final int SV_PRAYER_STATUS = 206; + public static final int SV_PRIVACY_SETTINGS = 51; + public static final int SV_REGION_ENTITY_UPDATE = 211; + public static final int SV_REGION_GROUND_ITEMS = 99; + public static final int SV_REGION_NPCS = 79; + public static final int SV_REGION_NPC_UPDATE = 104; + public static final int SV_REGION_OBJECTS = 48; + public static final int SV_REGION_PLAYERS = 191; + public static final int SV_REGION_PLAYER_UPDATE = 234; + public static final int SV_REGION_WALL_OBJECTS = 91; + public static final int SV_SERVER_MESSAGE = 89; + public static final int SV_SERVER_MESSAGE_ONTOP = 222; + public static final int SV_SHOP_CLOSE = 137; + public static final int SV_SHOP_OPEN = 101; + public static final int SV_SLEEP_CLOSE = 84; + public static final int SV_SLEEP_INCORRECT = 194; + public static final int SV_SLEEP_OPEN = 117; + public static final int SV_SOUND = 204; + public static final int SV_SYSTEM_UPDATE = 52; + public static final int SV_TELEPORT_BUBBLE = 36; + public static final int SV_TRADE_CLOSE = 128; + public static final int SV_TRADE_CONFIRM_OPEN = 20; + public static final int SV_TRADE_ITEMS = 97; + public static final int SV_TRADE_OPEN = 92; + public static final int SV_TRADE_RECIPIENT_STATUS = 162; + public static final int SV_TRADE_STATUS = 15; + public static final int SV_WELCOME = 182; + public static final int SV_WORLD_INFO = 25; +} diff --git a/mudclient204-threadless/GameCharacter.java b/mudclient204-threadless/GameCharacter.java new file mode 100644 index 0000000..33934fd --- /dev/null +++ b/mudclient204-threadless/GameCharacter.java @@ -0,0 +1,47 @@ +final class GameCharacter { + + public long hash; + public String name; + public int serverIndex; + public int serverId; + public int currentX; + public int currentY; + public int npcId; + public int stepCount; + public int animationCurrent; + public int animationNext; + public int movingStep; + public int waypointCurrent; + public int waypointsX[]; + public int waypointsY[]; + public int equippedItem[]; + public String message; + public int messageTimeout; + public int bubbleItem; + public int bubbleTimeout; + public int damageTaken; + public int healthCurrent; + public int healthMax; + public int combatTimer; + public int level; + public int colourHair; + public int colourTop; + public int colourBottom; + public int colourSkin; + public int incomingProjectileSprite; + public int attackingPlayerServerIndex; + public int attackingNpcServerIndex; + public int projectileRange; + //public boolean unused; + //public int unused1; + public int skullVisible; + + GameCharacter() { + waypointsX = new int[10]; + waypointsY = new int[10]; + equippedItem = new int[12]; + level = -1; + //unused = false; + //unused1 = -1; + } +} diff --git a/mudclient204-threadless/GameConnection.java b/mudclient204-threadless/GameConnection.java new file mode 100644 index 0000000..d62b15e --- /dev/null +++ b/mudclient204-threadless/GameConnection.java @@ -0,0 +1,544 @@ +import java.io.IOException; +import java.math.BigInteger; + +public class GameConnection extends GameShell { + + public static int clientVersion = 1; + public static int maxReadTries; + private static BigInteger rsaExponent = new BigInteger("58778699976184461502525193738213253649000149147835990136706041084440742975821"); + //private static BigInteger rsaModulus = new BigInteger("7162900525229798032761816791230527296329313291232324290237849263501208207972894053929065636522363163621000728841182238772712427862772219676577293600221789"); + private static BigInteger rsaModulus = new BigInteger("7656522762491711741880224224809835569769759737077076094091609307381193032090602256314159126169417567841597729801408692196383745596665658895073411749475443"); + private final int maxSocialListSize = 100; + public String server; + public int port; + public ClientStream clientStream; + public int friendListCount; + public long friendListHashes[]; + public int friendListOnline[]; + public int ignoreListCount; + public long ignoreList[]; + public int settingsBlockChat; + public int settingsBlockPrivate; + public int settingsBlockTrade; + public int settingsBlockDuel; + public long sessionID; + public int worldFullTimeout; + public int moderatorLevel; + String username; + String password; + byte incomingPacket[]; + int autoLoginTimeout; + long packetLastRead; + private int anIntArray629[]; + private int anInt630; + + public GameConnection() { + server = "127.0.0.1"; + port = 43594; + username = ""; + password = ""; + incomingPacket = new byte[5000]; + friendListHashes = new long[200]; + friendListOnline = new int[200]; + ignoreList = new long[maxSocialListSize]; + anIntArray629 = new int[maxSocialListSize]; + } + + protected void login(String u, String p, boolean reconnecting) { + if (worldFullTimeout > 0) { + showLoginScreenStatus("Please wait...", "Connecting to server"); + try { + Thread.sleep(2000L); + } catch (Exception Ex) { + } + showLoginScreenStatus("Sorry! The server is currently full.", "Please try again later"); + return; + } + try { + username = u; + u = Utility.formatAuthString(u, 20); + password = p; + p = Utility.formatAuthString(p, 20); + if (u.trim().length() == 0) { + showLoginScreenStatus("You must enter both a username", "and a password - Please try again"); + return; + } + if (reconnecting) + drawTextBox("Connection lost! Please wait...", "Attempting to re-establish"); + else + showLoginScreenStatus("Please wait...", "Connecting to server"); + clientStream = new ClientStream(createSocket(server, port), this); + clientStream.maxReadTries = maxReadTries; + long l = Utility.username2hash(u); + clientStream.newPacket((Command.CL_SESSION)); + clientStream.putByte((int) (l >> 16 & 31L)); + clientStream.flushPacket(); + long sessid = clientStream.getLong(); + sessionID = sessid; + if (sessid == 0L) { + showLoginScreenStatus("Login server offline.", "Please try again in a few mins"); + return; + } + System.out.println("Verb: Session id: " + sessid); + int limit30 = 0; + /* + try { + if (getStartedAsApplet()) { + String s2 = getParameter("limit30"); + if (s2.equals("1")) + limit30 = 1; + } + } catch (Exception Ex) { + }*/ + int ai[] = new int[4]; + ai[0] = (int) (Math.random() * 99999999D); + ai[1] = (int) (Math.random() * 99999999D); + ai[2] = (int) (sessid >> 32); + ai[3] = (int) sessid; + + // TODO maybe re-enable RSA later + /* + Buffer buffer = new Buffer(new byte[500]); + buffer.offset = 0; + buffer.putByte(10); + buffer.putInt(ai[0]); + buffer.putInt(ai[1]); + buffer.putInt(ai[2]); + buffer.putInt(ai[3]); + buffer.putInt(getLinkUID()); + buffer.putString(u); + buffer.putString(p); + buffer.encrypt(rsaExponent, rsaModulus); + */ + + clientStream.newPacket((Command.CL_LOGIN)); + + if (reconnecting) + clientStream.putByte(1); + else + clientStream.putByte(0); + clientStream.putShort(clientVersion); + clientStream.putByte(limit30); + + clientStream.putByte(10); + clientStream.putInt(ai[0]); + clientStream.putInt(ai[1]); + clientStream.putInt(ai[2]); + clientStream.putInt(ai[3]); + clientStream.putInt(getLinkUID()); + clientStream.putString(u); + clientStream.putString(p); + + //clientStream.putBytes(buffer.buffer, 0, buffer.offset); + + clientStream.flushPacket(); + clientStream.seedIsaac(ai); + int resp = clientStream.readStream(); + System.out.println("login response:" + resp); + if (resp == 25) { + moderatorLevel = 1; + autoLoginTimeout = 0; + resetGame(); + return; + } + if (resp == 0) { + moderatorLevel = 0; + autoLoginTimeout = 0; + resetGame(); + return; + } + if (resp == 1) { + autoLoginTimeout = 0; + method37(); + return; + } + if (reconnecting) { + u = ""; + p = ""; + resetLoginVars(); + return; + } + if (resp == -1) { + showLoginScreenStatus("Error unable to login.", "Server timed out"); + return; + } + if (resp == 3) { + showLoginScreenStatus("Invalid username or password.", "Try again, or create a new account"); + return; + } + if (resp == 4) { + showLoginScreenStatus("That username is already logged in.", "Wait 60 seconds then retry"); + return; + } + if (resp == 5) { + showLoginScreenStatus("The client has been updated.", "Please reload this page"); + return; + } + if (resp == 6) { + showLoginScreenStatus("You may only use 1 character at once.", "Your ip-address is already in use"); + return; + } + if (resp == 7) { + showLoginScreenStatus("Login attempts exceeded!", "Please try again in 5 minutes"); + return; + } + if (resp == 8) { + showLoginScreenStatus("Error unable to login.", "Server rejected session"); + return; + } + if (resp == 9) { + showLoginScreenStatus("Error unable to login.", "Loginserver rejected session"); + return; + } + if (resp == 10) { + showLoginScreenStatus("That username is already in use.", "Wait 60 seconds then retry"); + return; + } + if (resp == 11) { + showLoginScreenStatus("Account temporarily disabled.", "Check your message inbox for details"); + return; + } + if (resp == 12) { + showLoginScreenStatus("Account permanently disabled.", "Check your message inbox for details"); + return; + } + if (resp == 14) { + showLoginScreenStatus("Sorry! This world is currently full.", "Please try a different world"); + worldFullTimeout = 1500; + return; + } + if (resp == 15) { + showLoginScreenStatus("You need a members account", "to login to this world"); + return; + } + if (resp == 16) { + showLoginScreenStatus("Error - no reply from loginserver.", "Please try again"); + return; + } + if (resp == 17) { + showLoginScreenStatus("Error - failed to decode profile.", "Contact customer support"); + return; + } + if (resp == 18) { + showLoginScreenStatus("Account suspected stolen.", "Press 'recover a locked account' on front page."); + return; + } + if (resp == 20) { + showLoginScreenStatus("Error - loginserver mismatch", "Please try a different world"); + return; + } + if (resp == 21) { + showLoginScreenStatus("Unable to login.", "That is not an RS-Classic account"); + return; + } + if (resp == 22) { + showLoginScreenStatus("Password suspected stolen.", "Press 'change your password' on front page."); + return; + } else { + showLoginScreenStatus("Error unable to login.", "Unrecognised response code"); + return; + } + } catch (Exception exception) { + System.out.println(String.valueOf(exception)); + } + if (autoLoginTimeout > 0) { + try { + Thread.sleep(5000L); + } catch (Exception Ex) { + } + autoLoginTimeout--; + login(username, password, reconnecting); + } + if (reconnecting) { + username = ""; + password = ""; + resetLoginVars(); + } else { + showLoginScreenStatus("Sorry! Unable to connect.", "Check internet settings or try another world"); + } + } + + protected void closeConnection() { + if (clientStream != null) + try { + clientStream.newPacket((Command.CL_CLOSE_CONNECTION)); + clientStream.flushPacket(); + } catch (IOException Ex) { + } + username = ""; + password = ""; + resetLoginVars(); + } + + protected void lostConnection() { + try { + throw new Exception(""); + } catch (Exception ex) { + System.out.println("loast connection: "); + ex.printStackTrace(); + } + System.out.println("Lost connection"); + autoLoginTimeout = 10; + login(username, password, true); + } + + protected void drawTextBox(String s, String s1) { + /*Graphics g = getGraphics(); + Font font = new Font("Helvetica", 1, 15); + char c = '\u0200'; + char c1 = '\u0158'; + g.setColor(Color.black); + g.fillRect(c / 2 - 140, c1 / 2 - 25, 280, 50); + g.setColor(Color.white); + g.drawRect(c / 2 - 140, c1 / 2 - 25, 280, 50); + drawString(g, s, font, c / 2, c1 / 2 - 10); + drawString(g, s1, font, c / 2, c1 / 2 + 10);*/ + } + + protected void checkConnection() { + long l = System.currentTimeMillis(); + if (clientStream.hasPacket()) + packetLastRead = l; + if (l - packetLastRead > 5000L) { + packetLastRead = l; + clientStream.newPacket((Command.CL_PING)); + clientStream.sendPacket(); + } + try { + clientStream.writePacket(20); + } catch (IOException Ex) { + lostConnection(); + return; + } + if (!method43()) + return; + int psize = clientStream.readPacket(incomingPacket); + if (psize > 0) { + int ptype = clientStream.isaacCommand(incomingPacket[0] & 0xff); + handlePacket(ptype, ptype, psize); + } + } + + private void handlePacket(int opcode, int ptype, int psize) { + //ptype = clientStream.isaacCommand(ptype); + //System.out.println(String.format("opcode:%s(%d) psize:%d", opcode.name(), ptype, psize)); + System.out.println("opcode:" + opcode + " psize:" + psize); + if (opcode == Command.SV_MESSAGE) { + String s = new String(incomingPacket, 1, psize - 1); + showServerMessage(s); + } + if (opcode == Command.SV_CLOSE_CONNECTION) + closeConnection(); + if (opcode == Command.SV_LOGOUT_DENY) { + cantLogout(); + return; + } + if (opcode == Command.SV_FRIEND_LIST) { + friendListCount = Utility.getUnsignedByte(incomingPacket[1]); + for (int k = 0; k < friendListCount; k++) { + friendListHashes[k] = Utility.getUnsignedLong(incomingPacket, 2 + k * 9); + friendListOnline[k] = Utility.getUnsignedByte(incomingPacket[10 + k * 9]); + } + + sortFriendsList(); + return; + } + if (opcode == Command.SV_FRIEND_STATUS_CHANGE) { + long hash = Utility.getUnsignedLong(incomingPacket, 1); + int online = incomingPacket[9] & 0xff; + for (int i2 = 0; i2 < friendListCount; i2++) + if (friendListHashes[i2] == hash) { + if (friendListOnline[i2] == 0 && online != 0) + showServerMessage("@pri@" + Utility.hash2username(hash) + " has logged in"); + if (friendListOnline[i2] != 0 && online == 0) + showServerMessage("@pri@" + Utility.hash2username(hash) + " has logged out"); + friendListOnline[i2] = online; + psize = 0; // not sure what this is for + sortFriendsList(); + return; + } + + friendListHashes[friendListCount] = hash; + friendListOnline[friendListCount] = online; + friendListCount++; + sortFriendsList(); + return; + } + if (opcode == Command.SV_IGNORE_LIST) { + ignoreListCount = Utility.getUnsignedByte(incomingPacket[1]); + for (int i1 = 0; i1 < ignoreListCount; i1++) + ignoreList[i1] = Utility.getUnsignedLong(incomingPacket, 2 + i1 * 8); + + return; + } + if (opcode == Command.SV_PRIVACY_SETTINGS) { + settingsBlockChat = incomingPacket[1]; + settingsBlockPrivate = incomingPacket[2]; + settingsBlockTrade = incomingPacket[3]; + settingsBlockDuel = incomingPacket[4]; + return; + } + if (opcode == Command.SV_FRIEND_MESSAGE) { + long from = Utility.getUnsignedLong(incomingPacket, 1); + int k1 = Utility.getUnsignedInt(incomingPacket, 9); // is this some sort of message id ? + for (int j2 = 0; j2 < maxSocialListSize; j2++) + if (anIntArray629[j2] == k1) + return; + + anIntArray629[anInt630] = k1; + anInt630 = (anInt630 + 1) % maxSocialListSize; + String msg = WordFilter.filter(ChatMessage.descramble(incomingPacket, 13, psize - 13)); + showServerMessage("@pri@" + Utility.hash2username(from) + ": tells you " + msg); + return; + } else { + handleIncomingPacket(opcode, ptype, psize, incomingPacket); + return; + } + } + + private void sortFriendsList() { + boolean flag = true; + while (flag) { + flag = false; + for (int i = 0; i < friendListCount - 1; i++) + if (friendListOnline[i] != 255 && friendListOnline[i + 1] == 255 || friendListOnline[i] == 0 && friendListOnline[i + 1] != 0) { + int j = friendListOnline[i]; + friendListOnline[i] = friendListOnline[i + 1]; + friendListOnline[i + 1] = j; + long l = friendListHashes[i]; + friendListHashes[i] = friendListHashes[i + 1]; + friendListHashes[i + 1] = l; + flag = true; + } + + } + } + + protected void sendPrivacySettings(int chat, int priv, int trade, int duel) { + clientStream.newPacket((Command.CL_SETTINGS_PRIVACY)); + clientStream.putByte(chat); + clientStream.putByte(priv); + clientStream.putByte(trade); + clientStream.putByte(duel); + clientStream.sendPacket(); + } + + protected void ignoreAdd(String s) { + long l = Utility.username2hash(s); + clientStream.newPacket((Command.CL_IGNORE_ADD)); + clientStream.putLong(l); + clientStream.sendPacket(); + for (int i = 0; i < ignoreListCount; i++) + if (ignoreList[i] == l) + return; + + if (ignoreListCount >= maxSocialListSize) { + return; + } else { + ignoreList[ignoreListCount++] = l; + return; + } + } + + protected void ignoreRemove(long l) { + clientStream.newPacket((Command.CL_IGNORE_REMOVE)); + clientStream.putLong(l); + clientStream.sendPacket(); + for (int i = 0; i < ignoreListCount; i++) + if (ignoreList[i] == l) { + ignoreListCount--; + for (int j = i; j < ignoreListCount; j++) + ignoreList[j] = ignoreList[j + 1]; + + return; + } + + } + + protected void friendAdd(String s) { + clientStream.newPacket((Command.CL_FRIEND_ADD)); + clientStream.putLong(Utility.username2hash(s)); + clientStream.sendPacket(); + long l = Utility.username2hash(s); + for (int i = 0; i < friendListCount; i++) + if (friendListHashes[i] == l) + return; + + if (friendListCount >= maxSocialListSize) { + return; + } else { + friendListHashes[friendListCount] = l; + friendListOnline[friendListCount] = 0; + friendListCount++; + return; + } + } + + protected void friendRemove(long l) { + clientStream.newPacket((Command.CL_FRIEND_REMOVE)); + clientStream.putLong(l); + clientStream.sendPacket(); + for (int i = 0; i < friendListCount; i++) { + if (friendListHashes[i] != l) + continue; + friendListCount--; + for (int j = i; j < friendListCount; j++) { + friendListHashes[j] = friendListHashes[j + 1]; + friendListOnline[j] = friendListOnline[j + 1]; + } + + break; + } + + showServerMessage("@pri@" + Utility.hash2username(l) + " has been removed from your friends list"); + } + + protected void sendPrivateMessage(long u, byte buff[], int len) { + clientStream.newPacket((Command.CL_PM)); + clientStream.putLong(u); + clientStream.putBytes(buff, 0, len); + clientStream.sendPacket(); + } + + protected void sendChatMessage(byte buff[], int len) { + clientStream.newPacket((Command.CL_CHAT)); + clientStream.putBytes(buff, 0, len); + clientStream.sendPacket(); + } + + protected void sendCommandString(String s) { + clientStream.newPacket((Command.CL_COMMAND)); + clientStream.putString(s); + clientStream.sendPacket(); + } + + protected void showLoginScreenStatus(String s, String s1) { + } + + protected void method37() { + } + + protected void resetGame() { + } + + protected void resetLoginVars() { + } + + protected void cantLogout() { + } + + protected void handleIncomingPacket(int opcode, int ptype, int len, byte data[]) { + } + + protected void showServerMessage(String s) { + } + + protected boolean method43() { + return true; + } + + protected int getLinkUID() { + return 0; + } + +} diff --git a/mudclient204-threadless/GameData.java b/mudclient204-threadless/GameData.java new file mode 100644 index 0000000..5af21ec --- /dev/null +++ b/mudclient204-threadless/GameData.java @@ -0,0 +1,474 @@ +public class GameData { + + public static String modelName[] = new String[5000]; + public static String textureName[]; + public static String textureSubtypeName[]; + public static int objectModelIndex[]; + public static int objectWidth[]; + public static int objectHeight[]; + public static int objectType[]; + public static int objectElevation[]; + public static int spellCount; + public static int npcWidth[]; + public static int npcHeight[]; + public static int npcSprite[][]; + public static int npcAttack[]; + public static int npcStrength[]; + public static int npcHits[]; + public static int npcDefense[]; + public static int npcAttackable[]; + public static int spellLevel[]; + public static int spellRunesRequired[]; + public static int spellType[]; + public static int spellRunesId[][]; + public static int spellRunesCount[][]; + //public static String unused[] = new String[5000]; + public static int itemCount; + public static int itemSpriteCount; + public static int npcColourHair[]; + public static int npcColourTop[]; + public static int npcColorBottom[]; + public static int npcColourSkin[]; + public static int wallObjectHeight[]; + public static int wallObjectTextureFront[]; + public static int wallObjectTextureBack[]; + public static int wallObjectAdjacent[]; + public static int wallObjectInvisible[]; + //public static String unused2[] = new String[5000]; + public static int tileCount; + public static int animationCharacterColour[]; + public static int animationSomething[]; + public static int animationHasA[]; + public static int animationHasF[]; + public static int animationNumber[]; + public static int wallObjectCount; + public static int prayerLevel[]; + public static int prayerDrain[]; + public static int tileDecoration[]; + public static int tileType[]; + public static int tileAdjacent[]; + public static int modelCount; + public static int roofHeight[]; + public static int roofNumVertices[]; + public static int prayerCount; + public static String itemName[]; + public static String itemDescription[]; + public static String itemCommand[]; + public static int projectileSprite; + public static int npcCount; + public static String spellName[]; + public static String spellDescription[]; + public static int textureCount; + public static String wallObjectName[]; + public static String wallObjectDescription[]; + public static String wallObjectCommand1[]; + public static String wallObjectCommand2[]; + public static int roofCount; + public static int objectCount; + public static String npcName[]; + public static String npcDescription[]; + public static String npcCommand[]; + public static String animationName[]; + public static int itemPicture[]; + public static int itemBasePrice[]; + public static int itemStackable[]; + public static int itemUnused[]; + public static int itemWearable[]; + public static int itemMask[]; + public static int itemSpecial[]; + public static int itemMembers[]; + public static int animationCount; + public static String prayerName[]; + public static String prayerDescription[]; + public static String objectName[]; + public static String objectDescription[]; + public static String objectCommand1[]; + public static String objectCommand2[]; + public static int npcWalkModel[]; + public static int npcCombatModel[]; + public static int npcCombatAnimation[]; + static byte dataString[]; + static byte dataInteger[]; + static int stringOffset; + static int offset; + + public static int getModelIndex(String s) { + if (s.equalsIgnoreCase("na")) + return 0; + for (int i = 0; i < modelCount; i++) + if (modelName[i].equalsIgnoreCase(s)) + return i; + + modelName[modelCount++] = s; + return modelCount - 1; + } + + public static int getUnsignedByte() { + int i = dataInteger[offset] & 0xff; + offset++; + return i; + } + + public static int getUnsignedShort() { + int i = Utility.getUnsignedShort(dataInteger, offset); + offset += 2; + return i; + } + + public static int getUnsignedInt() { + int i = Utility.getUnsignedInt(dataInteger, offset); + offset += 4; + if (i > 99999999) + i = 99999999 - i; + return i; + } + + public static String getString() { + String s; + for (s = ""; dataString[stringOffset] != 0; s = s + (char) dataString[stringOffset++]) ; + stringOffset++; + return s; + } + + public static void loadData(byte buffer[], boolean isMembers) { + dataString = Utility.loadData("string.dat", 0, buffer); + stringOffset = 0; + dataInteger = Utility.loadData("integer.dat", 0, buffer); + offset = 0; + + System.out.println("dataString " + dataString); + System.out.println("dataInteger " + dataInteger); + + int i; + + itemCount = getUnsignedShort(); + itemName = new String[itemCount]; + itemDescription = new String[itemCount]; + itemCommand = new String[itemCount]; + itemPicture = new int[itemCount]; + itemBasePrice = new int[itemCount]; + itemStackable = new int[itemCount]; + itemUnused = new int[itemCount]; + itemWearable = new int[itemCount]; + itemMask = new int[itemCount]; + itemSpecial = new int[itemCount]; + itemMembers = new int[itemCount]; + for (i = 0; i < itemCount; i++) + itemName[i] = getString(); + + for (i = 0; i < itemCount; i++) + itemDescription[i] = getString(); + + for (i = 0; i < itemCount; i++) + itemCommand[i] = getString(); + + for (i = 0; i < itemCount; i++) { + itemPicture[i] = getUnsignedShort(); + if (itemPicture[i] + 1 > itemSpriteCount) + itemSpriteCount = itemPicture[i] + 1; + } + + for (i = 0; i < itemCount; i++) + itemBasePrice[i] = getUnsignedInt(); + + for (i = 0; i < itemCount; i++) + itemStackable[i] = getUnsignedByte(); + + for (i = 0; i < itemCount; i++) + itemUnused[i] = getUnsignedByte(); + + for (i = 0; i < itemCount; i++) + itemWearable[i] = getUnsignedShort(); + + for (i = 0; i < itemCount; i++) + itemMask[i] = getUnsignedInt(); + + for (i = 0; i < itemCount; i++) + itemSpecial[i] = getUnsignedByte(); + + for (i = 0; i < itemCount; i++) + itemMembers[i] = getUnsignedByte(); + + for (i = 0; i < itemCount; i++) + if (!isMembers && itemMembers[i] == 1) { + itemName[i] = "Members object"; + itemDescription[i] = "You need to be a member to use this object"; + itemBasePrice[i] = 0; + itemCommand[i] = ""; + itemUnused[0] = 0; + itemWearable[i] = 0; + itemSpecial[i] = 1; + } + + npcCount = getUnsignedShort(); + npcName = new String[npcCount]; + npcDescription = new String[npcCount]; + npcCommand = new String[npcCount]; + npcAttack = new int[npcCount]; + npcStrength = new int[npcCount]; + npcHits = new int[npcCount]; + npcDefense = new int[npcCount]; + npcAttackable = new int[npcCount]; + npcSprite = new int[npcCount][12]; + npcColourHair = new int[npcCount]; + npcColourTop = new int[npcCount]; + npcColorBottom = new int[npcCount]; + npcColourSkin = new int[npcCount]; + npcWidth = new int[npcCount]; + npcHeight = new int[npcCount]; + npcWalkModel = new int[npcCount]; + npcCombatModel = new int[npcCount]; + npcCombatAnimation = new int[npcCount]; + for (i = 0; i < npcCount; i++) + npcName[i] = getString(); + + for (i = 0; i < npcCount; i++) + npcDescription[i] = getString(); + + for (i = 0; i < npcCount; i++) + npcAttack[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) + npcStrength[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) + npcHits[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) + npcDefense[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) + npcAttackable[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) { + for (int i5 = 0; i5 < 12; i5++) { + npcSprite[i][i5] = getUnsignedByte(); + if (npcSprite[i][i5] == 255) + npcSprite[i][i5] = -1; + } + + } + + for (i = 0; i < npcCount; i++) + npcColourHair[i] = getUnsignedInt(); + + for (i = 0; i < npcCount; i++) + npcColourTop[i] = getUnsignedInt(); + + for (i = 0; i < npcCount; i++) + npcColorBottom[i] = getUnsignedInt(); + + for (i = 0; i < npcCount; i++) + npcColourSkin[i] = getUnsignedInt(); + + for (i = 0; i < npcCount; i++) + npcWidth[i] = getUnsignedShort(); + + for (i = 0; i < npcCount; i++) + npcHeight[i] = getUnsignedShort(); + + for (i = 0; i < npcCount; i++) + npcWalkModel[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) + npcCombatModel[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) + npcCombatAnimation[i] = getUnsignedByte(); + + for (i = 0; i < npcCount; i++) + npcCommand[i] = getString(); + + textureCount = getUnsignedShort(); + textureName = new String[textureCount]; + textureSubtypeName = new String[textureCount]; + for (i = 0; i < textureCount; i++) + textureName[i] = getString(); + + for (i = 0; i < textureCount; i++) + textureSubtypeName[i] = getString(); + + animationCount = getUnsignedShort(); + animationName = new String[animationCount]; + animationCharacterColour = new int[animationCount]; + animationSomething = new int[animationCount]; + animationHasA = new int[animationCount]; + animationHasF = new int[animationCount]; + animationNumber = new int[animationCount]; + for (i = 0; i < animationCount; i++) + animationName[i] = getString(); + + for (i = 0; i < animationCount; i++) + animationCharacterColour[i] = getUnsignedInt(); + + for (i = 0; i < animationCount; i++) + animationSomething[i] = getUnsignedByte(); + + for (i = 0; i < animationCount; i++) + animationHasA[i] = getUnsignedByte(); + + for (i = 0; i < animationCount; i++) + animationHasF[i] = getUnsignedByte(); + + for (i = 0; i < animationCount; i++) + animationNumber[i] = getUnsignedByte(); + + objectCount = getUnsignedShort(); + objectName = new String[objectCount]; + objectDescription = new String[objectCount]; + objectCommand1 = new String[objectCount]; + objectCommand2 = new String[objectCount]; + objectModelIndex = new int[objectCount]; + objectWidth = new int[objectCount]; + objectHeight = new int[objectCount]; + objectType = new int[objectCount]; + objectElevation = new int[objectCount]; + for (i = 0; i < objectCount; i++) + objectName[i] = getString(); + + for (i = 0; i < objectCount; i++) + objectDescription[i] = getString(); + + for (i = 0; i < objectCount; i++) + objectCommand1[i] = getString(); + + for (i = 0; i < objectCount; i++) + objectCommand2[i] = getString(); + + for (i = 0; i < objectCount; i++) + objectModelIndex[i] = getModelIndex(getString()); + + for (i = 0; i < objectCount; i++) + objectWidth[i] = getUnsignedByte(); + + for (i = 0; i < objectCount; i++) + objectHeight[i] = getUnsignedByte(); + + for (i = 0; i < objectCount; i++) + objectType[i] = getUnsignedByte(); + + for (i = 0; i < objectCount; i++) + objectElevation[i] = getUnsignedByte(); + + wallObjectCount = getUnsignedShort(); + wallObjectName = new String[wallObjectCount]; + wallObjectDescription = new String[wallObjectCount]; + wallObjectCommand1 = new String[wallObjectCount]; + wallObjectCommand2 = new String[wallObjectCount]; + wallObjectHeight = new int[wallObjectCount]; + wallObjectTextureFront = new int[wallObjectCount]; + wallObjectTextureBack = new int[wallObjectCount]; + wallObjectAdjacent = new int[wallObjectCount]; + wallObjectInvisible = new int[wallObjectCount]; + for (i = 0; i < wallObjectCount; i++) + wallObjectName[i] = getString(); + + for (i = 0; i < wallObjectCount; i++) + wallObjectDescription[i] = getString(); + + for (i = 0; i < wallObjectCount; i++) + wallObjectCommand1[i] = getString(); + + for (i = 0; i < wallObjectCount; i++) + wallObjectCommand2[i] = getString(); + + for (i = 0; i < wallObjectCount; i++) + wallObjectHeight[i] = getUnsignedShort(); + + for (i = 0; i < wallObjectCount; i++) + wallObjectTextureFront[i] = getUnsignedInt(); + + for (i = 0; i < wallObjectCount; i++) + wallObjectTextureBack[i] = getUnsignedInt(); + + for (i = 0; i < wallObjectCount; i++) + wallObjectAdjacent[i] = getUnsignedByte();// what's this? + + for (i = 0; i < wallObjectCount; i++) + wallObjectInvisible[i] = getUnsignedByte();// value is 0 if visible + + roofCount = getUnsignedShort();// the World class does something with these + roofHeight = new int[roofCount]; + roofNumVertices = new int[roofCount]; + for (i = 0; i < roofCount; i++) + roofHeight[i] = getUnsignedByte(); + + for (i = 0; i < roofCount; i++) + roofNumVertices[i] = getUnsignedByte(); + + tileCount = getUnsignedShort();// and these + tileDecoration = new int[tileCount]; + tileType = new int[tileCount]; + tileAdjacent = new int[tileCount]; + for (i = 0; i < tileCount; i++) + tileDecoration[i] = getUnsignedInt(); + + for (i = 0; i < tileCount; i++) + tileType[i] = getUnsignedByte(); + + for (i = 0; i < tileCount; i++) + tileAdjacent[i] = getUnsignedByte(); + + projectileSprite = getUnsignedShort(); + spellCount = getUnsignedShort(); + spellName = new String[spellCount]; + spellDescription = new String[spellCount]; + spellLevel = new int[spellCount]; + spellRunesRequired = new int[spellCount]; + spellType = new int[spellCount]; + spellRunesId = new int[spellCount][]; + spellRunesCount = new int[spellCount][]; + for (i = 0; i < spellCount; i++) + spellName[i] = getString(); + + for (i = 0; i < spellCount; i++) + spellDescription[i] = getString(); + + for (i = 0; i < spellCount; i++) + spellLevel[i] = getUnsignedByte(); + + for (i = 0; i < spellCount; i++) + spellRunesRequired[i] = getUnsignedByte(); + + for (i = 0; i < spellCount; i++) + spellType[i] = getUnsignedByte(); + + for (i = 0; i < spellCount; i++) { + int j = getUnsignedByte(); + spellRunesId[i] = new int[j]; + for (int k = 0; k < j; k++) + spellRunesId[i][k] = getUnsignedShort(); + + } + + for (i = 0; i < spellCount; i++) { + int j = getUnsignedByte(); + spellRunesCount[i] = new int[j]; + for (int k = 0; k < j; k++) + spellRunesCount[i][k] = getUnsignedByte(); + + } + + prayerCount = getUnsignedShort(); + prayerName = new String[prayerCount]; + prayerDescription = new String[prayerCount]; + prayerLevel = new int[prayerCount]; + prayerDrain = new int[prayerCount]; + for (i = 0; i < prayerCount; i++) + prayerName[i] = getString(); + + for (i = 0; i < prayerCount; i++) + prayerDescription[i] = getString(); + + for (i = 0; i < prayerCount; i++) + prayerLevel[i] = getUnsignedByte(); + + for (i = 0; i < prayerCount; i++) + prayerDrain[i] = getUnsignedByte(); + + dataString = null; + dataInteger = null; + } + //public static int unused3; + +} diff --git a/mudclient204-threadless/GameFrame.java b/mudclient204-threadless/GameFrame.java new file mode 100644 index 0000000..51a48f5 --- /dev/null +++ b/mudclient204-threadless/GameFrame.java @@ -0,0 +1,64 @@ +/* +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent;*/ + +public class GameFrame { + int windowWidth; + int windowHeight; + int translationMode; + int windowYTranslation; + GameShell gameShell; + + public GameFrame(GameShell game, int width, int height, String title, boolean resizable, boolean flag1) { + windowYTranslation = 28; + windowWidth = width; + windowHeight = height; + this.gameShell = game; + + if (flag1) + windowYTranslation = 48; + else + windowYTranslation = 28; + + /* + setTitle(title); + setResizable(resizable); + setVisible(true); + toFront(); + setSize(windowWidth, windowHeight); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + gameShell.destroy(); + } + }); + */ + } + + /*public Graphics getGraphics() { + Graphics g = super.getGraphics(); + if (translationMode == 0) + g.translate(0, 24); + else + g.translate(-5, 0); + return g; + } + + public void setSize(int x, int y) { + super.setSize(x, y + windowYTranslation); + } + + protected void processEvent(AWTEvent e) { + if (e instanceof MouseEvent) { + MouseEvent evt = (MouseEvent) e; + e = new MouseEvent(evt.getComponent(), evt.getID(), evt.getWhen(), evt.getModifiers(), evt.getX(), evt.getY() - 24, evt.getClickCount(), evt.isPopupTrigger()); + } + super.processEvent(e); + } + + public void paint(Graphics g) { + gameShell.paint(g); + }*/ +} diff --git a/mudclient204-threadless/GameModel.java b/mudclient204-threadless/GameModel.java new file mode 100644 index 0000000..bdddcd4 --- /dev/null +++ b/mudclient204-threadless/GameModel.java @@ -0,0 +1,1031 @@ +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class GameModel { + + private static int sine9[]; + private static int sine11[]; + private static int base64Alphabet[]; + public int numVertices; + public int projectVertexX[]; + public int projectVertexY[]; + public int projectVertexZ[]; + public int vertexViewX[]; + public int vertexViewY[]; + public int vertexIntensity[]; + public byte vertexAmbience[]; + public int numFaces; + public int faceNumVertices[]; + public int faceVertices[][]; + public int faceFillFront[]; + public int faceFillBack[]; + public int normalMagnitude[]; + public int normalScale[]; + public int faceIntensity[]; + public int faceNormalX[]; + public int faceNormalY[]; + public int faceNormalZ[]; + public int depth; + public int transformState; + public boolean visible; + public int x1; + public int x2; + public int y1; + public int y2; + public int z1; + public int z2; + public boolean textureTranslucent; + public boolean transparent; + public int key; + public int faceTag[]; + public byte isLocalPlayer[]; + public boolean isolated; + public boolean unlit; + public boolean unpickable; + public boolean projected; + public int maxVerts; + public int vertexX[]; + public int vertexY[]; + public int vertexZ[]; + public int vertexTransformedX[]; + public int vertexTransformedY[]; + public int vertexTransformedZ[]; + protected int lightDiffuse; + protected int lightAmbience; + private boolean autocommit; + private int magic; + private int maxFaces; + private int faceTransStateThing[][]; + private int faceBoundLeft[]; + private int faceBoundRight[]; + private int faceBoundBottom[]; + private int faceBoundTop[]; + private int faceBoundNear[]; + private int faceBoundFar[]; + private int baseX; + private int baseY; + private int baseZ; + private int orientationYaw; + private int orientationPitch; + private int orientationRoll; + private int scaleFx; + private int scaleFy; + private int scaleFz; + private int shearXy; + private int shearXz; + private int shearYx; + private int shearYz; + private int shearZx; + private int shearZy; + private int transformKind; + private int diameter; + private int lightDirectionX; + private int lightDirectionY; + private int lightDirectionZ; + private int lightDirectionMagnitude; + private int dataPtr; + + static { + sine9 = new int[512]; + sine11 = new int[2048]; + + base64Alphabet = new int[256]; + for (int i = 0; i < 256; i++) { + sine9[i] = (int) (Math.sin((double) i * 0.02454369D) * 32768D); + sine9[i + 256] = (int) (Math.cos((double) i * 0.02454369D) * 32768D); + } + + for (int j = 0; j < 1024; j++) { + sine11[j] = (int) (Math.sin((double) j * 0.00613592315D) * 32768D); + sine11[j + 1024] = (int) (Math.cos((double) j * 0.00613592315D) * 32768D); + } + + for (int j1 = 0; j1 < 10; j1++) + base64Alphabet[48 + j1] = j1; + + for (int k1 = 0; k1 < 26; k1++) + base64Alphabet[65 + k1] = k1 + 10; + + for (int l1 = 0; l1 < 26; l1++) + base64Alphabet[97 + l1] = l1 + 36; + + base64Alphabet[163] = 62; + base64Alphabet[36] = 63; + } + + public GameModel(int numVertices, int numFaces) { + transformState = 1; + visible = true; + textureTranslucent = false; + transparent = false; + key = -1; + autocommit = false; + isolated = false; + unlit = false; + unpickable = false; + projected = false; + magic = World.colourTransparent; + diameter = World.colourTransparent; + lightDirectionX = 180; + lightDirectionY = 155; + lightDirectionZ = 95; + lightDirectionMagnitude = 256; + lightDiffuse = 512; + lightAmbience = 32; + allocate(numVertices, numFaces); + faceTransStateThing = new int[numFaces][1]; + for (int v = 0; v < numFaces; v++) + faceTransStateThing[v][0] = v; + + } + + public GameModel(int numVertices, int numFaces, boolean autocommit, boolean isolated, boolean unlit, boolean unpickable, boolean projected) { + transformState = 1; + visible = true; + textureTranslucent = false; + transparent = false; + key = -1; + magic = World.colourTransparent; + diameter = World.colourTransparent; + lightDirectionX = 180; + lightDirectionY = 155; + lightDirectionZ = 95; + lightDirectionMagnitude = 256; + lightDiffuse = 512; + lightAmbience = 32; + this.autocommit = autocommit; + this.isolated = isolated; + this.unlit = unlit; + this.unpickable = unpickable; + this.projected = projected; + allocate(numVertices, numFaces); + } + + public GameModel(byte data[], int offset, boolean unused) { + transformState = 1; + visible = true; + textureTranslucent = false; + transparent = false; + key = -1; + autocommit = false; + isolated = false; + unlit = false; + unpickable = false; + projected = false; + magic = World.colourTransparent; + diameter = World.colourTransparent; + lightDirectionX = 180; + lightDirectionY = 155; + lightDirectionZ = 95; + lightDirectionMagnitude = 256; + lightDiffuse = 512; + lightAmbience = 32; + int j = Utility.getUnsignedShort(data, offset); + offset += 2; + int k = Utility.getUnsignedShort(data, offset); + offset += 2; + allocate(j, k); + faceTransStateThing = new int[k][1]; + for (int l = 0; l < j; l++) { + vertexX[l] = Utility.getSignedShort(data, offset); + offset += 2; + } + + for (int i1 = 0; i1 < j; i1++) { + vertexY[i1] = Utility.getSignedShort(data, offset); + offset += 2; + } + + for (int j1 = 0; j1 < j; j1++) { + vertexZ[j1] = Utility.getSignedShort(data, offset); + offset += 2; + } + + numVertices = j; + for (int k1 = 0; k1 < k; k1++) + faceNumVertices[k1] = data[offset++] & 0xff; + + for (int l1 = 0; l1 < k; l1++) { + faceFillFront[l1] = Utility.getSignedShort(data, offset); + offset += 2; + if (faceFillFront[l1] == 32767) + faceFillFront[l1] = magic; + } + + for (int i2 = 0; i2 < k; i2++) { + faceFillBack[i2] = Utility.getSignedShort(data, offset); + offset += 2; + if (faceFillBack[i2] == 32767) + faceFillBack[i2] = magic; + } + + for (int j2 = 0; j2 < k; j2++) { + int k2 = data[offset++] & 0xff; + if (k2 == 0) + faceIntensity[j2] = 0; + else + faceIntensity[j2] = magic; + } + + for (int l2 = 0; l2 < k; l2++) { + faceVertices[l2] = new int[faceNumVertices[l2]]; + for (int i3 = 0; i3 < faceNumVertices[l2]; i3++) + if (j < 256) { + faceVertices[l2][i3] = data[offset++] & 0xff; + } else { + faceVertices[l2][i3] = Utility.getUnsignedShort(data, offset); + offset += 2; + } + + } + + numFaces = k; + transformState = 1; + } + + public GameModel(String name) { + transformState = 1; + visible = true; + textureTranslucent = false; + transparent = false; + key = -1; + autocommit = false; + isolated = false; + unlit = false; + unpickable = false; + projected = false; + magic = World.colourTransparent; + diameter = World.colourTransparent; + lightDirectionX = 180; + lightDirectionY = 155; + lightDirectionZ = 95; + lightDirectionMagnitude = 256; + lightDiffuse = 512; + lightAmbience = 32; + byte data[]; + try { + InputStream inputstream = Utility.openFile(name); + DataInputStream datainputstream = new DataInputStream(inputstream); + data = new byte[3]; + dataPtr = 0; + for (int i = 0; i < 3; i += datainputstream.read(data, i, 3 - i)) ; + int sz = readBase64(data); + data = new byte[sz]; + dataPtr = 0; + for (int j = 0; j < sz; j += datainputstream.read(data, j, sz - j)) ; + datainputstream.close(); + } catch (IOException Ex) { + numVertices = 0; + numFaces = 0; + return; + } + int nV = readBase64(data); + int nF = readBase64(data); + allocate(nV, nF); + faceTransStateThing = new int[nF][]; + for (int j3 = 0; j3 < nV; j3++) { + int x = readBase64(data); + int y = readBase64(data); + int z = readBase64(data); + vertexAt(x, y, z); + } + + for (int k3 = 0; k3 < nF; k3++) { + int n = readBase64(data); + int front = readBase64(data); + int back = readBase64(data); + int l2 = readBase64(data); + lightDiffuse = readBase64(data); + lightAmbience = readBase64(data); + int gouraud = readBase64(data); + int vs[] = new int[n]; + for (int i = 0; i < n; i++) + vs[i] = readBase64(data); + + int ai1[] = new int[l2]; + for (int i4 = 0; i4 < l2; i4++) + ai1[i4] = readBase64(data); + + int j4 = createFace(n, vs, front, back); + faceTransStateThing[k3] = ai1; + if (gouraud == 0) + faceIntensity[j4] = 0; + else + faceIntensity[j4] = magic; + } + + transformState = 1; + } + + public GameModel(GameModel pieces[], int count, boolean autocommit, boolean isolated, boolean unlit, boolean unpickable) { + transformState = 1; + visible = true; + textureTranslucent = false; + transparent = false; + key = -1; + projected = false; + magic = World.colourTransparent; + diameter = World.colourTransparent; + lightDirectionX = 180; + lightDirectionY = 155; + lightDirectionZ = 95; + lightDirectionMagnitude = 256; + lightDiffuse = 512; + lightAmbience = 32; + this.autocommit = autocommit; + this.isolated = isolated; + this.unlit = unlit; + this.unpickable = unpickable; + merge(pieces, count, false); + } + + public GameModel(GameModel pieces[], int count) { + transformState = 1; + visible = true; + textureTranslucent = false; + transparent = false; + key = -1; + autocommit = false; + isolated = false; + unlit = false; + unpickable = false; + projected = false; + magic = World.colourTransparent; + diameter = World.colourTransparent; + lightDirectionX = 180; + lightDirectionY = 155; + lightDirectionZ = 95; + lightDirectionMagnitude = 256; + lightDiffuse = 512; + lightAmbience = 32; + merge(pieces, count, true); + } + + private void allocate(int numV, int numF) { + vertexX = new int[numV]; + vertexY = new int[numV]; + vertexZ = new int[numV]; + vertexIntensity = new int[numV]; + vertexAmbience = new byte[numV]; + faceNumVertices = new int[numF]; + faceVertices = new int[numF][]; + faceFillFront = new int[numF]; + faceFillBack = new int[numF]; + faceIntensity = new int[numF]; + normalScale = new int[numF]; + normalMagnitude = new int[numF]; + if (!projected) { + projectVertexX = new int[numV]; + projectVertexY = new int[numV]; + projectVertexZ = new int[numV]; + vertexViewX = new int[numV]; + vertexViewY = new int[numV]; + } + if (!unpickable) { + isLocalPlayer = new byte[numF]; + faceTag = new int[numF]; + } + if (autocommit) { + vertexTransformedX = vertexX; + vertexTransformedY = vertexY; + vertexTransformedZ = vertexZ; + } else { + vertexTransformedX = new int[numV]; + vertexTransformedY = new int[numV]; + vertexTransformedZ = new int[numV]; + } + if (!unlit || !isolated) { + faceNormalX = new int[numF]; + faceNormalY = new int[numF]; + faceNormalZ = new int[numF]; + } + if (!isolated) { + faceBoundLeft = new int[numF]; + faceBoundRight = new int[numF]; + faceBoundBottom = new int[numF]; + faceBoundTop = new int[numF]; + faceBoundNear = new int[numF]; + faceBoundFar = new int[numF]; + } + numFaces = 0; + numVertices = 0; + maxVerts = numV; + maxFaces = numF; + baseX = baseY = baseZ = 0; + orientationYaw = orientationPitch = orientationRoll = 0; + scaleFx = scaleFy = scaleFz = 256; + shearXy = shearXz = shearYx = shearYz = shearZx = shearZy = 256; + transformKind = 0; + } + + public void projectionPrepare() { + projectVertexX = new int[numVertices]; + projectVertexY = new int[numVertices]; + projectVertexZ = new int[numVertices]; + vertexViewX = new int[numVertices]; + vertexViewY = new int[numVertices]; + } + + public void clear() { + numFaces = 0; + numVertices = 0; + } + + public void reduce(int df, int dz) { + numFaces -= df; + if (numFaces < 0) + numFaces = 0; + numVertices -= dz; + if (numVertices < 0) + numVertices = 0; + } + + public void merge(GameModel pieces[], int count, boolean transState) { + int numF = 0; + int numV = 0; + for (int i = 0; i < count; i++) { + numF += pieces[i].numFaces; + numV += pieces[i].numVertices; + } + + allocate(numV, numF); + if (transState) + faceTransStateThing = new int[numF][]; + for (int i = 0; i < count; i++) { + GameModel source = pieces[i]; + source.commit(); + lightAmbience = source.lightAmbience; + lightDiffuse = source.lightDiffuse; + lightDirectionX = source.lightDirectionX; + lightDirectionY = source.lightDirectionY; + lightDirectionZ = source.lightDirectionZ; + lightDirectionMagnitude = source.lightDirectionMagnitude; + for (int srcF = 0; srcF < source.numFaces; srcF++) { + int dstVs[] = new int[source.faceNumVertices[srcF]]; + int srcVs[] = source.faceVertices[srcF]; + for (int v = 0; v < source.faceNumVertices[srcF]; v++) + dstVs[v] = vertexAt(source.vertexX[srcVs[v]], source.vertexY[srcVs[v]], source.vertexZ[srcVs[v]]); + + int dstF = createFace(source.faceNumVertices[srcF], dstVs, source.faceFillFront[srcF], source.faceFillBack[srcF]); + faceIntensity[dstF] = source.faceIntensity[srcF]; + normalScale[dstF] = source.normalScale[srcF]; + normalMagnitude[dstF] = source.normalMagnitude[srcF]; + if (transState) + if (count > 1) { + faceTransStateThing[dstF] = new int[source.faceTransStateThing[srcF].length + 1]; + faceTransStateThing[dstF][0] = i; + for (int i2 = 0; i2 < source.faceTransStateThing[srcF].length; i2++) + faceTransStateThing[dstF][i2 + 1] = source.faceTransStateThing[srcF][i2]; + + } else { + faceTransStateThing[dstF] = new int[source.faceTransStateThing[srcF].length]; + for (int j2 = 0; j2 < source.faceTransStateThing[srcF].length; j2++) + faceTransStateThing[dstF][j2] = source.faceTransStateThing[srcF][j2]; + + } + } + + } + + transformState = 1; + } + + public int vertexAt(int x, int y, int z) { + for (int l = 0; l < numVertices; l++) + if (vertexX[l] == x && vertexY[l] == y && vertexZ[l] == z) + return l; + + if (numVertices >= maxVerts) { + return -1; + } else { + vertexX[numVertices] = x; + vertexY[numVertices] = y; + vertexZ[numVertices] = z; + return numVertices++; + } + } + + public int createVertex(int i, int j, int k) { + if (numVertices >= maxVerts) { + return -1; + } else { + vertexX[numVertices] = i; + vertexY[numVertices] = j; + vertexZ[numVertices] = k; + return numVertices++; + } + } + + public int createFace(int n, int vs[], int front, int back) { + if (numFaces >= maxFaces) { + return -1; + } else { + faceNumVertices[numFaces] = n; + faceVertices[numFaces] = vs; + faceFillFront[numFaces] = front; + faceFillBack[numFaces] = back; + transformState = 1; + return numFaces++; + } + } + + public GameModel[] split(int unused1, int unused2, int pieceDx, int pieceDz, int rows, int count, int pieceMaxVertices, boolean pickable) { + commit(); + int pieceNV[] = new int[count]; + int pieceNF[] = new int[count]; + for (int i = 0; i < count; i++) { + pieceNV[i] = 0; + pieceNF[i] = 0; + } + + for (int f = 0; f < numFaces; f++) { + int sumX = 0; + int sumZ = 0; + int n = faceNumVertices[f]; + int vs[] = faceVertices[f]; + for (int i = 0; i < n; i++) { + sumX += vertexX[vs[i]]; + sumZ += vertexZ[vs[i]]; + } + + int p = sumX / (n * pieceDx) + (sumZ / (n * pieceDz)) * rows; + pieceNV[p] += n; + pieceNF[p]++; + } + + GameModel pieces[] = new GameModel[count]; + for (int i = 0; i < count; i++) { + if (pieceNV[i] > pieceMaxVertices) + pieceNV[i] = pieceMaxVertices; + pieces[i] = new GameModel(pieceNV[i], pieceNF[i], true, true, true, pickable, true); + pieces[i].lightDiffuse = lightDiffuse; + pieces[i].lightAmbience = lightAmbience; + } + + for (int f = 0; f < numFaces; f++) { + int sumX = 0; + int sumZ = 0; + int n = faceNumVertices[f]; + int vs[] = faceVertices[f]; + for (int i = 0; i < n; i++) { + sumX += vertexX[vs[i]]; + sumZ += vertexZ[vs[i]]; + } + + int p = sumX / (n * pieceDx) + (sumZ / (n * pieceDz)) * rows; + copyLighting(pieces[p], vs, n, f); + } + + for (int p = 0; p < count; p++) + pieces[p].projectionPrepare(); + + return pieces; + } + + public void copyLighting(GameModel model, int srcVs[], int nV, int inF) { + int dstVs[] = new int[nV]; + for (int inV = 0; inV < nV; inV++) { + int outV = dstVs[inV] = model.vertexAt(vertexX[srcVs[inV]], vertexY[srcVs[inV]], vertexZ[srcVs[inV]]); + model.vertexIntensity[outV] = vertexIntensity[srcVs[inV]]; + model.vertexAmbience[outV] = vertexAmbience[srcVs[inV]]; + } + + int outF = model.createFace(nV, dstVs, faceFillFront[inF], faceFillBack[inF]); + if (!model.unpickable && !unpickable) + model.faceTag[outF] = faceTag[inF]; + model.faceIntensity[outF] = faceIntensity[inF]; + model.normalScale[outF] = normalScale[inF]; + model.normalMagnitude[outF] = normalMagnitude[inF]; + } + + public void setLight(boolean gouraud, int ambient, int diffuse, int x, int y, int z) { + lightAmbience = 256 - ambient * 4; + lightDiffuse = (64 - diffuse) * 16 + 128; + if (unlit) + return; + for (int i = 0; i < numFaces; i++) + if (gouraud) + faceIntensity[i] = magic; + else + faceIntensity[i] = 0; + + lightDirectionX = x; + lightDirectionY = y; + lightDirectionZ = z; + lightDirectionMagnitude = (int) Math.sqrt(x * x + y * y + z * z); + light(); + } + + public void setLight(int ambience, int diffuse, int x, int y, int z) { + lightAmbience = 256 - ambience * 4; + lightDiffuse = (64 - diffuse) * 16 + 128; + if (!unlit) { + lightDirectionX = x; + lightDirectionY = y; + lightDirectionZ = z; + lightDirectionMagnitude = (int) Math.sqrt(x * x + y * y + z * z); + light(); + } + } + + public void setLight(int x, int y, int z) { + if (!unlit) { + lightDirectionX = x; + lightDirectionY = y; + lightDirectionZ = z; + lightDirectionMagnitude = (int) Math.sqrt(x * x + y * y + z * z); + light(); + } + } + + public void setVertexAmbience(int v, int ambience) { + vertexAmbience[v] = (byte) ambience; + } + + public void rotate(int yaw, int pitch, int roll) { + orientationYaw = orientationYaw + yaw & 0xff; + orientationPitch = orientationPitch + pitch & 0xff; + orientationRoll = orientationRoll + roll & 0xff; + determineTransformKind(); + transformState = 1; + } + + public void orient(int yaw, int pitch, int roll) { + orientationYaw = yaw & 0xff; + orientationPitch = pitch & 0xff; + orientationRoll = roll & 0xff; + determineTransformKind(); + transformState = 1; + } + + public void translate(int x, int y, int z) { + baseX += x; + baseY += y; + baseZ += z; + determineTransformKind(); + transformState = 1; + } + + public void place(int x, int y, int z) { + baseX = x; + baseY = y; + baseZ = z; + determineTransformKind(); + transformState = 1; + } + + private void determineTransformKind() { + if (shearXy != 256 || shearXz != 256 || shearYx != 256 || shearYz != 256 || shearZx != 256 || shearZy != 256) { + transformKind = 4; + } else if (scaleFx != 256 || scaleFy != 256 || scaleFz != 256) { + transformKind = 3; + } else if (orientationYaw != 0 || orientationPitch != 0 || orientationRoll != 0) { + transformKind = 2; + } else if (baseX != 0 || baseY != 0 || baseZ != 0) { + transformKind = 1; + } else { + transformKind = 0; + } + } + + private void applyTranslate(int dx, int dy, int dz) { + for (int v = 0; v < numVertices; v++) { + vertexTransformedX[v] += dx; + vertexTransformedY[v] += dy; + vertexTransformedZ[v] += dz; + } + + } + + private void applyRotation(int yaw, int roll, int pitch) { + for (int v = 0; v < numVertices; v++) { + if (pitch != 0) { + int sin = sine9[pitch]; + int cos = sine9[pitch + 256]; + int x = vertexTransformedY[v] * sin + vertexTransformedX[v] * cos >> 15; + vertexTransformedY[v] = vertexTransformedY[v] * cos - vertexTransformedX[v] * sin >> 15; + vertexTransformedX[v] = x; + } + if (yaw != 0) { + int sin = sine9[yaw]; + int cos = sine9[yaw + 256]; + int y = vertexTransformedY[v] * cos - vertexTransformedZ[v] * sin >> 15; + vertexTransformedZ[v] = vertexTransformedY[v] * sin + vertexTransformedZ[v] * cos >> 15; + vertexTransformedY[v] = y; + } + if (roll != 0) { + int sin = sine9[roll]; + int cos = sine9[roll + 256]; + int x = vertexTransformedZ[v] * sin + vertexTransformedX[v] * cos >> 15; + vertexTransformedZ[v] = vertexTransformedZ[v] * cos - vertexTransformedX[v] * sin >> 15; + vertexTransformedX[v] = x; + } + } + + } + + private void applyShear(int xy, int xz, int yx, int yz, int zx, int zy) { + for (int idx = 0; idx < numVertices; idx++) { + if (xy != 0) + vertexTransformedX[idx] += vertexTransformedY[idx] * xy >> 8; + if (xz != 0) + vertexTransformedZ[idx] += vertexTransformedY[idx] * xz >> 8; + if (yx != 0) + vertexTransformedX[idx] += vertexTransformedZ[idx] * yx >> 8; + if (yz != 0) + vertexTransformedY[idx] += vertexTransformedZ[idx] * yz >> 8; + if (zx != 0) + vertexTransformedZ[idx] += vertexTransformedX[idx] * zx >> 8; + if (zy != 0) + vertexTransformedY[idx] += vertexTransformedX[idx] * zy >> 8; + } + + } + + private void applyScale(int fx, int fy, int fz) { + for (int v = 0; v < numVertices; v++) { + vertexTransformedX[v] = vertexTransformedX[v] * fx >> 8; + vertexTransformedY[v] = vertexTransformedY[v] * fy >> 8; + vertexTransformedZ[v] = vertexTransformedZ[v] * fz >> 8; + } + + } + + private void computeBounds() { + x1 = y1 = z1 = 0xf423f; + diameter = x2 = y2 = z2 = 0xfff0bdc1; + for (int face = 0; face < numFaces; face++) { + int vs[] = faceVertices[face]; + int v = vs[0]; + int n = faceNumVertices[face]; + int x1; + int x2 = x1 = vertexTransformedX[v]; + int y1; + int y2 = y1 = vertexTransformedY[v]; + int z1; + int z2 = z1 = vertexTransformedZ[v]; + for (int i = 0; i < n; i++) { + v = vs[i]; + if (vertexTransformedX[v] < x1) + x1 = vertexTransformedX[v]; + else if (vertexTransformedX[v] > x2) + x2 = vertexTransformedX[v]; + if (vertexTransformedY[v] < y1) + y1 = vertexTransformedY[v]; + else if (vertexTransformedY[v] > y2) + y2 = vertexTransformedY[v]; + if (vertexTransformedZ[v] < z1) + z1 = vertexTransformedZ[v]; + else if (vertexTransformedZ[v] > z2) + z2 = vertexTransformedZ[v]; + } + + if (!isolated) { + faceBoundLeft[face] = x1; + faceBoundRight[face] = x2; + faceBoundBottom[face] = y1; + faceBoundTop[face] = y2; + faceBoundNear[face] = z1; + faceBoundFar[face] = z2; + } + if (x2 - x1 > diameter) + diameter = x2 - x1; + if (y2 - y1 > diameter) + diameter = y2 - y1; + if (z2 - z1 > diameter) + diameter = z2 - z1; + if (x1 < this.x1) + this.x1 = x1; + if (x2 > this.x2) + this.x2 = x2; + if (y1 < this.y1) + this.y1 = y1; + if (y2 > this.y2) + this.y2 = y2; + if (z1 < this.z1) + this.z1 = z1; + if (z2 > this.z2) + this.z2 = z2; + } + + } + + public void light() { + if (unlit) + return; + int divisor = lightDiffuse * lightDirectionMagnitude >> 8; + for (int face = 0; face < numFaces; face++) + if (faceIntensity[face] != magic) + faceIntensity[face] = (faceNormalX[face] * lightDirectionX + faceNormalY[face] * lightDirectionY + faceNormalZ[face] * lightDirectionZ) / divisor; + + int normalX[] = new int[numVertices]; + int normalY[] = new int[numVertices]; + int normalZ[] = new int[numVertices]; + int normalMagnitude[] = new int[numVertices]; + for (int k = 0; k < numVertices; k++) { + normalX[k] = 0; + normalY[k] = 0; + normalZ[k] = 0; + normalMagnitude[k] = 0; + } + + for (int face = 0; face < numFaces; face++) + if (faceIntensity[face] == magic) { + for (int v = 0; v < faceNumVertices[face]; v++) { + int k1 = faceVertices[face][v]; + normalX[k1] += faceNormalX[face]; + normalY[k1] += faceNormalY[face]; + normalZ[k1] += faceNormalZ[face]; + normalMagnitude[k1]++; + } + + } + + for (int v = 0; v < numVertices; v++) + if (normalMagnitude[v] > 0) + vertexIntensity[v] = (normalX[v] * lightDirectionX + normalY[v] * lightDirectionY + normalZ[v] * lightDirectionZ) / (divisor * normalMagnitude[v]); + + } + + public void relight() { + if (unlit && isolated) + return; + for (int face = 0; face < numFaces; face++) { + int verts[] = faceVertices[face]; + int aX = vertexTransformedX[verts[0]]; + int aY = vertexTransformedY[verts[0]]; + int aZ = vertexTransformedZ[verts[0]]; + int bX = vertexTransformedX[verts[1]] - aX; + int bY = vertexTransformedY[verts[1]] - aY; + int bZ = vertexTransformedZ[verts[1]] - aZ; + int cX = vertexTransformedX[verts[2]] - aX; + int cY = vertexTransformedY[verts[2]] - aY; + int cZ = vertexTransformedZ[verts[2]] - aZ; + int normX = bY * cZ - cY * bZ; + int normY = bZ * cX - cZ * bX; + int normZ; + for (normZ = bX * cY - cX * bY; normX > 8192 || normY > 8192 || normZ > 8192 || normX < -8192 || normY < -8192 || normZ < -8192; normZ >>= 1) { + normX >>= 1; + normY >>= 1; + } + + int normMag = (int) (256D * Math.sqrt(normX * normX + normY * normY + normZ * normZ)); + if (normMag <= 0) + normMag = 1; + faceNormalX[face] = (normX * 0x10000) / normMag; + faceNormalY[face] = (normY * 0x10000) / normMag; + faceNormalZ[face] = (normZ * 65535) / normMag; + normalScale[face] = -1; + } + + light(); + } + + public void apply() { + if (transformState == 2) { + transformState = 0; + for (int v = 0; v < numVertices; v++) { + vertexTransformedX[v] = vertexX[v]; + vertexTransformedY[v] = vertexY[v]; + vertexTransformedZ[v] = vertexZ[v]; + } + + x1 = y1 = z1 = 0xff676981; + diameter = x2 = y2 = z2 = 0x98967f; + return; + } + if (transformState == 1) { + transformState = 0; + for (int v = 0; v < numVertices; v++) { + vertexTransformedX[v] = vertexX[v]; + vertexTransformedY[v] = vertexY[v]; + vertexTransformedZ[v] = vertexZ[v]; + } + + if (transformKind >= 2) + applyRotation(orientationYaw, orientationPitch, orientationRoll); + if (transformKind >= 3) + applyScale(scaleFx, scaleFy, scaleFz); + if (transformKind >= 4) + applyShear(shearXy, shearXz, shearYx, shearYz, shearZx, shearZy); + if (transformKind >= 1) + applyTranslate(baseX, baseY, baseZ); + computeBounds(); + relight(); + } + } + + public void project(int cameraX, int cameraY, int cameraZ, int cameraPitch, int cameraRoll, int cameraYaw, int viewDist, int clipNear) { + apply(); + if (z1 > Scene.frustumNearZ || z2 < Scene.furstumFarZ || x1 > Scene.frustumMinX || x2 < Scene.frustumMaxX || y1 > Scene.furstumMinY || y2 < Scene.furstumMaxY) { + visible = false; + return; + } + visible = true; + int yawSin = 0; + int yawCos = 0; + int pitchSin = 0; + int pitchCos = 0; + int rollSin = 0; + int rollCos = 0; + if (cameraYaw != 0) { + yawSin = sine11[cameraYaw]; + yawCos = sine11[cameraYaw + 1024]; + } + if (cameraRoll != 0) { + rollSin = sine11[cameraRoll]; + rollCos = sine11[cameraRoll + 1024]; + } + if (cameraPitch != 0) { + pitchSin = sine11[cameraPitch]; + pitchCos = sine11[cameraPitch + 1024]; + } + for (int v = 0; v < numVertices; v++) { + int x = vertexTransformedX[v] - cameraX; + int y = vertexTransformedY[v] - cameraY; + int z = vertexTransformedZ[v] - cameraZ; + if (cameraYaw != 0) { + int X = y * yawSin + x * yawCos >> 15; + y = y * yawCos - x * yawSin >> 15; + x = X; + } + if (cameraRoll != 0) { + int X = z * rollSin + x * rollCos >> 15; + z = z * rollCos - x * rollSin >> 15; + x = X; + } + if (cameraPitch != 0) { + int Y = y * pitchCos - z * pitchSin >> 15; + z = y * pitchSin + z * pitchCos >> 15; + y = Y; + } + if (z >= clipNear) + vertexViewX[v] = (x << viewDist) / z; + else + vertexViewX[v] = x << viewDist; + if (z >= clipNear) + vertexViewY[v] = (y << viewDist) / z; + else + vertexViewY[v] = y << viewDist; + projectVertexX[v] = x; + projectVertexY[v] = y; + projectVertexZ[v] = z; + } + + } + + public void commit() { + apply(); + for (int i = 0; i < numVertices; i++) { + vertexX[i] = vertexTransformedX[i]; + vertexY[i] = vertexTransformedY[i]; + vertexZ[i] = vertexTransformedZ[i]; + } + + baseX = baseY = baseZ = 0; + orientationYaw = orientationPitch = orientationRoll = 0; + scaleFx = scaleFy = scaleFz = 256; + shearXy = shearXz = shearYx = shearYz = shearZx = shearZy = 256; + transformKind = 0; + } + + public GameModel copy() { + GameModel pieces[] = new GameModel[1]; + pieces[0] = this; + GameModel gameModel = new GameModel(pieces, 1); + gameModel.depth = depth; + gameModel.transparent = transparent; + return gameModel; + } + + public GameModel copy(boolean autocommit, boolean isolated, boolean unlit, boolean pickable) { + GameModel pieces[] = new GameModel[1]; + pieces[0] = this; + GameModel gameModel = new GameModel(pieces, 1, autocommit, isolated, unlit, pickable); + gameModel.depth = depth; + return gameModel; + } + + public void copyPosition(GameModel model) { + orientationYaw = model.orientationYaw; + orientationPitch = model.orientationPitch; + orientationRoll = model.orientationRoll; + baseX = model.baseX; + baseY = model.baseY; + baseZ = model.baseZ; + determineTransformKind(); + transformState = 1; + } + + public int readBase64(byte buff[]) { + for (; buff[dataPtr] == 10 || buff[dataPtr] == 13; dataPtr++) ; + int hi = base64Alphabet[buff[dataPtr++] & 0xff]; + int mid = base64Alphabet[buff[dataPtr++] & 0xff]; + int lo = base64Alphabet[buff[dataPtr++] & 0xff]; + int val = (hi * 4096 + mid * 64 + lo) - 0x20000; + if (val == 0x1e240) + val = magic; + return val; + } +} diff --git a/mudclient204-threadless/GameShell.java b/mudclient204-threadless/GameShell.java new file mode 100644 index 0000000..28f54fa --- /dev/null +++ b/mudclient204-threadless/GameShell.java @@ -0,0 +1,565 @@ +import java.io.DataInputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.URL; + +class KeyEvent { + static final int VK_LEFT = -12345678; + static final int VK_RIGHT = -12345678; + static final int VK_UP = -12345678; + static final int VK_DOWN = -12345678; + static final int VK_SPACE = -12345678; + static final int VK_F1 = -12345678; + static final int VK_BACK_SPACE = -12345678; + static final int VK_ENTER = -12345678; +} + +public class GameShell { + public static GameFrame gameFrame = null; + private static String charMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"\243$%^&*()-_=+[{]};:'@#~,<.>/?\\| "; + public int mouseActionTimeout; + public int loadingStep; + public String logoHeaderText; + public boolean keyLeft; + public boolean keyRight; + public boolean keyUp; + public boolean keyDown; + public boolean keySpace; + public int threadSleep; + public int mouseX; + public int mouseY; + public int mouseButtonDown; + public int lastMouseButtonDown; + public boolean interlace; + public String inputTextCurrent; + public String inputTextFinal; + public String inputPmCurrent; + public String inputPmFinal; + public int appletWidth; + public int appletHeight; + //private Thread appletThread; + private int targetFps; + private int maxDrawTime; + private long timings[]; + private boolean startedAsApplet; + private int stopTimeout; + private int interlaceTimer; + private boolean hasRefererLogoNotused; + private int loadingProgressPercent; + private String loadingProgessText; + /* + private Font fontTimesRoman15; + private Font fontHelvetica13b; + private Font fontHelvetica12; + private Image imageLogo;*/ + protected int fps; + + public GameShell() { + appletWidth = 512; + appletHeight = 344; + targetFps = 20; + maxDrawTime = 1000; + timings = new long[10]; + loadingStep = 1; + hasRefererLogoNotused = false; + loadingProgessText = "Loading"; + /* + fontTimesRoman15 = new Font("TimesRoman", 0, 15); + fontHelvetica13b = new Font("Helvetica", Font.BOLD, 13); + fontHelvetica12 = new Font("Helvetica", 0, 12);*/ + keyLeft = false; + keyRight = false; + keyUp = false; + keyDown = false; + keySpace = false; + threadSleep = 1; + interlace = false; + inputTextCurrent = ""; + inputTextFinal = ""; + inputPmCurrent = ""; + inputPmFinal = ""; + } + + private void dummy() { + this.keyPressed('A', 97); + this.keyReleased(97); + this.mouseMoved(0, 0); + this.mouseReleased(0, 0); + this.mousePressed(0, 0, 0); + this.mouseDragged(0, 0, 0); + } + + protected void startGame() { + } + + protected synchronized void handleInputs() { + } + + protected void onClosing() { + } + + protected synchronized void draw() { + } + + protected void startApplication(int width, int height, String title, boolean resizeable) { + startedAsApplet = false; + System.out.println("Started application"); + appletWidth = width; + appletHeight = height; + gameFrame = new GameFrame(this, width, height, title, resizeable, false); + loadingStep = 1; + //appletThread = new Thread(this); + //appletThread.start(); + //appletThread.setPriority(1); + dummy(); + start(); + run(); + } + + protected void setTargetFps(int i) { + targetFps = 1000 / i; + } + + protected void resetTimings() { + for (int i = 0; i < 10; i++) { + timings[i] = 0L; + } + } + + public synchronized void keyPressed(char chr, int code) { + handleKeyPress(chr); + mouseActionTimeout = 0; + + if (code == KeyEvent.VK_LEFT) { + keyLeft = true; + } else if (code == KeyEvent.VK_RIGHT) { + keyRight = true; + } else if (code == KeyEvent.VK_UP) { + keyUp = true; + } else if (code == KeyEvent.VK_DOWN) { + keyDown = true; + } else if (code == KeyEvent.VK_SPACE) { + keySpace = true; + } else if (code == KeyEvent.VK_F1) { + interlace = !interlace; + } else { + boolean foundText = false; + + for (int i = 0; i < charMap.length(); i++) { + if (charMap.charAt(i) == chr) { + foundText = true; + break; + } + } + + if (foundText) { + if (inputTextCurrent.length() < 20) { + inputTextCurrent += chr; + } + if (inputPmCurrent.length() < 80) { + inputPmCurrent += chr; + } + } + } + if (code == KeyEvent.VK_BACK_SPACE) { + if (inputTextCurrent.length() > 0) { + inputTextCurrent = inputTextCurrent.substring(0, inputTextCurrent.length() - 1); + } + if (inputPmCurrent.length() > 0) { + inputPmCurrent = inputPmCurrent.substring(0, inputPmCurrent.length() - 1); + } + } + if (code == KeyEvent.VK_ENTER) { + inputTextFinal = inputTextCurrent; + inputPmFinal = inputPmCurrent; + } + } + + protected void handleKeyPress(int i) { + } + + + public synchronized void keyReleased(int code) { + if (code == KeyEvent.VK_LEFT) { + keyLeft = false; + } else if (code == KeyEvent.VK_RIGHT) { + keyRight = false; + } else if (code == KeyEvent.VK_UP) { + keyUp = false; + } else if (code == KeyEvent.VK_DOWN) { + keyDown = false; + } else if (code == KeyEvent.VK_SPACE) { + keySpace = false; + } + } + + public synchronized void mouseMoved(int x, int y) { + mouseX = x; + mouseY = y; + mouseButtonDown = 0; + mouseActionTimeout = 0; + } + + public synchronized void mouseReleased(int x, int y) { + mouseX = x; + mouseY = y; + mouseButtonDown = 0; + } + + public synchronized void mousePressed(int x, int y, int button) { + mouseX = x; + mouseY = y; + mouseButtonDown = button; + lastMouseButtonDown = mouseButtonDown; + mouseActionTimeout = 0; + handleMouseDown(mouseButtonDown, x, y); + } + + public synchronized void mouseDragged(int x, int y, int button) { + mouseX = x; + mouseY = y; + mouseButtonDown = button; + } + + protected void handleMouseDown(int i, int j, int k) { + } + + /* + public void init() { + startedAsApplet = true; + System.out.println("Started applet"); + appletWidth = 512; + appletHeight = 344; + loadingStep = 1; + Utility.appletCodeBase = getCodeBase(); + addMouseListener(this); + addMouseMotionListener(this); + addKeyListener(this); + startThread(this); + }*/ + + public void start() { + if (stopTimeout >= 0) + stopTimeout = 0; + } + + public void stop() { + if (stopTimeout >= 0) + stopTimeout = 4000 / targetFps; + } + + public void destroy() { + stopTimeout = -1; + + try { + Thread.sleep(5000L); + } catch (Exception ignored) { + } + + if (stopTimeout == -1) { + System.out.println("5 seconds expired, forcing kill"); + closeProgram(); + } + } + + private void closeProgram() { + stopTimeout = -2; + System.out.println("Closing program"); + onClosing(); + + try { + Thread.sleep(1000L); + } catch (Exception ignored) { + } + + System.exit(0); + } + + public void run() { + if (loadingStep == 1) { + loadingStep = 2; + //graphics = getGraphics(); + loadJagex(); + drawLoadingScreen(0, "Loading..."); + startGame(); + loadingStep = 0; + } + + int i = 0; + int j = 256; + int sleep = 1; + int i1 = 0; + + for (int j1 = 0; j1 < 10; j1++) { + timings[j1] = System.currentTimeMillis(); + } + + while (stopTimeout >= 0) { + if (stopTimeout > 0) { + stopTimeout--; + if (stopTimeout == 0) { + closeProgram(); + //appletThread = null; + return; + } + } + int k1 = j; + int lastSleep = sleep; + j = 300; + sleep = 1; + long time = System.currentTimeMillis(); + if (timings[i] == 0L) { + j = k1; + sleep = lastSleep; + } else if (time > timings[i]) + j = (int) ((long) (2560 * targetFps) / (time - timings[i])); + if (j < 25) + j = 25; + if (j > 256) { + j = 256; + sleep = (int) ((long) targetFps - (time - timings[i]) / 10L); + if (sleep < threadSleep) + sleep = threadSleep; + } + try { + Thread.sleep(sleep); + } catch (InterruptedException ignored) { + } + timings[i] = time; + i = (i + 1) % 10; + if (sleep > 1) { + for (int j2 = 0; j2 < 10; j2++) + if (timings[j2] != 0L) + timings[j2] += sleep; + + } + int k2 = 0; + while (i1 < 256) { + handleInputs(); + i1 += j; + if (++k2 > maxDrawTime) { + i1 = 0; + interlaceTimer += 6; + if (interlaceTimer > 25) { + interlaceTimer = 0; + interlace = true; + } + break; + } + } + interlaceTimer--; + i1 &= 0xff; + draw(); + + this.fps = (1000 * j) / (this.targetFps * 256); + } + + if (stopTimeout == -1) + closeProgram(); + + //appletThread = null; + } + + /* + public void update(Graphics g) { + paint(g); + } + + public void paint(Graphics g) { + if (loadingStep == 2 && imageLogo != null) { + drawLoadingScreen(loadingProgressPercent, loadingProgessText); + } + }*/ + + private void loadJagex() { + //graphics.setColor(Color.black); + //graphics.fillRect(0, 0, appletWidth, appletHeight); + + byte buff[] = readDataFile("jagex.jag", "Jagex library", 0); + + if (buff != null) { + byte logo[] = Utility.loadData("logo.tga", 0, buff); + //imageLogo = createImage(logo); + } + + buff = readDataFile("fonts" + Version.FONTS + ".jag", "Game fonts", 5); + + if (buff != null) { + Surface.createFont(Utility.loadData("h11p.jf", 0, buff), 0); + Surface.createFont(Utility.loadData("h12b.jf", 0, buff), 1); + Surface.createFont(Utility.loadData("h12p.jf", 0, buff), 2); + Surface.createFont(Utility.loadData("h13b.jf", 0, buff), 3); + Surface.createFont(Utility.loadData("h14b.jf", 0, buff), 4); + Surface.createFont(Utility.loadData("h16b.jf", 0, buff), 5); + Surface.createFont(Utility.loadData("h20b.jf", 0, buff), 6); + Surface.createFont(Utility.loadData("h24b.jf", 0, buff), 7); + } + } + + private void drawLoadingScreen(int percent, String text) { + /* + try { + int midx = (appletWidth - 281) / 2; + int midy = (appletHeight - 148) / 2; + graphics.setColor(Color.black); + graphics.fillRect(0, 0, appletWidth, appletHeight); + + if (!hasRefererLogoNotused) { + graphics.drawImage(imageLogo, midx, midy, this); + } + + midx += 2; + midy += 90; + loadingProgressPercent = percent; + loadingProgessText = text; + graphics.setColor(new Color(132, 132, 132)); + + if (hasRefererLogoNotused) { + graphics.setColor(new Color(220, 0, 0)); + } + + graphics.drawRect(midx - 2, midy - 2, 280, 23); + graphics.fillRect(midx, midy, (277 * percent) / 100, 20); + graphics.setColor(new Color(198, 198, 198)); + + if (hasRefererLogoNotused) { + graphics.setColor(new Color(255, 255, 255)); + } + + drawString(graphics, text, fontTimesRoman15, midx + 138, midy + 10); + + if (!hasRefererLogoNotused) { + drawString(graphics, "Created by JAGeX - visit www.jagex.com", fontHelvetica13b, midx + 138, midy + 30); + drawString(graphics, "\2512001-2002 Andrew Gower and Jagex Ltd", fontHelvetica13b, midx + 138, midy + 44); + } else { + graphics.setColor(new Color(132, 132, 152)); + drawString(graphics, "\2512001-2002 Andrew Gower and Jagex Ltd", fontHelvetica12, midx + 138, appletHeight - 20); + } + + if (logoHeaderText != null) { + graphics.setColor(Color.white); + drawString(graphics, logoHeaderText, fontHelvetica13b, midx + 138, midy - 120); + } + } catch (Exception ignored) { + }*/ + } + + protected void showLoadingProgress(int i, String s) { + /* + try { + int j = (appletWidth - 281) / 2; + int k = (appletHeight - 148) / 2; + j += 2; + k += 90; + loadingProgressPercent = i; + loadingProgessText = s; + int l = (277 * i) / 100; + graphics.setColor(new Color(132, 132, 132)); + if (hasRefererLogoNotused) + graphics.setColor(new Color(220, 0, 0)); + graphics.fillRect(j, k, l, 20); + graphics.setColor(Color.black); + graphics.fillRect(j + l, k, 277 - l, 20); + graphics.setColor(new Color(198, 198, 198)); + if (hasRefererLogoNotused) + graphics.setColor(new Color(255, 255, 255)); + drawString(graphics, s, fontTimesRoman15, j + 138, k + 10); + } catch (Exception ignored) { + }*/ + } + + /* + protected void drawString(Graphics g, String s, Font font, int i, int j) { + Object obj; + if (gameFrame == null) + obj = this; + else + obj = gameFrame; + FontMetrics fontmetrics = ((Component) (obj)).getFontMetrics(font); + fontmetrics.stringWidth(s); + g.setFont(font); + g.drawString(s, i - fontmetrics.stringWidth(s) / 2, j + fontmetrics.getHeight() / 4); + } + + private Image createImage(byte buff[]) { + int i = buff[13] * 256 + buff[12]; + int j = buff[15] * 256 + buff[14]; + byte abyte1[] = new byte[256]; + byte abyte2[] = new byte[256]; + byte abyte3[] = new byte[256]; + + for (int k = 0; k < 256; k++) { + abyte1[k] = buff[20 + k * 3]; + abyte2[k] = buff[19 + k * 3]; + abyte3[k] = buff[18 + k * 3]; + } + + IndexColorModel indexcolormodel = new IndexColorModel(8, 256, abyte1, abyte2, abyte3); + + byte abyte4[] = new byte[i * j]; + int l = 0; + + for (int i1 = j - 1; i1 >= 0; i1--) { + for (int j1 = 0; j1 < i; j1++) + abyte4[l++] = buff[786 + j1 + i1 * i]; + + } + + MemoryImageSource memoryimagesource = new MemoryImageSource(i, j, indexcolormodel, abyte4, 0, i); + return createImage(memoryimagesource); + }*/ + + protected byte[] readDataFile(String file, String description, int percent) { + file = "./data204/" + file; + int archiveSize = 0; + int archiveSizeCompressed = 0; + byte archiveData[] = null; + + try { + showLoadingProgress(percent, "Loading " + description + " - 0%"); + java.io.InputStream inputstream = Utility.openFile(file); + DataInputStream datainputstream = new DataInputStream(inputstream); + byte header[] = new byte[6]; + datainputstream.readFully(header, 0, 6); + archiveSize = ((header[0] & 0xff) << 16) + ((header[1] & 0xff) << 8) + (header[2] & 0xff); + archiveSizeCompressed = ((header[3] & 0xff) << 16) + ((header[4] & 0xff) << 8) + (header[5] & 0xff); + showLoadingProgress(percent, "Loading " + description + " - 5%"); + int read = 0; + archiveData = new byte[archiveSizeCompressed]; + while (read < archiveSizeCompressed) { + int length = archiveSizeCompressed - read; + if (length > 1000) + length = 1000; + datainputstream.readFully(archiveData, read, length); + read += length; + showLoadingProgress(percent, "Loading " + description + " - " + (5 + (read * 95) / archiveSizeCompressed) + "%"); + } + datainputstream.close(); + } catch (IOException ignored) { + } + + showLoadingProgress(percent, "Unpacking " + description); + + if (archiveSizeCompressed != archiveSize) { + byte decompressed[] = new byte[archiveSize]; + BZLib.decompress(decompressed, archiveSize, archiveData, archiveSizeCompressed, 0); + return decompressed; + } else { + return archiveData; + } + } + + protected Socket createSocket(String s, int i) throws IOException { + Socket socket = new Socket(InetAddress.getByName(s), i); + socket.setSoTimeout(30000); + socket.setTcpNoDelay(true); + return socket; + } + + /*protected void startThread(Runnable runnable) { + Thread thread = new Thread(runnable); + thread.setDaemon(true); + thread.start(); + }*/ +} diff --git a/mudclient204-threadless/ISAAC.java b/mudclient204-threadless/ISAAC.java new file mode 100644 index 0000000..6ee2535 --- /dev/null +++ b/mudclient204-threadless/ISAAC.java @@ -0,0 +1,181 @@ +public class ISAAC { + + private int count; + private int results[]; + private int memory[]; + private int a; + private int b; + private int c; + + public ISAAC(int seed[]) { + memory = new int[256]; + results = new int[256]; + for (int i = 0; i < seed.length; i++) + results[i] = seed[i]; + + init(); + } + + public int getNextValue() { + if (count-- == 0) { + isaac(); + count = 255; + } + return results[count]; + } + + private void isaac() { + b += ++c; + for (int i = 0; i < 256; i++) { + int x = memory[i]; + switch (i & 3) { + case 0: // '\0' + a ^= a << 13; + break; + + case 1: // '\001' + a ^= a >>> 6; + break; + + case 2: // '\002' + a ^= a << 2; + break; + + case 3: // '\003' + a ^= a >>> 16; + break; + } + a += memory[i + 128 & 0xff]; + int k; + memory[i] = k = memory[(x & 0x3fc) >> 2] + a + b; + results[i] = b = memory[(k >> 8 & 0x3fc) >> 2] + x; + } + + } + + private void init() { + int i1; + int j1; + int k1; + int l1; + int i2; + int j2; + int k2; + int l = i1 = j1 = k1 = l1 = i2 = j2 = k2 = 0x9e3779b9; + for (int i = 0; i < 4; i++) { + l ^= i1 << 11; + k1 += l; + i1 += j1; + i1 ^= j1 >>> 2; + l1 += i1; + j1 += k1; + j1 ^= k1 << 8; + i2 += j1; + k1 += l1; + k1 ^= l1 >>> 16; + j2 += k1; + l1 += i2; + l1 ^= i2 << 10; + k2 += l1; + i2 += j2; + i2 ^= j2 >>> 4; + l += i2; + j2 += k2; + j2 ^= k2 << 8; + i1 += j2; + k2 += l; + k2 ^= l >>> 9; + j1 += k2; + l += i1; + } + + for (int j = 0; j < 256; j += 8) { + l += results[j]; + i1 += results[j + 1]; + j1 += results[j + 2]; + k1 += results[j + 3]; + l1 += results[j + 4]; + i2 += results[j + 5]; + j2 += results[j + 6]; + k2 += results[j + 7]; + l ^= i1 << 11; + k1 += l; + i1 += j1; + i1 ^= j1 >>> 2; + l1 += i1; + j1 += k1; + j1 ^= k1 << 8; + i2 += j1; + k1 += l1; + k1 ^= l1 >>> 16; + j2 += k1; + l1 += i2; + l1 ^= i2 << 10; + k2 += l1; + i2 += j2; + i2 ^= j2 >>> 4; + l += i2; + j2 += k2; + j2 ^= k2 << 8; + i1 += j2; + k2 += l; + k2 ^= l >>> 9; + j1 += k2; + l += i1; + memory[j] = l; + memory[j + 1] = i1; + memory[j + 2] = j1; + memory[j + 3] = k1; + memory[j + 4] = l1; + memory[j + 5] = i2; + memory[j + 6] = j2; + memory[j + 7] = k2; + } + + for (int k = 0; k < 256; k += 8) { + l += memory[k]; + i1 += memory[k + 1]; + j1 += memory[k + 2]; + k1 += memory[k + 3]; + l1 += memory[k + 4]; + i2 += memory[k + 5]; + j2 += memory[k + 6]; + k2 += memory[k + 7]; + l ^= i1 << 11; + k1 += l; + i1 += j1; + i1 ^= j1 >>> 2; + l1 += i1; + j1 += k1; + j1 ^= k1 << 8; + i2 += j1; + k1 += l1; + k1 ^= l1 >>> 16; + j2 += k1; + l1 += i2; + l1 ^= i2 << 10; + k2 += l1; + i2 += j2; + i2 ^= j2 >>> 4; + l += i2; + j2 += k2; + j2 ^= k2 << 8; + i1 += j2; + k2 += l; + k2 ^= l >>> 9; + j1 += k2; + l += i1; + memory[k] = l; + memory[k + 1] = i1; + memory[k + 2] = j1; + memory[k + 3] = k1; + memory[k + 4] = l1; + memory[k + 5] = i2; + memory[k + 6] = j2; + memory[k + 7] = k2; + } + + isaac(); + count = 256; + } +} diff --git a/mudclient204-threadless/Packet.java b/mudclient204-threadless/Packet.java new file mode 100644 index 0000000..c245460 --- /dev/null +++ b/mudclient204-threadless/Packet.java @@ -0,0 +1,266 @@ +import java.io.IOException; + +public class Packet { + + //static char charMap[]; + public static int anIntArray537[] = new int[256]; + public static int anIntArray541[] = new int[256]; + public int readTries; + public int maxReadTries; + public int packetStart; + public byte packetData[]; + /*private static int anIntArray521[] = { + 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, + 1023, 2047, 4095, 8191, 16383, 32767, 65535, 0x1ffff, 0x3ffff, 0x7ffff, + 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, + 0x3fffffff, 0x7fffffff, -1 + }; + int anInt522 = 61; + int anInt523 = 59; + int anInt524 = 42; + int anInt525 = 43; + int anInt526 = 44; // index list for charMap + int anInt527 = 45; + int anInt528 = 46; + int anInt529 = 47; + int anInt530 = 92; + int anInt531 = 32; + int anInt532 = 124; + int anInt533 = 34; */ + public ISAAC isaacIncoming; + public ISAAC isaacOutgoing; + protected int length; + protected int packetMaxLength; + protected boolean socketException; + protected String socketExceptionMessage; + protected int delay; + private int packetEnd; + private int packet8Check; + + public Packet() { + packetEnd = 3; + packet8Check = 8; + packetMaxLength = 5000; + socketException = false; + socketExceptionMessage = ""; + } + + public void seedIsaac(int seed[]) { + // TODO toggle isaac + //isaacIncoming = new ISAAC(seed); + //isaacOutgoing = new ISAAC(seed); + } + + public void closeStream() { + } + + public void readBytes(int len, byte buff[]) + throws IOException { + readStreamBytes(len, 0, buff); + } + + public int readPacket(byte buff[]) { + try { + readTries++; + if (maxReadTries > 0 && readTries > maxReadTries) { + socketException = true; + socketExceptionMessage = "time-out"; + maxReadTries += maxReadTries; + return 0; + } + if (length == 0 && availableStream() >= 2) { + length = readStream(); + if (length >= 160) + length = (length - 160) * 256 + readStream(); + } + if (length > 0 && availableStream() >= length) { + if (length >= 160) { + readBytes(length, buff); + } else { + buff[length - 1] = (byte) readStream(); + if (length > 1) + readBytes(length - 1, buff); + } + int i = length; + length = 0; + readTries = 0; + return i; + } + } catch (IOException ioexception) { + socketException = true; + socketExceptionMessage = ioexception.getMessage(); + } + return 0; + } + + public int availableStream() + throws IOException { + return 0; + } + + public void readStreamBytes(int i, int j, byte abyte0[]) + throws IOException { + } + + public boolean hasPacket() { + return packetStart > 0; + } + + public void writePacket(int i) + throws IOException { + if (socketException) { + packetStart = 0; + packetEnd = 3; + socketException = false; + throw new IOException(socketExceptionMessage); + } + delay++; + if (delay < i) + return; + if (packetStart > 0) { + delay = 0; + writeStreamBytes(packetData, 0, packetStart); + } + packetStart = 0; + packetEnd = 3; + } + + public void sendPacket() { + if (isaacOutgoing != null) { + int i = packetData[packetStart + 2] & 0xff; + packetData[packetStart + 2] = (byte) (i + isaacOutgoing.getNextValue()); + } + if (packet8Check != 8) // what the fuck is this even for? legacy? + packetEnd++; + int j = packetEnd - packetStart - 2; + if (j >= 160) { + packetData[packetStart] = (byte) (160 + j / 256); + packetData[packetStart + 1] = (byte) (j & 0xff); + } else { + packetData[packetStart] = (byte) j; + packetEnd--; + packetData[packetStart + 1] = packetData[packetEnd]; + } + if (packetMaxLength <= 10000) // this keeps count of how many times we send each opcode, and how much bandwidth each opcode uses per session + { + int k = packetData[packetStart + 2] & 0xff; + anIntArray537[k]++; + anIntArray541[k] += packetEnd - packetStart; + } + packetStart = packetEnd; + } + + public void putBytes(byte src[], int srcPos, int len) { + //for (int k = 0; k < len; k++) + // packetData[packetEnd++] = src[srcPos + k]; + System.arraycopy(src, srcPos, packetData, packetEnd, len); + packetEnd += len; + + } + + public void putLong(long l) { + putInt((int) (l >> 32)); + putInt((int) (l & -1L)); + } + + public void newPacket(int i) { + if (packetStart > (packetMaxLength * 4) / 5) + try { + writePacket(0); + } catch (IOException ioexception) { + socketException = true; + socketExceptionMessage = ioexception.getMessage(); + } + if (packetData == null) + packetData = new byte[packetMaxLength]; + packetData[packetStart + 2] = (byte) i; + packetData[packetStart + 3] = 0; + packetEnd = packetStart + 3; + packet8Check = 8; + } + + public void writeStreamBytes(byte abyte0[], int i, int j) + throws IOException { + } + + public int readStream() + throws IOException { + return 0; + } + + public long getLong() + throws IOException { + long l = getShort(); + long l1 = getShort(); + long l2 = getShort(); + long l3 = getShort(); + return (l << 48) + (l1 << 32) + (l2 << 16) + l3; + } + + public void putShort(int i) { + packetData[packetEnd++] = (byte) (i >> 8); + packetData[packetEnd++] = (byte) i; + } + + public void putInt(int i) { + packetData[packetEnd++] = (byte) (i >> 24); + packetData[packetEnd++] = (byte) (i >> 16); + packetData[packetEnd++] = (byte) (i >> 8); + packetData[packetEnd++] = (byte) i; + } + + public int getShort() + throws IOException { + int i = getByte(); + int j = getByte(); + return i * 256 + j; + } + + public void putString(String s) { + //s.getBytes(0, s.length(), packetData, packetEnd); + System.arraycopy(s.getBytes(), 0, packetData, packetEnd, s.length()); + packetEnd += s.length(); + } + + public void putByte(int i) { + packetData[packetEnd++] = (byte) i; + } + + public int isaacCommand(int i) { + // TODO toggle isaac + //return i - isaacIncoming.getNextValue() & 0xff; + return i; + } + + public int getByte() + throws IOException { + return readStream(); + } + + public void flushPacket() + throws IOException { + sendPacket(); + writePacket(0); + } + // public static int anInt543; + + /*static + { + charMap = new char[256]; + for(int i = 0; i < 256; i++) + charMap[i] = (char)i; + + charMap[61] = '='; + charMap[59] = ';'; + charMap[42] = '*'; + charMap[43] = '+'; + charMap[44] = ','; + charMap[45] = '-'; + charMap[46] = '.'; + charMap[47] = '/'; + charMap[92] = '\\'; + charMap[124] = '|'; + charMap[33] = '!'; + charMap[34] = '"'; + } */ +} diff --git a/mudclient204-threadless/Panel.java b/mudclient204-threadless/Panel.java new file mode 100644 index 0000000..3810a10 --- /dev/null +++ b/mudclient204-threadless/Panel.java @@ -0,0 +1,708 @@ +public class Panel { + + public static boolean drawBackgroundArrow = true; + public static int baseSpriteStart; + public static int redMod = 114; + public static int greenMod = 114; + public static int blueMod = 176; + public static int textListEntryHeightMod; + public boolean controlShown[]; + public boolean controlListScrollbarHandleDragged[]; + public boolean controlMaskText[]; + public boolean controlClicked[]; + public int controlFlashText[]; + public int controlListEntryCount[]; + public int controlListEntryMouseButtonDown[]; + public int controlListEntryMouseOver[]; + public boolean aBoolean219; + protected Surface surface; + int controlCount; + int maxControls; + boolean controlUseAlternativeColour[]; + int controlX[]; + int controlY[]; + int controlType[]; + int controlWidth[]; + int controlHeight[]; + int controlInputMaxLen[]; + int controlTextSize[]; + String controlText[]; + String controlListEntries[][]; + int mouseX; + int mouseY; + int mouseLastButtonDown; + int mouseButtonDown; + int focusControlIndex; + int mouseMetaButtonHeld; + int colourScrollbarTop; + int colourScrollbarBottom; + int colourScrollbarHandleLeft; + int colourScrollbarHandleMid; + int colourScrollbarHandleRight; + int colourRoundedBoxOut; + int colourRoundedBoxMid; + int colourRoundedBoxIn; + int colourBoxTopNBottom; + int colourBoxTopNBottom2; + int colourBoxLeftNRight2; + int colourBoxLeftNRight; + + public Panel(Surface surface, int max) { + focusControlIndex = -1; + aBoolean219 = true; + this.surface = surface; + maxControls = max; + controlShown = new boolean[max]; + controlListScrollbarHandleDragged = new boolean[max]; + controlMaskText = new boolean[max]; + controlClicked = new boolean[max]; + controlUseAlternativeColour = new boolean[max]; + controlFlashText = new int[max];// not so sure + controlListEntryCount = new int[max]; + controlListEntryMouseButtonDown = new int[max]; + controlListEntryMouseOver = new int[max]; + controlX = new int[max]; + controlY = new int[max]; + controlType = new int[max]; + controlWidth = new int[max]; + controlHeight = new int[max]; + controlInputMaxLen = new int[max]; + controlTextSize = new int[max]; + controlText = new String[max]; + controlListEntries = new String[max][]; + colourScrollbarTop = rgb2longMod(114, 114, 176); + colourScrollbarBottom = rgb2longMod(14, 14, 62); + colourScrollbarHandleLeft = rgb2longMod(200, 208, 232); + colourScrollbarHandleMid = rgb2longMod(96, 129, 184); + colourScrollbarHandleRight = rgb2longMod(53, 95, 115); + colourRoundedBoxOut = rgb2longMod(117, 142, 171); + colourRoundedBoxMid = rgb2longMod(98, 122, 158); + colourRoundedBoxIn = rgb2longMod(86, 100, 136); + colourBoxTopNBottom = rgb2longMod(135, 146, 179); + colourBoxTopNBottom2 = rgb2longMod(97, 112, 151); + colourBoxLeftNRight2 = rgb2longMod(88, 102, 136); + colourBoxLeftNRight = rgb2longMod(84, 93, 120); + } + + public int rgb2longMod(int i, int j, int k) { + return Surface.rgb2long((redMod * i) / 114, (greenMod * j) / 114, (blueMod * k) / 176); + } + + public void handleMouse(int mx, int my, int lastmb, int mbdown) { + mouseX = mx; + mouseY = my; + mouseButtonDown = mbdown; + if (lastmb != 0) + mouseLastButtonDown = lastmb; + if (lastmb == 1) { + for (int i1 = 0; i1 < controlCount; i1++) { + if (controlShown[i1] && controlType[i1] == 10 && mouseX >= controlX[i1] && mouseY >= controlY[i1] && mouseX <= controlX[i1] + controlWidth[i1] && mouseY <= controlY[i1] + controlHeight[i1]) + controlClicked[i1] = true; + if (controlShown[i1] && controlType[i1] == 14 && mouseX >= controlX[i1] && mouseY >= controlY[i1] && mouseX <= controlX[i1] + controlWidth[i1] && mouseY <= controlY[i1] + controlHeight[i1]) + controlListEntryMouseButtonDown[i1] = 1 - controlListEntryMouseButtonDown[i1]; + } + + } + if (mbdown == 1) + mouseMetaButtonHeld++; + else + mouseMetaButtonHeld = 0; + if (lastmb == 1 || mouseMetaButtonHeld > 20) { + for (int j1 = 0; j1 < controlCount; j1++) + if (controlShown[j1] && controlType[j1] == 15 && mouseX >= controlX[j1] && mouseY >= controlY[j1] && mouseX <= controlX[j1] + controlWidth[j1] && mouseY <= controlY[j1] + controlHeight[j1]) + controlClicked[j1] = true; + + mouseMetaButtonHeld -= 5; + } + } + + public boolean isClicked(int i) { + if (controlShown[i] && controlClicked[i]) { + controlClicked[i] = false; + return true; + } else { + return false; + } + } + + public void keyPress(int key) { + if (key == 0) + return; + if (focusControlIndex != -1 && controlText[focusControlIndex] != null && controlShown[focusControlIndex]) { + int inputLen = controlText[focusControlIndex].length(); + if (key == 8 && inputLen > 0) + controlText[focusControlIndex] = controlText[focusControlIndex].substring(0, inputLen - 1); + if ((key == 10 || key == 13) && inputLen > 0) + controlClicked[focusControlIndex] = true; + String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"£$%^&*()-_=+[{]};:'@#~,<.>/?\\| "; + if (inputLen < controlInputMaxLen[focusControlIndex]) { + for (int k = 0; k < s.length(); k++) + if (key == s.charAt(k)) + controlText[focusControlIndex] += (char) key; + + } + if (key == 9) + do + focusControlIndex = (focusControlIndex + 1) % controlCount; + while (controlType[focusControlIndex] != 5 && controlType[focusControlIndex] != 6); + } + } + + public void drawPanel() { + for (int i = 0; i < controlCount; i++) + if (controlShown[i]) + if (controlType[i] == 0)// text + drawText(i, controlX[i], controlY[i], controlText[i], controlTextSize[i]); + else if (controlType[i] == 1)// text (centered) + drawText(i, controlX[i] - surface.textWidth(controlText[i], controlTextSize[i]) / 2, controlY[i], controlText[i], controlTextSize[i]); + else if (controlType[i] == 2)// component gradient bg + drawBox(controlX[i], controlY[i], controlWidth[i], controlHeight[i]); + else if (controlType[i] == 3)// horiz line + drawLineHoriz(controlX[i], controlY[i], controlWidth[i]); + else if (controlType[i] == 4)// text list (no interaction) + drawTextList(i, controlX[i], controlY[i], controlWidth[i], controlHeight[i], controlTextSize[i], controlListEntries[i], controlListEntryCount[i], controlFlashText[i]); + else if (controlType[i] == 5 || controlType[i] == 6)// input text + drawTextInput(i, controlX[i], controlY[i], controlWidth[i], controlHeight[i], controlText[i], controlTextSize[i]); + else if (controlType[i] == 7)// option list horiz + drawOptionListHoriz(i, controlX[i], controlY[i], controlTextSize[i], controlListEntries[i]); + else if (controlType[i] == 8)// option list vert + drawOptionListVert(i, controlX[i], controlY[i], controlTextSize[i], controlListEntries[i]); + else if (controlType[i] == 9)// text list (interaction) + drawTextListInteractive(i, controlX[i], controlY[i], controlWidth[i], controlHeight[i], controlTextSize[i], controlListEntries[i], controlListEntryCount[i], controlFlashText[i]); + else if (controlType[i] == 11)// rounded box + drawRoundedBox(controlX[i], controlY[i], controlWidth[i], controlHeight[i]); + else if (controlType[i] == 12)// image + drawPicture(controlX[i], controlY[i], controlTextSize[i]); + else if (controlType[i] == 14)// checkbox + drawCheckbox(i, controlX[i], controlY[i], controlWidth[i], controlHeight[i]); + + mouseLastButtonDown = 0; + } + + protected void drawCheckbox(int control, int x, int y, int width, int height) { + surface.drawBox(x, y, width, height, 0xffffff); + surface.drawLineHoriz(x, y, width, colourBoxTopNBottom); + surface.drawLineVert(x, y, height, colourBoxTopNBottom); + surface.drawLineHoriz(x, (y + height) - 1, width, colourBoxLeftNRight); + surface.drawLineVert((x + width) - 1, y, height, colourBoxLeftNRight); + if (controlListEntryMouseButtonDown[control] == 1) { + for (int j1 = 0; j1 < height; j1++) { + surface.drawLineHoriz(x + j1, y + j1, 1, 0); + surface.drawLineHoriz((x + width) - 1 - j1, y + j1, 1, 0); + } + + } + } + + protected void drawText(int control, int x, int y, String text, int textSize) { + int y2 = y + surface.textHeight(textSize) / 3; + drawstring(control, x, y2, text, textSize); + } + + protected void drawstring(int control, int x, int y, String text, int textSize) { + int i1; + if (controlUseAlternativeColour[control]) + i1 = 0xffffff; + else + i1 = 0; + surface.drawstring(text, x, y, textSize, i1); + } + + protected void drawTextInput(int control, int x, int y, int width, int height, String text, int textSize) { + if (controlMaskText[control]) { + int len = text.length(); + text = ""; + for (int i2 = 0; i2 < len; i2++) + text = text + "X"; + + } + if (controlType[control] == 5) {// "list input" + if (mouseLastButtonDown == 1 && mouseX >= x && mouseY >= y - height / 2 && mouseX <= x + width && mouseY <= y + height / 2) + focusControlIndex = control; + } else if (controlType[control] == 6) {// "text input" + if (mouseLastButtonDown == 1 && mouseX >= x - width / 2 && mouseY >= y - height / 2 && mouseX <= x + width / 2 && mouseY <= y + height / 2) + focusControlIndex = control; + x -= surface.textWidth(text, textSize) / 2; + } + if (focusControlIndex == control) + text = text + "*"; + int y2 = y + surface.textHeight(textSize) / 3; + drawstring(control, x, y2, text, textSize); + } + + public void drawBox(int x, int y, int width, int height) { + surface.setBounds(x, y, x + width, y + height); + surface.drawGradient(x, y, width, height, colourBoxLeftNRight, colourBoxTopNBottom); + if (drawBackgroundArrow) {// set to false inside startGame, draw some kindof an arrow?? + for (int i1 = x - (y & 0x3f); i1 < x + width; i1 += 128) { + for (int j1 = y - (y & 0x1f); j1 < y + height; j1 += 128) + surface.drawSpriteAlpha(i1, j1, 6 + baseSpriteStart, 128); + + } + + } + surface.drawLineHoriz(x, y, width, colourBoxTopNBottom); + surface.drawLineHoriz(x + 1, y + 1, width - 2, colourBoxTopNBottom); + surface.drawLineHoriz(x + 2, y + 2, width - 4, colourBoxTopNBottom2); + surface.drawLineVert(x, y, height, colourBoxTopNBottom); + surface.drawLineVert(x + 1, y + 1, height - 2, colourBoxTopNBottom); + surface.drawLineVert(x + 2, y + 2, height - 4, colourBoxTopNBottom2); + surface.drawLineHoriz(x, (y + height) - 1, width, colourBoxLeftNRight); + surface.drawLineHoriz(x + 1, (y + height) - 2, width - 2, colourBoxLeftNRight); + surface.drawLineHoriz(x + 2, (y + height) - 3, width - 4, colourBoxLeftNRight2); + surface.drawLineVert((x + width) - 1, y, height, colourBoxLeftNRight); + surface.drawLineVert((x + width) - 2, y + 1, height - 2, colourBoxLeftNRight); + surface.drawLineVert((x + width) - 3, y + 2, height - 4, colourBoxLeftNRight2); + surface.resetBounds(); + } + + public void drawRoundedBox(int x, int y, int width, int height) { + surface.drawBox(x, y, width, height, 0); + surface.drawBoxEdge(x, y, width, height, colourRoundedBoxOut); + surface.drawBoxEdge(x + 1, y + 1, width - 2, height - 2, colourRoundedBoxMid); + surface.drawBoxEdge(x + 2, y + 2, width - 4, height - 4, colourRoundedBoxIn); + surface.drawSprite(x, y, 2 + baseSpriteStart); + surface.drawSprite((x + width) - 7, y, 3 + baseSpriteStart); + surface.drawSprite(x, (y + height) - 7, 4 + baseSpriteStart); + surface.drawSprite((x + width) - 7, (y + height) - 7, 5 + baseSpriteStart); + } + + protected void drawPicture(int x, int y, int size) { + surface.drawSprite(x, y, size); + } + + protected void drawLineHoriz(int x, int y, int width) { + surface.drawLineHoriz(x, y, width, 0xffffff); + } + + protected void drawTextList(int control, int x, int y, int width, int height, int textSize, + String listEntries[], int listEntryCount, int l1) { + int displayedEntryCount = height / surface.textHeight(textSize); + if (l1 > listEntryCount - displayedEntryCount) + l1 = listEntryCount - displayedEntryCount; + if (l1 < 0) + l1 = 0; + controlFlashText[control] = l1; + if (displayedEntryCount < listEntryCount) { + int cornerTopRight = (x + width) - 12; + int cornerBottomLeft = ((height - 27) * displayedEntryCount) / listEntryCount; + if (cornerBottomLeft < 6) + cornerBottomLeft = 6; + int j3 = ((height - 27 - cornerBottomLeft) * l1) / (listEntryCount - displayedEntryCount); + if (mouseButtonDown == 1 && mouseX >= cornerTopRight && mouseX <= cornerTopRight + 12) { + if (mouseY > y && mouseY < y + 12 && l1 > 0) + l1--; + if (mouseY > (y + height) - 12 && mouseY < y + height && l1 < listEntryCount - displayedEntryCount) + l1++; + controlFlashText[control] = l1; + } + if (mouseButtonDown == 1 && (mouseX >= cornerTopRight && mouseX <= cornerTopRight + 12 || mouseX >= cornerTopRight - 12 && mouseX <= cornerTopRight + 24 && controlListScrollbarHandleDragged[control])) { + if (mouseY > y + 12 && mouseY < (y + height) - 12) { + controlListScrollbarHandleDragged[control] = true; + int l3 = mouseY - y - 12 - cornerBottomLeft / 2; + l1 = (l3 * listEntryCount) / (height - 24); + if (l1 > listEntryCount - displayedEntryCount) + l1 = listEntryCount - displayedEntryCount; + if (l1 < 0) + l1 = 0; + controlFlashText[control] = l1; + } + } else { + controlListScrollbarHandleDragged[control] = false; + } + j3 = ((height - 27 - cornerBottomLeft) * l1) / (listEntryCount - displayedEntryCount); + drawListContainer(x, y, width, height, j3, cornerBottomLeft); + } + int entryListStartY = height - displayedEntryCount * surface.textHeight(textSize); + int y2 = y + (surface.textHeight(textSize) * 5) / 6 + entryListStartY / 2; + for (int entry = l1; entry < listEntryCount; entry++) { + drawstring(control, x + 2, y2, listEntries[entry], textSize); + y2 += surface.textHeight(textSize) - textListEntryHeightMod; + if (y2 >= y + height) + return; + } + + } + + protected void drawListContainer(int x, int y, int width, int height, int corner1, int corner2) { + int x2 = (x + width) - 12; + surface.drawBoxEdge(x2, y, 12, height, 0); + surface.drawSprite(x2 + 1, y + 1, baseSpriteStart);// up arrow? + surface.drawSprite(x2 + 1, (y + height) - 12, 1 + baseSpriteStart);// down arrow? + surface.drawLineHoriz(x2, y + 13, 12, 0); + surface.drawLineHoriz(x2, (y + height) - 13, 12, 0); + surface.drawGradient(x2 + 1, y + 14, 11, height - 27, colourScrollbarTop, colourScrollbarBottom); + surface.drawBox(x2 + 3, corner1 + y + 14, 7, corner2, colourScrollbarHandleMid); + surface.drawLineVert(x2 + 2, corner1 + y + 14, corner2, colourScrollbarHandleLeft); + surface.drawLineVert(x2 + 2 + 8, corner1 + y + 14, corner2, colourScrollbarHandleRight); + } + + protected void drawOptionListHoriz(int control, int x, int y, int textSize, String listEntries[]) { + int listTotalTextWidth = 0; + int listEntryCount = listEntries.length; + for (int idx = 0; idx < listEntryCount; idx++) { + listTotalTextWidth += surface.textWidth(listEntries[idx], textSize); + if (idx < listEntryCount - 1) + listTotalTextWidth += surface.textWidth(" ", textSize); + } + + int left = x - listTotalTextWidth / 2; + int bottom = y + surface.textHeight(textSize) / 3; + for (int idx = 0; idx < listEntryCount; idx++) { + int colour; + if (controlUseAlternativeColour[control]) + colour = 0xffffff; + else + colour = 0; + if (mouseX >= left && mouseX <= left + surface.textWidth(listEntries[idx], textSize) && mouseY <= bottom && mouseY > bottom - surface.textHeight(textSize)) { + if (controlUseAlternativeColour[control]) + colour = 0x808080; + else + colour = 0xffffff; + if (mouseLastButtonDown == 1) { + controlListEntryMouseButtonDown[control] = idx; + controlClicked[control] = true; + } + } + if (controlListEntryMouseButtonDown[control] == idx) + if (controlUseAlternativeColour[control]) + colour = 0xff0000; + else + colour = 0xc00000; + surface.drawstring(listEntries[idx], left, bottom, textSize, colour); + left += surface.textWidth(listEntries[idx] + " ", textSize); + } + + } + + protected void drawOptionListVert(int control, int x, int y, int textSize, String listEntries[]) { + int listEntryCount = listEntries.length; + int listTotalTextHeightMid = y - (surface.textHeight(textSize) * (listEntryCount - 1)) / 2; + for (int idx = 0; idx < listEntryCount; idx++) { + int colour; + if (controlUseAlternativeColour[control]) + colour = 0xffffff; + else + colour = 0; + int entryTextWidth = surface.textWidth(listEntries[idx], textSize); + if (mouseX >= x - entryTextWidth / 2 && mouseX <= x + entryTextWidth / 2 && mouseY - 2 <= listTotalTextHeightMid && mouseY - 2 > listTotalTextHeightMid - surface.textHeight(textSize)) { + if (controlUseAlternativeColour[control]) + colour = 0x808080; + else + colour = 0xffffff; + if (mouseLastButtonDown == 1) { + controlListEntryMouseButtonDown[control] = idx; + controlClicked[control] = true; + } + } + if (controlListEntryMouseButtonDown[control] == idx) + if (controlUseAlternativeColour[control]) + colour = 0xff0000; + else + colour = 0xc00000; + surface.drawstring(listEntries[idx], x - entryTextWidth / 2, listTotalTextHeightMid, textSize, colour); + listTotalTextHeightMid += surface.textHeight(textSize); + } + + } + + protected void drawTextListInteractive(int control, int x, int y, int width, int height, int textSize, + String listEntries[], int listEntryCount, int l1) { + int displayedEntryCount = height / surface.textHeight(textSize); + if (displayedEntryCount < listEntryCount) { + int right = (x + width) - 12; + int l2 = ((height - 27) * displayedEntryCount) / listEntryCount; + if (l2 < 6) + l2 = 6; + int j3 = ((height - 27 - l2) * l1) / (listEntryCount - displayedEntryCount); + if (mouseButtonDown == 1 && mouseX >= right && mouseX <= right + 12) { + if (mouseY > y && mouseY < y + 12 && l1 > 0) + l1--; + if (mouseY > (y + height) - 12 && mouseY < y + height && l1 < listEntryCount - displayedEntryCount) + l1++; + controlFlashText[control] = l1; + } + if (mouseButtonDown == 1 && (mouseX >= right && mouseX <= right + 12 || mouseX >= right - 12 && mouseX <= right + 24 && controlListScrollbarHandleDragged[control])) { + if (mouseY > y + 12 && mouseY < (y + height) - 12) { + controlListScrollbarHandleDragged[control] = true; + int l3 = mouseY - y - 12 - l2 / 2; + l1 = (l3 * listEntryCount) / (height - 24); + if (l1 < 0) + l1 = 0; + if (l1 > listEntryCount - displayedEntryCount) + l1 = listEntryCount - displayedEntryCount; + controlFlashText[control] = l1; + } + } else { + controlListScrollbarHandleDragged[control] = false; + } + j3 = ((height - 27 - l2) * l1) / (listEntryCount - displayedEntryCount); + drawListContainer(x, y, width, height, j3, l2); + } else { + l1 = 0; + controlFlashText[control] = 0; + } + controlListEntryMouseOver[control] = -1; + int k2 = height - displayedEntryCount * surface.textHeight(textSize); + int i3 = y + (surface.textHeight(textSize) * 5) / 6 + k2 / 2; + for (int k3 = l1; k3 < listEntryCount; k3++) { + int i4; + if (controlUseAlternativeColour[control]) + i4 = 0xffffff; + else + i4 = 0; + if (mouseX >= x + 2 && mouseX <= x + 2 + surface.textWidth(listEntries[k3], textSize) && mouseY - 2 <= i3 && mouseY - 2 > i3 - surface.textHeight(textSize)) { + if (controlUseAlternativeColour[control]) + i4 = 0x808080; + else + i4 = 0xffffff; + controlListEntryMouseOver[control] = k3; + if (mouseLastButtonDown == 1) { + controlListEntryMouseButtonDown[control] = k3; + controlClicked[control] = true; + } + } + if (controlListEntryMouseButtonDown[control] == k3 && aBoolean219) + i4 = 0xff0000; + surface.drawstring(listEntries[k3], x + 2, i3, textSize, i4); + i3 += surface.textHeight(textSize); + if (i3 >= y + height) + return; + } + + } + + public int addText(int x, int y, String text, int size, boolean flag) { + controlType[controlCount] = 1; + controlShown[controlCount] = true; + controlClicked[controlCount] = false; + controlTextSize[controlCount] = size; + controlUseAlternativeColour[controlCount] = flag; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlText[controlCount] = text; + return controlCount++; + } + + public int addButtonBackground(int x, int y, int width, int height) { + controlType[controlCount] = 2; + controlShown[controlCount] = true; + controlClicked[controlCount] = false; + controlX[controlCount] = x - width / 2; + controlY[controlCount] = y - height / 2; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + return controlCount++; + } + + public int addBoxRounded(int x, int y, int width, int height) { + controlType[controlCount] = 11; + controlShown[controlCount] = true; + controlClicked[controlCount] = false; + controlX[controlCount] = x - width / 2; + controlY[controlCount] = y - height / 2; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + return controlCount++; + } + + public int addSprite(int x, int y, int spriteId) { + int imgWidth = surface.spriteWidth[spriteId]; + int imgHeight = surface.spriteHeight[spriteId]; + controlType[controlCount] = 12; + controlShown[controlCount] = true; + controlClicked[controlCount] = false; + controlX[controlCount] = x - imgWidth / 2; + controlY[controlCount] = y - imgHeight / 2; + controlWidth[controlCount] = imgWidth; + controlHeight[controlCount] = imgHeight; + controlTextSize[controlCount] = spriteId; + return controlCount++; + } + + public int addTextList(int x, int y, int width, int height, int size, int maxLength, boolean flag) { + controlType[controlCount] = 4; + controlShown[controlCount] = true; + controlClicked[controlCount] = false; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + controlUseAlternativeColour[controlCount] = flag; + controlTextSize[controlCount] = size; + controlInputMaxLen[controlCount] = maxLength; + controlListEntryCount[controlCount] = 0; + controlFlashText[controlCount] = 0; + controlListEntries[controlCount] = new String[maxLength]; + return controlCount++; + } + + public int addTextListInput(int x, int y, int width, int height, int size, int maxLength, boolean flag, + boolean flag1) { + controlType[controlCount] = 5; + controlShown[controlCount] = true; + controlMaskText[controlCount] = flag; + controlClicked[controlCount] = false; + controlTextSize[controlCount] = size; + controlUseAlternativeColour[controlCount] = flag1; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + controlInputMaxLen[controlCount] = maxLength; + controlText[controlCount] = ""; + return controlCount++; + } + + public int addTextInput(int x, int y, int width, int height, int size, int maxLength, boolean flag, + boolean flag1) { + controlType[controlCount] = 6; + controlShown[controlCount] = true; + controlMaskText[controlCount] = flag; + controlClicked[controlCount] = false; + controlTextSize[controlCount] = size; + controlUseAlternativeColour[controlCount] = flag1; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + controlInputMaxLen[controlCount] = maxLength; + controlText[controlCount] = ""; + return controlCount++; + } + + public int addTextListInteractive(int x, int y, int width, int height, int textSize, int maxLength, boolean flag) { + controlType[controlCount] = 9; + controlShown[controlCount] = true; + controlClicked[controlCount] = false; + controlTextSize[controlCount] = textSize; + controlUseAlternativeColour[controlCount] = flag; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + controlInputMaxLen[controlCount] = maxLength; + controlListEntries[controlCount] = new String[maxLength]; + controlListEntryCount[controlCount] = 0; + controlFlashText[controlCount] = 0; + controlListEntryMouseButtonDown[controlCount] = -1; + controlListEntryMouseOver[controlCount] = -1; + return controlCount++; + } + + public int addButton(int x, int y, int width, int height) { + controlType[controlCount] = 10; + controlShown[controlCount] = true; + controlClicked[controlCount] = false; + controlX[controlCount] = x - width / 2; + controlY[controlCount] = y - height / 2; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + return controlCount++; + } + + public int addLineHoriz(int x, int y, int width) { + controlType[controlCount] = 3; + controlShown[controlCount] = true; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlWidth[controlCount] = width; + return controlCount++; + } + + public int addOptionListHoriz(int x, int y, int textSize, int maxListCount, + boolean useAltColour) { + controlType[controlCount] = 7; + controlShown[controlCount] = true; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlTextSize[controlCount] = textSize; + controlListEntries[controlCount] = new String[maxListCount]; + controlListEntryCount[controlCount] = 0; + controlUseAlternativeColour[controlCount] = useAltColour; + controlClicked[controlCount] = false; + return controlCount++; + } + + public int addOptionListVert(int x, int y, int textSize, int maxListCount, + boolean useAltColour) { + controlType[controlCount] = 8; + controlShown[controlCount] = true; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlTextSize[controlCount] = textSize; + controlListEntries[controlCount] = new String[maxListCount]; + controlListEntryCount[controlCount] = 0; + controlUseAlternativeColour[controlCount] = useAltColour; + controlClicked[controlCount] = false; + return controlCount++; + } + + public int addCheckbox(int x, int y, int width, int height) { + controlType[controlCount] = 14; + controlShown[controlCount] = true; + controlX[controlCount] = x; + controlY[controlCount] = y; + controlWidth[controlCount] = width; + controlHeight[controlCount] = height; + controlListEntryMouseButtonDown[controlCount] = 0; + return controlCount++; + } + + public void clearList(int control) { + controlListEntryCount[control] = 0; + } + + public void resetListProps(int control) { + controlFlashText[control] = 0; + controlListEntryMouseOver[control] = -1; + } + + public void addListEntry(int control, int index, String text) { + controlListEntries[control][index] = text; + if (index + 1 > controlListEntryCount[control]) + controlListEntryCount[control] = index + 1; + } + + public void removeListEntry(int control, String text, boolean flag) { + int j = controlListEntryCount[control]++; + if (j >= controlInputMaxLen[control]) { + j--; + controlListEntryCount[control]--; + for (int k = 0; k < j; k++) + controlListEntries[control][k] = controlListEntries[control][k + 1]; + + } + controlListEntries[control][j] = text; + if (flag) + controlFlashText[control] = 999999;// 0xf423f; + } + + public void updateText(int control, String s) { + controlText[control] = s; + } + + public String getText(int control) { + if (controlText[control] == null) + return "null"; + else + return controlText[control]; + } + + public void show(int control) { + controlShown[control] = true; + } + + public void hide(int control) { + controlShown[control] = false; + } + + public void setFocus(int control) { + focusControlIndex = control; + } + + public int getListEntryIndex(int control) { + return controlListEntryMouseOver[control]; + } + +} diff --git a/mudclient204-threadless/Polygon.java b/mudclient204-threadless/Polygon.java new file mode 100644 index 0000000..fd62693 --- /dev/null +++ b/mudclient204-threadless/Polygon.java @@ -0,0 +1,25 @@ +public class Polygon { + + protected int minPlaneX; + protected int minPlaneY; + protected int maxPlaneX; + protected int maxPlaneY; + protected int minZ; + protected int maxZ; + protected GameModel model; + protected int face; + protected int depth; + protected int normalX; + protected int normalY; + protected int normalZ; + protected int visibility; + protected int facefill; + protected boolean skipSomething; + protected int index; + protected int index2; + + public Polygon() { + skipSomething = false; + index2 = -1; + } +} diff --git a/mudclient204-threadless/Scanline.java b/mudclient204-threadless/Scanline.java new file mode 100644 index 0000000..07c7693 --- /dev/null +++ b/mudclient204-threadless/Scanline.java @@ -0,0 +1,10 @@ +public class Scanline { + + int startX; + int endX; + int startS; + int endS; + + public Scanline() { + } +} diff --git a/mudclient204-threadless/Scene.java b/mudclient204-threadless/Scene.java new file mode 100644 index 0000000..2bace3a --- /dev/null +++ b/mudclient204-threadless/Scene.java @@ -0,0 +1,3127 @@ +public class Scene { + + public static int sin2048Cache[] = new int[2048]; + static int frustumMaxX; + static int frustumMinX; + static int furstumMaxY; + static int furstumMinY; + static int furstumFarZ; + static int frustumNearZ; + private static int sin512Cache[] = new int[512]; + private static long textureCountLoaded; + private static byte aByteArray434[]; + //private static int anIntArray435[] = new int[256]; + public int lastVisiblePolygonsCount; + public int clipNear; + public int clipFar3d; + public int clipFar2d; + public int fogZFalloff; + public int fogZDistance; + public boolean wideBand; + public double aDouble387; + public int anInt388; + public int modelCount; + public int maxModelCount; + public GameModel models[]; + public GameModel view; + public int raster[]; + int rampCount; + int gradientBase[]; + int gradientRamps[][]; + int anIntArray377[]; + int textureCount; + byte textureColoursUsed[][]; + int textureColourList[][]; + int textureDimension[]; + long textureLoadedNumber[]; + int texturePixels[][]; + boolean textureBackTransparent[]; + int textureColours64[][]; + int textureColours128[][]; + Surface surface; + Scanline scanlines[]; + int minY; + int maxY; + int planeX[]; + int planeY[]; + int vertexShade[]; + int vertexX[]; + int vertexY[]; + int vertexZ[]; + boolean interlace; + int newStart; + int newEnd; + private boolean mousePickingActive; + private int mouseX; + private int mouseY; + private int mousePickedCount; + private int mousePickedMax; + private GameModel mousePickedModels[]; + private int mousePickedFaces[]; + private int width; + private int clipX; + private int clipY; + private int baseX; + private int baseY; + private int viewDistance; + private int normalMagnitude; + private int cameraX; + private int cameraY; + private int cameraZ; + private int cameraYaw; + private int cameraPitch; + private int cameraRoll; + // private int modelState[]; // only set not used + private int visiblePolygonsCount; + private Polygon visiblePolygons[]; + private int spriteCount; + private int spriteId[]; + private int spriteX[]; + private int spriteZ[]; + private int spriteY[]; + private int spriteWidth[]; + private int spriteHeight[]; + private int spriteTranslateX[]; + + public Scene(Surface surface, int i, int polygons, int k) { + rampCount = 50; + gradientBase = new int[rampCount]; + gradientRamps = new int[rampCount][256]; + clipNear = 5; + clipFar3d = 1000; + clipFar2d = 1000; + fogZFalloff = 20; + fogZDistance = 10; + wideBand = false; + aDouble387 = 1.1000000000000001D; + anInt388 = 1; + mousePickingActive = false; + mousePickedMax = 100; + mousePickedModels = new GameModel[mousePickedMax]; + mousePickedFaces = new int[mousePickedMax]; + width = surface.width1; + clipX = 256; + clipY = 192; + baseX = 256; + baseY = 256; + viewDistance = 8; + normalMagnitude = 4; + planeX = new int[40]; + planeY = new int[40]; + vertexShade = new int[40]; + vertexX = new int[40]; + vertexY = new int[40]; + vertexZ = new int[40]; + interlace = false; + this.surface = surface; + clipX = surface.width2 / 2; + clipY = surface.height2 / 2; + raster = surface.pixels; + modelCount = 0; + maxModelCount = i; + models = new GameModel[maxModelCount]; + // modelState = new int[maxModelCount]; // only set not used + visiblePolygonsCount = 0; + visiblePolygons = new Polygon[polygons]; + for (int l = 0; l < polygons; l++) + visiblePolygons[l] = new Polygon(); + + spriteCount = 0; + view = new GameModel(k * 2, k); + spriteId = new int[k]; + spriteWidth = new int[k]; + spriteHeight = new int[k]; + spriteX = new int[k]; + spriteZ = new int[k]; + spriteY = new int[k]; + spriteTranslateX = new int[k]; + if (aByteArray434 == null) + aByteArray434 = new byte[17691]; + cameraX = 0; + cameraY = 0; + cameraZ = 0; + cameraYaw = 0; + cameraPitch = 0; + cameraRoll = 0; + for (int i1 = 0; i1 < 256; i1++) { + sin512Cache[i1] = (int) (Math.sin((double) i1 * 0.02454369D) * 32768D); + sin512Cache[i1 + 256] = (int) (Math.cos((double) i1 * 0.02454369D) * 32768D); + } + + for (int j1 = 0; j1 < 1024; j1++) { + sin2048Cache[j1] = (int) (Math.sin((double) j1 * 0.00613592315D) * 32768D); + sin2048Cache[j1 + 1024] = (int) (Math.cos((double) j1 * 0.00613592315D) * 32768D); + } + + } + + private static void textureScanline(int ai[], int ai1[], int i, int j, int k, int l, int i1, int j1, + int k1, int l1, int i2, int j2, int k2, int l2) { + if (i2 <= 0) + return; + int i3 = 0; + int j3 = 0; + int i4 = 0; + if (i1 != 0) { + i = k / i1 << 7; + j = l / i1 << 7; + } + if (i < 0) + i = 0; + else if (i > 16256) + i = 16256; + k += j1; + l += k1; + i1 += l1; + if (i1 != 0) { + i3 = k / i1 << 7; + j3 = l / i1 << 7; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 16256) + i3 = 16256; + int k3 = i3 - i >> 4; + int l3 = j3 - j >> 4; + for (int j4 = i2 >> 4; j4 > 0; j4--) { + i += k2 & 0x600000; + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i = i3; + j = j3; + k += j1; + l += k1; + i1 += l1; + if (i1 != 0) { + i3 = k / i1 << 7; + j3 = l / i1 << 7; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 16256) + i3 = 16256; + k3 = i3 - i >> 4; + l3 = j3 - j >> 4; + } + + for (int k4 = 0; k4 < (i2 & 0xf); k4++) { + if ((k4 & 3) == 0) { + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + } + ai[j2++] = ai1[(j & 0x3f80) + (i >> 7)] >>> i4; + i += k3; + j += l3; + } + + } + + private static void textureTranslucentScanline(int ai[], int ai1[], int i, int j, int k, int l, int i1, int j1, + int k1, int l1, int i2, int j2, int k2, int l2) { + if (i2 <= 0) + return; + int i3 = 0; + int j3 = 0; + int i4 = 0; + if (i1 != 0) { + i = k / i1 << 7; + j = l / i1 << 7; + } + if (i < 0) + i = 0; + else if (i > 16256) + i = 16256; + k += j1; + l += k1; + i1 += l1; + if (i1 != 0) { + i3 = k / i1 << 7; + j3 = l / i1 << 7; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 16256) + i3 = 16256; + int k3 = i3 - i >> 4; + int l3 = j3 - j >> 4; + for (int j4 = i2 >> 4; j4 > 0; j4--) { + i += k2 & 0x600000; + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i = i3; + j = j3; + k += j1; + l += k1; + i1 += l1; + if (i1 != 0) { + i3 = k / i1 << 7; + j3 = l / i1 << 7; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 16256) + i3 = 16256; + k3 = i3 - i >> 4; + l3 = j3 - j >> 4; + } + + for (int k4 = 0; k4 < (i2 & 0xf); k4++) { + if ((k4 & 3) == 0) { + i = (i & 0x3fff) + (k2 & 0x600000); + i4 = k2 >> 23; + k2 += l2; + } + ai[j2++] = (ai1[(j & 0x3f80) + (i >> 7)] >>> i4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + } + + } + + private static void textureBackTranslucentScanline(int ai[], int i, int j, int k, int ai1[], int l, int i1, int j1, + int k1, int l1, int i2, int j2, int k2, int l2, int i3) { + if (j2 <= 0) + return; + int j3 = 0; + int k3 = 0; + i3 <<= 2; + if (j1 != 0) { + j3 = l / j1 << 7; + k3 = i1 / j1 << 7; + } + if (j3 < 0) + j3 = 0; + else if (j3 > 16256) + j3 = 16256; + for (int j4 = j2; j4 > 0; j4 -= 16) { + l += k1; + i1 += l1; + j1 += i2; + j = j3; + k = k3; + if (j1 != 0) { + j3 = l / j1 << 7; + k3 = i1 / j1 << 7; + } + if (j3 < 0) + j3 = 0; + else if (j3 > 16256) + j3 = 16256; + int l3 = j3 - j >> 4; + int i4 = k3 - k >> 4; + int k4 = l2 >> 23; + j += l2 & 0x600000; + l2 += i3; + if (j4 < 16) { + for (int l4 = 0; l4 < j4; l4++) { + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((l4 & 3) == 3) { + j = (j & 0x3fff) + (l2 & 0x600000); + k4 = l2 >> 23; + l2 += i3; + } + } + + } else { + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + j = (j & 0x3fff) + (l2 & 0x600000); + k4 = l2 >> 23; + l2 += i3; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + j = (j & 0x3fff) + (l2 & 0x600000); + k4 = l2 >> 23; + l2 += i3; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + j = (j & 0x3fff) + (l2 & 0x600000); + k4 = l2 >> 23; + l2 += i3; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0x3f80) + (j >> 7)] >>> k4) != 0) + ai[k2] = i; + k2++; + } + } + + } + + private static void textureScanline2(int ai[], int ai1[], int i, int j, int k, int l, int i1, int j1, + int k1, int l1, int i2, int j2, int k2, int l2) { + if (i2 <= 0) + return; + int i3 = 0; + int j3 = 0; + l2 <<= 2; + if (i1 != 0) { + i3 = k / i1 << 6; + j3 = l / i1 << 6; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 4032) + i3 = 4032; + for (int i4 = i2; i4 > 0; i4 -= 16) { + k += j1; + l += k1; + i1 += l1; + i = i3; + j = j3; + if (i1 != 0) { + i3 = k / i1 << 6; + j3 = l / i1 << 6; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 4032) + i3 = 4032; + int k3 = i3 - i >> 4; + int l3 = j3 - j >> 4; + int j4 = k2 >> 20; + i += k2 & 0xc0000; + k2 += l2; + if (i4 < 16) { + for (int k4 = 0; k4 < i4; k4++) { + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + if ((k4 & 3) == 3) { + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + } + } + + } else { + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + i += k3; + j += l3; + ai[j2++] = ai1[(j & 0xfc0) + (i >> 6)] >>> j4; + } + } + + } + + private static void textureTranslucentScanline2(int ai[], int ai1[], int i, int j, int k, int l, int i1, int j1, + int k1, int l1, int i2, int j2, int k2, int l2) { + if (i2 <= 0) + return; + int i3 = 0; + int j3 = 0; + l2 <<= 2; + if (i1 != 0) { + i3 = k / i1 << 6; + j3 = l / i1 << 6; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 4032) + i3 = 4032; + for (int i4 = i2; i4 > 0; i4 -= 16) { + k += j1; + l += k1; + i1 += l1; + i = i3; + j = j3; + if (i1 != 0) { + i3 = k / i1 << 6; + j3 = l / i1 << 6; + } + if (i3 < 0) + i3 = 0; + else if (i3 > 4032) + i3 = 4032; + int k3 = i3 - i >> 4; + int l3 = j3 - j >> 4; + int j4 = k2 >> 20; + i += k2 & 0xc0000; + k2 += l2; + if (i4 < 16) { + for (int k4 = 0; k4 < i4; k4++) { + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + if ((k4 & 3) == 3) { + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + } + } + + } else { + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + i = (i & 0xfff) + (k2 & 0xc0000); + j4 = k2 >> 20; + k2 += l2; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + i += k3; + j += l3; + ai[j2++] = (ai1[(j & 0xfc0) + (i >> 6)] >>> j4) + (ai[j2] >> 1 & 0x7f7f7f); + } + } + + } + + private static void textureBackTranslucentScanline2(int ai[], int i, int j, int k, int ai1[], int l, int i1, int j1, + int k1, int l1, int i2, int j2, int k2, int l2, int i3) { + if (j2 <= 0) + return; + int j3 = 0; + int k3 = 0; + i3 <<= 2; + if (j1 != 0) { + j3 = l / j1 << 6; + k3 = i1 / j1 << 6; + } + if (j3 < 0) + j3 = 0; + else if (j3 > 4032) + j3 = 4032; + for (int j4 = j2; j4 > 0; j4 -= 16) { + l += k1; + i1 += l1; + j1 += i2; + j = j3; + k = k3; + if (j1 != 0) { + j3 = l / j1 << 6; + k3 = i1 / j1 << 6; + } + if (j3 < 0) + j3 = 0; + else if (j3 > 4032) + j3 = 4032; + int l3 = j3 - j >> 4; + int i4 = k3 - k >> 4; + int k4 = l2 >> 20; + j += l2 & 0xc0000; + l2 += i3; + if (j4 < 16) { + for (int l4 = 0; l4 < j4; l4++) { + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((l4 & 3) == 3) { + j = (j & 0xfff) + (l2 & 0xc0000); + k4 = l2 >> 20; + l2 += i3; + } + } + + } else { + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + j = (j & 0xfff) + (l2 & 0xc0000); + k4 = l2 >> 20; + l2 += i3; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + j = (j & 0xfff) + (l2 & 0xc0000); + k4 = l2 >> 20; + l2 += i3; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + j = (j & 0xfff) + (l2 & 0xc0000); + k4 = l2 >> 20; + l2 += i3; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + j += l3; + k += i4; + if ((i = ai1[(k & 0xfc0) + (j >> 6)] >>> k4) != 0) + ai[k2] = i; + k2++; + } + } + + } + + private static void gradientScanline(int ai[], int i, int j, int k, int ai1[], int l, int i1) { + if (i >= 0) + return; + i1 <<= 1; + k = ai1[l >> 8 & 0xff]; + l += i1; + int j1 = i / 8; + for (int k1 = j1; k1 < 0; k1++) { + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + } + + j1 = -(i % 8); + for (int l1 = 0; l1 < j1; l1++) { + ai[j++] = k; + if ((l1 & 1) == 1) { + k = ai1[l >> 8 & 0xff]; + l += i1; + } + } + + } + + private static void textureGradientScanline(int ai[], int i, int j, int k, int ai1[], int l, int i1) { + if (i >= 0) + return; + i1 <<= 2; + k = ai1[l >> 8 & 0xff]; + l += i1; + int j1 = i / 16; + for (int k1 = j1; k1 < 0; k1++) { + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + k = ai1[l >> 8 & 0xff]; + l += i1; + } + + j1 = -(i % 16); + for (int l1 = 0; l1 < j1; l1++) { + ai[j++] = k + (ai[j] >> 1 & 0x7f7f7f); + if ((l1 & 3) == 3) { + k = ai1[l >> 8 & 0xff]; + l += i1; + l += i1; + } + } + + } + + private static void gradientScanline2(int ai[], int i, int j, int k, int ai1[], int l, int i1) { + if (i >= 0) + return; + i1 <<= 2; + k = ai1[l >> 8 & 0xff]; + l += i1; + int j1 = i / 16; + for (int k1 = j1; k1 < 0; k1++) { + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + ai[j++] = k; + k = ai1[l >> 8 & 0xff]; + l += i1; + } + + j1 = -(i % 16); + for (int l1 = 0; l1 < j1; l1++) { + ai[j++] = k; + if ((l1 & 3) == 3) { + k = ai1[l >> 8 & 0xff]; + l += i1; + } + } + + } + + public static int rgb(int i, int j, int k) { + return -1 - (i / 8) * 1024 - (j / 8) * 32 - k / 8; + } + + public void addModel(GameModel model) { + if (model == null) + System.out.println("Warning tried to add null object!"); + if (modelCount < maxModelCount) { + //modelState[modelCount] = 0; // only set, not used + models[modelCount++] = model; + } + } + + public void removeModel(GameModel gameModel) { + for (int i = 0; i < modelCount; i++) + if (models[i] == gameModel) { + modelCount--; + for (int j = i; j < modelCount; j++) { + models[j] = models[j + 1]; + //modelState[j] = modelState[j + 1]; // only set, not used + } + + } + + } + + public void dispose() { + clear(); + for (int i = 0; i < modelCount; i++) + models[i] = null; + + modelCount = 0; + } + + public void clear() { + spriteCount = 0; + view.clear(); + } + + public void reduceSprites(int i) { + spriteCount -= i; + view.reduce(i, i * 2); + if (spriteCount < 0) + spriteCount = 0; + } + + public int addSprite(int n, int x, int z, int y, int w, int h, int tag) { + spriteId[spriteCount] = n; + spriteX[spriteCount] = x; + spriteZ[spriteCount] = z; + spriteY[spriteCount] = y; + spriteWidth[spriteCount] = w; + spriteHeight[spriteCount] = h; + spriteTranslateX[spriteCount] = 0; + int l1 = view.createVertex(x, z, y); + int i2 = view.createVertex(x, z - h, y); + int vs[] = { + l1, i2 + }; + view.createFace(2, vs, 0, 0); + view.faceTag[spriteCount] = tag; + view.isLocalPlayer[spriteCount++] = 0; + return spriteCount - 1; + } + + public void setLocalPlayer(int i) { + view.isLocalPlayer[i] = 1; + } + + public void setSpriteTranslateX(int i, int n) { + spriteTranslateX[i] = n; + } + + public void setMouseLoc(int x, int y) { + mouseX = x - baseX; + mouseY = y; + mousePickedCount = 0; + mousePickingActive = true; + } + + public int getMousePickedCount() { + return mousePickedCount; + } + + public int[] getMousePickedFaces() { + return mousePickedFaces; + } + + public GameModel[] getMousePickedModels() { + return mousePickedModels; + } + + public void setBounds(int baseX, int baseY, int clipX, int clipY, int width, int viewDistance) { + this.clipX = clipX; + this.clipY = clipY; + this.baseX = baseX; + this.baseY = baseY; + this.width = width; + this.viewDistance = viewDistance; + scanlines = new Scanline[clipY + baseY]; + for (int k1 = 0; k1 < clipY + baseY; k1++) + scanlines[k1] = new Scanline(); + + } + + private void polygonsQSort(Polygon polygons[], int low, int high) { + if (low < high) { + int min = low - 1; + int max = high + 1; + int mid = (low + high) / 2; + Polygon polygon = polygons[mid]; + polygons[mid] = polygons[low]; + polygons[low] = polygon; + int j1 = polygon.depth; + while (min < max) { + do + max--; + while (polygons[max].depth < j1); + do + min++; + while (polygons[min].depth > j1); + if (min < max) { + Polygon polygon_1 = polygons[min]; + polygons[min] = polygons[max]; + polygons[max] = polygon_1; + } + } + polygonsQSort(polygons, low, max); + polygonsQSort(polygons, max + 1, high); + } + } + + public void polygonsIntersectSort(int step, Polygon polygons[], int count) { + for (int i = 0; i <= count; i++) { + polygons[i].skipSomething = false; + polygons[i].index = i; + polygons[i].index2 = -1; + } + + int l = 0; + do { + while (polygons[l].skipSomething) + l++; + if (l == count) + return; + Polygon polygon = polygons[l]; + polygon.skipSomething = true; + int i1 = l; + int j1 = l + step; + if (j1 >= count) + j1 = count - 1; + for (int k1 = j1; k1 >= i1 + 1; k1--) { + Polygon other = polygons[k1]; + if (polygon.minPlaneX < other.maxPlaneX && other.minPlaneX < polygon.maxPlaneX && polygon.minPlaneY < other.maxPlaneY && other.minPlaneY < polygon.maxPlaneY && polygon.index != other.index2 && !separatePolygon(polygon, other) && heuristicPolygon(other, polygon)) { + polygonsOrder(polygons, i1, k1); + if (polygons[k1] != other) + k1++; + i1 = newStart; + other.index2 = polygon.index; + } + } + + } while (true); + } + + public boolean polygonsOrder(Polygon polygons[], int start, int end) { + do { + Polygon polygon = polygons[start]; + for (int k = start + 1; k <= end; k++) { + Polygon polygon_1 = polygons[k]; + if (!separatePolygon(polygon_1, polygon)) + break; + polygons[start] = polygon_1; + polygons[k] = polygon; + start = k; + if (start == end) { + newStart = start; + newEnd = start - 1; + return true; + } + } + + Polygon polygon_2 = polygons[end]; + for (int l = end - 1; l >= start; l--) { + Polygon polygon_3 = polygons[l]; + if (!separatePolygon(polygon_2, polygon_3)) + break; + polygons[end] = polygon_3; + polygons[l] = polygon_2; + end = l; + if (start == end) { + newStart = end + 1; + newEnd = end; + return true; + } + } + + if (start + 1 >= end) { + newStart = start; + newEnd = end; + return false; + } + if (!polygonsOrder(polygons, start + 1, end)) { + newStart = start; + return false; + } + end = newEnd; + } while (true); + } + + public void setFrustum(int i, int j, int k) { + int l = -cameraYaw + 1024 & 0x3ff; + int i1 = -cameraPitch + 1024 & 0x3ff; + int j1 = -cameraRoll + 1024 & 0x3ff; + if (j1 != 0) { + int k1 = sin2048Cache[j1]; + int j2 = sin2048Cache[j1 + 1024]; + int i3 = j * k1 + i * j2 >> 15; + j = j * j2 - i * k1 >> 15; + i = i3; + } + if (l != 0) { + int l1 = sin2048Cache[l]; + int k2 = sin2048Cache[l + 1024]; + int j3 = j * k2 - k * l1 >> 15; + k = j * l1 + k * k2 >> 15; + j = j3; + } + if (i1 != 0) { + int i2 = sin2048Cache[i1]; + int l2 = sin2048Cache[i1 + 1024]; + int k3 = k * i2 + i * l2 >> 15; + k = k * l2 - i * i2 >> 15; + i = k3; + } + if (i < frustumMaxX) + frustumMaxX = i; + if (i > frustumMinX) + frustumMinX = i; + if (j < furstumMaxY) + furstumMaxY = j; + if (j > furstumMinY) + furstumMinY = j; + if (k < furstumFarZ) + furstumFarZ = k; + if (k > frustumNearZ) + frustumNearZ = k; + } + + public void render() { + interlace = surface.interlace; + int i3 = clipX * clipFar3d >> viewDistance; + int j3 = clipY * clipFar3d >> viewDistance; + frustumMaxX = 0; + frustumMinX = 0; + furstumMaxY = 0; + furstumMinY = 0; + furstumFarZ = 0; + frustumNearZ = 0; + setFrustum(-i3, -j3, clipFar3d); + setFrustum(-i3, j3, clipFar3d); + setFrustum(i3, -j3, clipFar3d); + setFrustum(i3, j3, clipFar3d); + setFrustum(-clipX, -clipY, 0); + setFrustum(-clipX, clipY, 0); + setFrustum(clipX, -clipY, 0); + setFrustum(clipX, clipY, 0); + frustumMaxX += cameraX; + frustumMinX += cameraX; + furstumMaxY += cameraY; + furstumMinY += cameraY; + furstumFarZ += cameraZ; + frustumNearZ += cameraZ; + models[modelCount] = view; + view.transformState = 2; + for (int i = 0; i < modelCount; i++) + models[i].project(cameraX, cameraY, cameraZ, cameraYaw, cameraPitch, cameraRoll, viewDistance, clipNear); + + models[modelCount].project(cameraX, cameraY, cameraZ, cameraYaw, cameraPitch, cameraRoll, viewDistance, clipNear); + visiblePolygonsCount = 0; + for (int count = 0; count < modelCount; count++) { + GameModel gameModel = models[count]; + if (gameModel.visible) { + for (int face = 0; face < gameModel.numFaces; face++) { + int num_vertices = gameModel.faceNumVertices[face]; + int vertices[] = gameModel.faceVertices[face]; + boolean visible = false; + for (int vertex = 0; vertex < num_vertices; vertex++) { + int z = gameModel.projectVertexZ[vertices[vertex]]; + if (z <= clipNear || z >= clipFar3d) + continue; + visible = true; + break; + } + + if (visible) { + int viewxcount = 0; + for (int vertex = 0; vertex < num_vertices; vertex++) { + int x = gameModel.vertexViewX[vertices[vertex]]; + if (x > -clipX) + viewxcount |= 1; + if (x < clipX) + viewxcount |= 2; + if (viewxcount == 3) + break; + } + + if (viewxcount == 3) { + int viewycount = 0; + for (int vertex = 0; vertex < num_vertices; vertex++) { + int k1 = gameModel.vertexViewY[vertices[vertex]]; + if (k1 > -clipY) + viewycount |= 1; + if (k1 < clipY) + viewycount |= 2; + if (viewycount == 3) + break; + } + + if (viewycount == 3) { + Polygon polygon_1 = visiblePolygons[visiblePolygonsCount]; + polygon_1.model = gameModel; + polygon_1.face = face; + initialisePolygon3d(visiblePolygonsCount); + int facefill; + if (polygon_1.visibility < 0) + facefill = gameModel.faceFillFront[face]; + else + facefill = gameModel.faceFillBack[face]; + if (facefill != World.colourTransparent) { // 12345678 = invisible ? + int h = 0; + for (int vertex = 0; vertex < num_vertices; vertex++) + h += gameModel.projectVertexZ[vertices[vertex]]; + + polygon_1.depth = h / num_vertices + gameModel.depth; + polygon_1.facefill = facefill; + visiblePolygonsCount++; + } + } + } + } + } + + } + } + + GameModel model_2d = view; + if (model_2d.visible) { + for (int face = 0; face < model_2d.numFaces; face++) { + int faceVertices[] = model_2d.faceVertices[face]; + int vertex0 = faceVertices[0]; + int vx = model_2d.vertexViewX[vertex0]; + int vy = model_2d.vertexViewY[vertex0]; + int vz = model_2d.projectVertexZ[vertex0]; + if (vz > clipNear && vz < clipFar2d) { + int vw = (spriteWidth[face] << viewDistance) / vz; + int vh = (spriteHeight[face] << viewDistance) / vz; + if (vx - vw / 2 <= clipX && vx + vw / 2 >= -clipX && vy - vh <= clipY && vy >= -clipY) { + Polygon polygon_2 = visiblePolygons[visiblePolygonsCount]; + polygon_2.model = model_2d; + polygon_2.face = face; + initialisePolygon2d(visiblePolygonsCount); + polygon_2.depth = (vz + model_2d.projectVertexZ[faceVertices[1]]) / 2; + visiblePolygonsCount++; + } + } + } + + } + if (visiblePolygonsCount == 0) + return; + lastVisiblePolygonsCount = visiblePolygonsCount; + polygonsQSort(visiblePolygons, 0, visiblePolygonsCount - 1); + polygonsIntersectSort(100, visiblePolygons, visiblePolygonsCount); + for (int model = 0; model < visiblePolygonsCount; model++) { + Polygon polygon = visiblePolygons[model]; + GameModel gameModel_2 = polygon.model; + int l = polygon.face; + if (gameModel_2 == view) { + int faceverts[] = gameModel_2.faceVertices[l]; + int face_0 = faceverts[0]; + int vx = gameModel_2.vertexViewX[face_0]; + int vy = gameModel_2.vertexViewY[face_0]; + int vz = gameModel_2.projectVertexZ[face_0]; + int w = (spriteWidth[l] << viewDistance) / vz; + int h = (spriteHeight[l] << viewDistance) / vz; + //int i11 = vy - gameModel_2.vertexViewY[faceverts[1]]; // not used + //int tx = ((gameModel_2.vertexViewX[faceverts[1]] - vx) * i11) / h; // redundant + int tx = gameModel_2.vertexViewX[faceverts[1]] - vx; + int x = vx - w / 2; + int y = (baseY + vy) - h; + surface.spriteClipping(x + baseX, y, w, h, spriteId[l], tx, (256 << viewDistance) / vz); + if (mousePickingActive && mousePickedCount < mousePickedMax) { + x += (spriteTranslateX[l] << viewDistance) / vz; + if (mouseY >= y && mouseY <= y + h && mouseX >= x && mouseX <= x + w && !gameModel_2.unpickable && gameModel_2.isLocalPlayer[l] == 0) { + mousePickedModels[mousePickedCount] = gameModel_2; + mousePickedFaces[mousePickedCount] = l; + mousePickedCount++; + } + } + } else { + int k8 = 0; + int j10 = 0; + int l10 = gameModel_2.faceNumVertices[l]; + int ai3[] = gameModel_2.faceVertices[l]; + if (gameModel_2.faceIntensity[l] != World.colourTransparent) + if (polygon.visibility < 0) + j10 = gameModel_2.lightAmbience - gameModel_2.faceIntensity[l]; + else + j10 = gameModel_2.lightAmbience + gameModel_2.faceIntensity[l]; + for (int k11 = 0; k11 < l10; k11++) { + int k2 = ai3[k11]; + vertexX[k11] = gameModel_2.projectVertexX[k2]; + vertexY[k11] = gameModel_2.projectVertexY[k2]; + vertexZ[k11] = gameModel_2.projectVertexZ[k2]; + if (gameModel_2.faceIntensity[l] == World.colourTransparent) + if (polygon.visibility < 0) + j10 = (gameModel_2.lightAmbience - gameModel_2.vertexIntensity[k2]) + gameModel_2.vertexAmbience[k2]; + else + j10 = gameModel_2.lightAmbience + gameModel_2.vertexIntensity[k2] + gameModel_2.vertexAmbience[k2]; + if (gameModel_2.projectVertexZ[k2] >= clipNear) { + planeX[k8] = gameModel_2.vertexViewX[k2]; + planeY[k8] = gameModel_2.vertexViewY[k2]; + vertexShade[k8] = j10; + if (gameModel_2.projectVertexZ[k2] > fogZDistance) + vertexShade[k8] += (gameModel_2.projectVertexZ[k2] - fogZDistance) / fogZFalloff; + k8++; + } else { + int k9; + if (k11 == 0) + k9 = ai3[l10 - 1]; + else + k9 = ai3[k11 - 1]; + if (gameModel_2.projectVertexZ[k9] >= clipNear) { + int k7 = gameModel_2.projectVertexZ[k2] - gameModel_2.projectVertexZ[k9]; + int i5 = gameModel_2.projectVertexX[k2] - ((gameModel_2.projectVertexX[k2] - gameModel_2.projectVertexX[k9]) * (gameModel_2.projectVertexZ[k2] - clipNear)) / k7; + int j6 = gameModel_2.projectVertexY[k2] - ((gameModel_2.projectVertexY[k2] - gameModel_2.projectVertexY[k9]) * (gameModel_2.projectVertexZ[k2] - clipNear)) / k7; + planeX[k8] = (i5 << viewDistance) / clipNear; + planeY[k8] = (j6 << viewDistance) / clipNear; + vertexShade[k8] = j10; + k8++; + } + if (k11 == l10 - 1) + k9 = ai3[0]; + else + k9 = ai3[k11 + 1]; + if (gameModel_2.projectVertexZ[k9] >= clipNear) { + int l7 = gameModel_2.projectVertexZ[k2] - gameModel_2.projectVertexZ[k9]; + int j5 = gameModel_2.projectVertexX[k2] - ((gameModel_2.projectVertexX[k2] - gameModel_2.projectVertexX[k9]) * (gameModel_2.projectVertexZ[k2] - clipNear)) / l7; + int k6 = gameModel_2.projectVertexY[k2] - ((gameModel_2.projectVertexY[k2] - gameModel_2.projectVertexY[k9]) * (gameModel_2.projectVertexZ[k2] - clipNear)) / l7; + planeX[k8] = (j5 << viewDistance) / clipNear; + planeY[k8] = (k6 << viewDistance) / clipNear; + vertexShade[k8] = j10; + k8++; + } + } + } + + for (int i12 = 0; i12 < l10; i12++) { + if (vertexShade[i12] < 0) + vertexShade[i12] = 0; + else if (vertexShade[i12] > 255) + vertexShade[i12] = 255; + if (polygon.facefill >= 0) + if (textureDimension[polygon.facefill] == 1) + vertexShade[i12] <<= 9; + else + vertexShade[i12] <<= 6; + } + + generateScanlines(0, 0, 0, 0, k8, planeX, planeY, vertexShade, gameModel_2, l); + if (maxY > minY) + rasterize(0, 0, l10, vertexX, vertexY, vertexZ, polygon.facefill, gameModel_2); + } + } + + mousePickingActive = false; + } + + private void generateScanlines(int i, int j, int k, int l, int i1, int ai[], int ai1[], + int ai2[], GameModel gameModel, int pid) { + if (i1 == 3) { + int k1 = ai1[0] + baseY; + int k2 = ai1[1] + baseY; + int k3 = ai1[2] + baseY; + int k4 = ai[0]; + int l5 = ai[1]; + int j7 = ai[2]; + int l8 = ai2[0]; + int j10 = ai2[1]; + int j11 = ai2[2]; + int j12 = (baseY + clipY) - 1; + int l12 = 0; + int j13 = 0; + int l13 = 0; + int j14 = 0; + int l14 = World.colourTransparent; + int j15 = 0xff439eb2; + if (k3 != k1) { + j13 = (j7 - k4 << 8) / (k3 - k1); + j14 = (j11 - l8 << 8) / (k3 - k1); + if (k1 < k3) { + l12 = k4 << 8; + l13 = l8 << 8; + l14 = k1; + j15 = k3; + } else { + l12 = j7 << 8; + l13 = j11 << 8; + l14 = k3; + j15 = k1; + } + if (l14 < 0) { + l12 -= j13 * l14; + l13 -= j14 * l14; + l14 = 0; + } + if (j15 > j12) + j15 = j12; + } + int l15 = 0; + int j16 = 0; + int l16 = 0; + int j17 = 0; + int l17 = World.colourTransparent; + int j18 = 0xff439eb2; + if (k2 != k1) { + j16 = (l5 - k4 << 8) / (k2 - k1); + j17 = (j10 - l8 << 8) / (k2 - k1); + if (k1 < k2) { + l15 = k4 << 8; + l16 = l8 << 8; + l17 = k1; + j18 = k2; + } else { + l15 = l5 << 8; + l16 = j10 << 8; + l17 = k2; + j18 = k1; + } + if (l17 < 0) { + l15 -= j16 * l17; + l16 -= j17 * l17; + l17 = 0; + } + if (j18 > j12) + j18 = j12; + } + int l18 = 0; + int j19 = 0; + int l19 = 0; + int j20 = 0; + int l20 = World.colourTransparent; + int j21 = 0xff439eb2; + if (k3 != k2) { + j19 = (j7 - l5 << 8) / (k3 - k2); + j20 = (j11 - j10 << 8) / (k3 - k2); + if (k2 < k3) { + l18 = l5 << 8; + l19 = j10 << 8; + l20 = k2; + j21 = k3; + } else { + l18 = j7 << 8; + l19 = j11 << 8; + l20 = k3; + j21 = k2; + } + if (l20 < 0) { + l18 -= j19 * l20; + l19 -= j20 * l20; + l20 = 0; + } + if (j21 > j12) + j21 = j12; + } + minY = l14; + if (l17 < minY) + minY = l17; + if (l20 < minY) + minY = l20; + maxY = j15; + if (j18 > maxY) + maxY = j18; + if (j21 > maxY) + maxY = j21; + int l21 = 0; + for (k = minY; k < maxY; k++) { + if (k >= l14 && k < j15) { + i = j = l12; + l = l21 = l13; + l12 += j13; + l13 += j14; + } else { + i = 0xa0000; + j = 0xfff60000; + } + if (k >= l17 && k < j18) { + if (l15 < i) { + i = l15; + l = l16; + } + if (l15 > j) { + j = l15; + l21 = l16; + } + l15 += j16; + l16 += j17; + } + if (k >= l20 && k < j21) { + if (l18 < i) { + i = l18; + l = l19; + } + if (l18 > j) { + j = l18; + l21 = l19; + } + l18 += j19; + l19 += j20; + } + Scanline scanline_6 = scanlines[k]; + scanline_6.startX = i; + scanline_6.endX = j; + scanline_6.startS = l; + scanline_6.endS = l21; + } + + if (minY < baseY - clipY) + minY = baseY - clipY; + } else if (i1 == 4) { + int l1 = ai1[0] + baseY; + int l2 = ai1[1] + baseY; + int l3 = ai1[2] + baseY; + int l4 = ai1[3] + baseY; + int i6 = ai[0]; + int k7 = ai[1]; + int i9 = ai[2]; + int k10 = ai[3]; + int k11 = ai2[0]; + int k12 = ai2[1]; + int i13 = ai2[2]; + int k13 = ai2[3]; + int i14 = (baseY + clipY) - 1; + int k14 = 0; + int i15 = 0; + int k15 = 0; + int i16 = 0; + int k16 = World.colourTransparent; + int i17 = 0xff439eb2; + if (l4 != l1) { + i15 = (k10 - i6 << 8) / (l4 - l1); + i16 = (k13 - k11 << 8) / (l4 - l1); + if (l1 < l4) { + k14 = i6 << 8; + k15 = k11 << 8; + k16 = l1; + i17 = l4; + } else { + k14 = k10 << 8; + k15 = k13 << 8; + k16 = l4; + i17 = l1; + } + if (k16 < 0) { + k14 -= i15 * k16; + k15 -= i16 * k16; + k16 = 0; + } + if (i17 > i14) + i17 = i14; + } + int k17 = 0; + int i18 = 0; + int k18 = 0; + int i19 = 0; + int k19 = World.colourTransparent; + int i20 = 0xff439eb2; + if (l2 != l1) { + i18 = (k7 - i6 << 8) / (l2 - l1); + i19 = (k12 - k11 << 8) / (l2 - l1); + if (l1 < l2) { + k17 = i6 << 8; + k18 = k11 << 8; + k19 = l1; + i20 = l2; + } else { + k17 = k7 << 8; + k18 = k12 << 8; + k19 = l2; + i20 = l1; + } + if (k19 < 0) { + k17 -= i18 * k19; + k18 -= i19 * k19; + k19 = 0; + } + if (i20 > i14) + i20 = i14; + } + int k20 = 0; + int i21 = 0; + int k21 = 0; + int i22 = 0; + int j22 = World.colourTransparent; + int k22 = 0xff439eb2; + if (l3 != l2) { + i21 = (i9 - k7 << 8) / (l3 - l2); + i22 = (i13 - k12 << 8) / (l3 - l2); + if (l2 < l3) { + k20 = k7 << 8; + k21 = k12 << 8; + j22 = l2; + k22 = l3; + } else { + k20 = i9 << 8; + k21 = i13 << 8; + j22 = l3; + k22 = l2; + } + if (j22 < 0) { + k20 -= i21 * j22; + k21 -= i22 * j22; + j22 = 0; + } + if (k22 > i14) + k22 = i14; + } + int l22 = 0; + int i23 = 0; + int j23 = 0; + int k23 = 0; + int l23 = World.colourTransparent; + int i24 = 0xff439eb2; + if (l4 != l3) { + i23 = (k10 - i9 << 8) / (l4 - l3); + k23 = (k13 - i13 << 8) / (l4 - l3); + if (l3 < l4) { + l22 = i9 << 8; + j23 = i13 << 8; + l23 = l3; + i24 = l4; + } else { + l22 = k10 << 8; + j23 = k13 << 8; + l23 = l4; + i24 = l3; + } + if (l23 < 0) { + l22 -= i23 * l23; + j23 -= k23 * l23; + l23 = 0; + } + if (i24 > i14) + i24 = i14; + } + minY = k16; + if (k19 < minY) + minY = k19; + if (j22 < minY) + minY = j22; + if (l23 < minY) + minY = l23; + maxY = i17; + if (i20 > maxY) + maxY = i20; + if (k22 > maxY) + maxY = k22; + if (i24 > maxY) + maxY = i24; + int j24 = 0; + for (k = minY; k < maxY; k++) { + if (k >= k16 && k < i17) { + i = j = k14; + l = j24 = k15; + k14 += i15; + k15 += i16; + } else { + i = 0xa0000; + j = 0xfff60000; + } + if (k >= k19 && k < i20) { + if (k17 < i) { + i = k17; + l = k18; + } + if (k17 > j) { + j = k17; + j24 = k18; + } + k17 += i18; + k18 += i19; + } + if (k >= j22 && k < k22) { + if (k20 < i) { + i = k20; + l = k21; + } + if (k20 > j) { + j = k20; + j24 = k21; + } + k20 += i21; + k21 += i22; + } + if (k >= l23 && k < i24) { + if (l22 < i) { + i = l22; + l = j23; + } + if (l22 > j) { + j = l22; + j24 = j23; + } + l22 += i23; + j23 += k23; + } + Scanline scanline_7 = scanlines[k]; + scanline_7.startX = i; + scanline_7.endX = j; + scanline_7.startS = l; + scanline_7.endS = j24; + } + + if (minY < baseY - clipY) + minY = baseY - clipY; + } else { + maxY = minY = ai1[0] += baseY; + for (k = 1; k < i1; k++) { + int i2; + if ((i2 = ai1[k] += baseY) < minY) + minY = i2; + else if (i2 > maxY) + maxY = i2; + } + + if (minY < baseY - clipY) + minY = baseY - clipY; + if (maxY >= baseY + clipY) + maxY = (baseY + clipY) - 1; + if (minY >= maxY) + return; + for (k = minY; k < maxY; k++) { + Scanline scanline = scanlines[k]; + scanline.startX = 0xa0000; + scanline.endX = 0xfff60000; + } + + int j2 = i1 - 1; + int i3 = ai1[0]; + int i4 = ai1[j2]; + if (i3 < i4) { + int i5 = ai[0] << 8; + int j6 = (ai[j2] - ai[0] << 8) / (i4 - i3); + int l7 = ai2[0] << 8; + int j9 = (ai2[j2] - ai2[0] << 8) / (i4 - i3); + if (i3 < 0) { + i5 -= j6 * i3; + l7 -= j9 * i3; + i3 = 0; + } + if (i4 > maxY) + i4 = maxY; + for (k = i3; k <= i4; k++) { + Scanline scanline_2 = scanlines[k]; + scanline_2.startX = scanline_2.endX = i5; + scanline_2.startS = scanline_2.endS = l7; + i5 += j6; + l7 += j9; + } + + } else if (i3 > i4) { + int j5 = ai[j2] << 8; + int k6 = (ai[0] - ai[j2] << 8) / (i3 - i4); + int i8 = ai2[j2] << 8; + int k9 = (ai2[0] - ai2[j2] << 8) / (i3 - i4); + if (i4 < 0) { + j5 -= k6 * i4; + i8 -= k9 * i4; + i4 = 0; + } + if (i3 > maxY) + i3 = maxY; + for (k = i4; k <= i3; k++) { + Scanline scanline_3 = scanlines[k]; + scanline_3.startX = scanline_3.endX = j5; + scanline_3.startS = scanline_3.endS = i8; + j5 += k6; + i8 += k9; + } + + } + for (k = 0; k < j2; k++) { + int k5 = k + 1; + int j3 = ai1[k]; + int j4 = ai1[k5]; + if (j3 < j4) { + int l6 = ai[k] << 8; + int j8 = (ai[k5] - ai[k] << 8) / (j4 - j3); + int l9 = ai2[k] << 8; + int l10 = (ai2[k5] - ai2[k] << 8) / (j4 - j3); + if (j3 < 0) { + l6 -= j8 * j3; + l9 -= l10 * j3; + j3 = 0; + } + if (j4 > maxY) + j4 = maxY; + for (int l11 = j3; l11 <= j4; l11++) { + Scanline scanline_4 = scanlines[l11]; + if (l6 < scanline_4.startX) { + scanline_4.startX = l6; + scanline_4.startS = l9; + } + if (l6 > scanline_4.endX) { + scanline_4.endX = l6; + scanline_4.endS = l9; + } + l6 += j8; + l9 += l10; + } + + } else if (j3 > j4) { + int i7 = ai[k5] << 8; + int k8 = (ai[k] - ai[k5] << 8) / (j3 - j4); + int i10 = ai2[k5] << 8; + int i11 = (ai2[k] - ai2[k5] << 8) / (j3 - j4); + if (j4 < 0) { + i7 -= k8 * j4; + i10 -= i11 * j4; + j4 = 0; + } + if (j3 > maxY) + j3 = maxY; + for (int i12 = j4; i12 <= j3; i12++) { + Scanline scanline_5 = scanlines[i12]; + if (i7 < scanline_5.startX) { + scanline_5.startX = i7; + scanline_5.startS = i10; + } + if (i7 > scanline_5.endX) { + scanline_5.endX = i7; + scanline_5.endS = i10; + } + i7 += k8; + i10 += i11; + } + + } + } + + if (minY < baseY - clipY) + minY = baseY - clipY; + } + if (mousePickingActive && mousePickedCount < mousePickedMax && mouseY >= minY && mouseY < maxY) { + Scanline scanline_1 = scanlines[mouseY]; + if (mouseX >= scanline_1.startX >> 8 && mouseX <= scanline_1.endX >> 8 && scanline_1.startX <= scanline_1.endX && !gameModel.unpickable && gameModel.isLocalPlayer[pid] == 0) { + mousePickedModels[mousePickedCount] = gameModel; + mousePickedFaces[mousePickedCount] = pid; + mousePickedCount++; + } + } + } + + private void rasterize(int i, int j, int k, int ai[], int ai1[], int ai2[], int l, + GameModel gameModel) { + if (l == -2) + return; + if (l >= 0) { + if (l >= textureCount) + l = 0; + prepareTexture(l); + int i1 = ai[0]; + int k1 = ai1[0]; + int j2 = ai2[0]; + int i3 = i1 - ai[1]; + int k3 = k1 - ai1[1]; + int i4 = j2 - ai2[1]; + k--; + int i6 = ai[k] - i1; + int j7 = ai1[k] - k1; + int k8 = ai2[k] - j2; + if (textureDimension[l] == 1) { + int l9 = i6 * k1 - j7 * i1 << 12; + int k10 = j7 * j2 - k8 * k1 << (5 - viewDistance) + 7 + 4; + int i11 = k8 * i1 - i6 * j2 << (5 - viewDistance) + 7; + int k11 = i3 * k1 - k3 * i1 << 12; + int i12 = k3 * j2 - i4 * k1 << (5 - viewDistance) + 7 + 4; + int k12 = i4 * i1 - i3 * j2 << (5 - viewDistance) + 7; + int i13 = k3 * i6 - i3 * j7 << 5; + int k13 = i4 * j7 - k3 * k8 << (5 - viewDistance) + 4; + int i14 = i3 * k8 - i4 * i6 >> viewDistance - 5; + int k14 = k10 >> 4; + int i15 = i12 >> 4; + int k15 = k13 >> 4; + int i16 = minY - baseY; + int k16 = width; + int i17 = baseX + minY * k16; + byte byte1 = 1; + l9 += i11 * i16; + k11 += k12 * i16; + i13 += i14 * i16; + if (interlace) { + if ((minY & 1) == 1) { + minY++; + l9 += i11; + k11 += k12; + i13 += i14; + i17 += k16; + } + i11 <<= 1; + k12 <<= 1; + i14 <<= 1; + k16 <<= 1; + byte1 = 2; + } + if (gameModel.textureTranslucent) { + for (i = minY; i < maxY; i += byte1) { + Scanline scanline_3 = scanlines[i]; + j = scanline_3.startX >> 8; + int k17 = scanline_3.endX >> 8; + int k20 = k17 - j; + if (k20 <= 0) { + l9 += i11; + k11 += k12; + i13 += i14; + i17 += k16; + } else { + int i22 = scanline_3.startS; + int k23 = (scanline_3.endS - i22) / k20; + if (j < -clipX) { + i22 += (-clipX - j) * k23; + j = -clipX; + k20 = k17 - j; + } + if (k17 > clipX) { + int l17 = clipX; + k20 = l17 - j; + } + textureTranslucentScanline(raster, texturePixels[l], 0, 0, l9 + k14 * j, k11 + i15 * j, i13 + k15 * j, k10, i12, k13, k20, i17 + j, i22, k23 << 2); + l9 += i11; + k11 += k12; + i13 += i14; + i17 += k16; + } + } + + return; + } + if (!textureBackTransparent[l]) { + for (i = minY; i < maxY; i += byte1) { + Scanline scanline_4 = scanlines[i]; + j = scanline_4.startX >> 8; + int i18 = scanline_4.endX >> 8; + int l20 = i18 - j; + if (l20 <= 0) { + l9 += i11; + k11 += k12; + i13 += i14; + i17 += k16; + } else { + int j22 = scanline_4.startS; + int l23 = (scanline_4.endS - j22) / l20; + if (j < -clipX) { + j22 += (-clipX - j) * l23; + j = -clipX; + l20 = i18 - j; + } + if (i18 > clipX) { + int j18 = clipX; + l20 = j18 - j; + } + textureScanline(raster, texturePixels[l], 0, 0, l9 + k14 * j, k11 + i15 * j, i13 + k15 * j, k10, i12, k13, l20, i17 + j, j22, l23 << 2); + l9 += i11; + k11 += k12; + i13 += i14; + i17 += k16; + } + } + + return; + } + for (i = minY; i < maxY; i += byte1) { + Scanline scanline_5 = scanlines[i]; + j = scanline_5.startX >> 8; + int k18 = scanline_5.endX >> 8; + int i21 = k18 - j; + if (i21 <= 0) { + l9 += i11; + k11 += k12; + i13 += i14; + i17 += k16; + } else { + int k22 = scanline_5.startS; + int i24 = (scanline_5.endS - k22) / i21; + if (j < -clipX) { + k22 += (-clipX - j) * i24; + j = -clipX; + i21 = k18 - j; + } + if (k18 > clipX) { + int l18 = clipX; + i21 = l18 - j; + } + textureBackTranslucentScanline(raster, 0, 0, 0, texturePixels[l], l9 + k14 * j, k11 + i15 * j, i13 + k15 * j, k10, i12, k13, i21, i17 + j, k22, i24); + l9 += i11; + k11 += k12; + i13 += i14; + i17 += k16; + } + } + + return; + } + int i10 = i6 * k1 - j7 * i1 << 11; + int l10 = j7 * j2 - k8 * k1 << (5 - viewDistance) + 6 + 4; + int j11 = k8 * i1 - i6 * j2 << (5 - viewDistance) + 6; + int l11 = i3 * k1 - k3 * i1 << 11; + int j12 = k3 * j2 - i4 * k1 << (5 - viewDistance) + 6 + 4; + int l12 = i4 * i1 - i3 * j2 << (5 - viewDistance) + 6; + int j13 = k3 * i6 - i3 * j7 << 5; + int l13 = i4 * j7 - k3 * k8 << (5 - viewDistance) + 4; + int j14 = i3 * k8 - i4 * i6 >> viewDistance - 5; + int l14 = l10 >> 4; + int j15 = j12 >> 4; + int l15 = l13 >> 4; + int j16 = minY - baseY; + int l16 = width; + int j17 = baseX + minY * l16; + byte byte2 = 1; + i10 += j11 * j16; + l11 += l12 * j16; + j13 += j14 * j16; + if (interlace) { + if ((minY & 1) == 1) { + minY++; + i10 += j11; + l11 += l12; + j13 += j14; + j17 += l16; + } + j11 <<= 1; + l12 <<= 1; + j14 <<= 1; + l16 <<= 1; + byte2 = 2; + } + if (gameModel.textureTranslucent) { + for (i = minY; i < maxY; i += byte2) { + Scanline scanline_6 = scanlines[i]; + j = scanline_6.startX >> 8; + int i19 = scanline_6.endX >> 8; + int j21 = i19 - j; + if (j21 <= 0) { + i10 += j11; + l11 += l12; + j13 += j14; + j17 += l16; + } else { + int l22 = scanline_6.startS; + int j24 = (scanline_6.endS - l22) / j21; + if (j < -clipX) { + l22 += (-clipX - j) * j24; + j = -clipX; + j21 = i19 - j; + } + if (i19 > clipX) { + int j19 = clipX; + j21 = j19 - j; + } + textureTranslucentScanline2(raster, texturePixels[l], 0, 0, i10 + l14 * j, l11 + j15 * j, j13 + l15 * j, l10, j12, l13, j21, j17 + j, l22, j24); + i10 += j11; + l11 += l12; + j13 += j14; + j17 += l16; + } + } + + return; + } + if (!textureBackTransparent[l]) { + for (i = minY; i < maxY; i += byte2) { + Scanline scanline_7 = scanlines[i]; + j = scanline_7.startX >> 8; + int k19 = scanline_7.endX >> 8; + int k21 = k19 - j; + if (k21 <= 0) { + i10 += j11; + l11 += l12; + j13 += j14; + j17 += l16; + } else { + int i23 = scanline_7.startS; + int k24 = (scanline_7.endS - i23) / k21; + if (j < -clipX) { + i23 += (-clipX - j) * k24; + j = -clipX; + k21 = k19 - j; + } + if (k19 > clipX) { + int l19 = clipX; + k21 = l19 - j; + } + textureScanline2(raster, texturePixels[l], 0, 0, i10 + l14 * j, l11 + j15 * j, j13 + l15 * j, l10, j12, l13, k21, j17 + j, i23, k24); + i10 += j11; + l11 += l12; + j13 += j14; + j17 += l16; + } + } + + return; + } + for (i = minY; i < maxY; i += byte2) { + Scanline scanline = scanlines[i]; + j = scanline.startX >> 8; + int i20 = scanline.endX >> 8; + int l21 = i20 - j; + if (l21 <= 0) { + i10 += j11; + l11 += l12; + j13 += j14; + j17 += l16; + } else { + int j23 = scanline.startS; + int l24 = (scanline.endS - j23) / l21; + if (j < -clipX) { + j23 += (-clipX - j) * l24; + j = -clipX; + l21 = i20 - j; + } + if (i20 > clipX) { + int j20 = clipX; + l21 = j20 - j; + } + textureBackTranslucentScanline2(raster, 0, 0, 0, texturePixels[l], i10 + l14 * j, l11 + j15 * j, j13 + l15 * j, l10, j12, l13, l21, j17 + j, j23, l24); + i10 += j11; + l11 += l12; + j13 += j14; + j17 += l16; + } + } + + return; + } + for (int j1 = 0; j1 < rampCount; j1++) { + if (gradientBase[j1] == l) { + anIntArray377 = gradientRamps[j1]; + break; + } + if (j1 == rampCount - 1) { + int l1 = (int) (Math.random() * (double) rampCount); + gradientBase[l1] = l; + l = -1 - l; + int k2 = (l >> 10 & 0x1f) * 8; + int j3 = (l >> 5 & 0x1f) * 8; + int l3 = (l & 0x1f) * 8; + for (int j4 = 0; j4 < 256; j4++) { + int j6 = j4 * j4; + int k7 = (k2 * j6) / 0x10000; + int l8 = (j3 * j6) / 0x10000; + int j10 = (l3 * j6) / 0x10000; + gradientRamps[l1][255 - j4] = (k7 << 16) + (l8 << 8) + j10; + } + + anIntArray377 = gradientRamps[l1]; + } + } + + int i2 = width; + int l2 = baseX + minY * i2; + byte byte0 = 1; + if (interlace) { + if ((minY & 1) == 1) { + minY++; + l2 += i2; + } + i2 <<= 1; + byte0 = 2; + } + if (gameModel.transparent) { + for (i = minY; i < maxY; i += byte0) { + Scanline scanline = scanlines[i]; + j = scanline.startX >> 8; + int k4 = scanline.endX >> 8; + int k6 = k4 - j; + if (k6 <= 0) { + l2 += i2; + } else { + int l7 = scanline.startS; + int i9 = (scanline.endS - l7) / k6; + if (j < -clipX) { + l7 += (-clipX - j) * i9; + j = -clipX; + k6 = k4 - j; + } + if (k4 > clipX) { + int l4 = clipX; + k6 = l4 - j; + } + textureGradientScanline(raster, -k6, l2 + j, 0, anIntArray377, l7, i9); + l2 += i2; + } + } + + return; + } + if (wideBand) { + for (i = minY; i < maxY; i += byte0) { + Scanline scanline_1 = scanlines[i]; + j = scanline_1.startX >> 8; + int i5 = scanline_1.endX >> 8; + int l6 = i5 - j; + if (l6 <= 0) { + l2 += i2; + } else { + int i8 = scanline_1.startS; + int j9 = (scanline_1.endS - i8) / l6; + if (j < -clipX) { + i8 += (-clipX - j) * j9; + j = -clipX; + l6 = i5 - j; + } + if (i5 > clipX) { + int j5 = clipX; + l6 = j5 - j; + } + gradientScanline(raster, -l6, l2 + j, 0, anIntArray377, i8, j9); + l2 += i2; + } + } + + return; + } + for (i = minY; i < maxY; i += byte0) { + Scanline scanline_2 = scanlines[i]; + j = scanline_2.startX >> 8; + int k5 = scanline_2.endX >> 8; + int i7 = k5 - j; + if (i7 <= 0) { + l2 += i2; + } else { + int j8 = scanline_2.startS; + int k9 = (scanline_2.endS - j8) / i7; + if (j < -clipX) { + j8 += (-clipX - j) * k9; + j = -clipX; + i7 = k5 - j; + } + if (k5 > clipX) { + int l5 = clipX; + i7 = l5 - j; + } + gradientScanline2(raster, -i7, l2 + j, 0, anIntArray377, j8, k9); + l2 += i2; + } + } + + } + + public void setCamera(int x, int z, int y, int pitch, int yaw, int roll, int distance) { + pitch &= 0x3ff; + yaw &= 0x3ff; + roll &= 0x3ff; + cameraYaw = 1024 - pitch & 0x3ff; + cameraPitch = 1024 - yaw & 0x3ff; + cameraRoll = 1024 - roll & 0x3ff; + int l1 = 0; + int i2 = 0; + int j2 = distance; + if (pitch != 0) { + int k2 = sin2048Cache[pitch]; + int j3 = sin2048Cache[pitch + 1024]; + int i4 = i2 * j3 - j2 * k2 >> 15; + j2 = i2 * k2 + j2 * j3 >> 15; + i2 = i4; + } + if (yaw != 0) { + int l2 = sin2048Cache[yaw]; + int k3 = sin2048Cache[yaw + 1024]; + int j4 = j2 * l2 + l1 * k3 >> 15; + j2 = j2 * k3 - l1 * l2 >> 15; + l1 = j4; + } + if (roll != 0) { + int i3 = sin2048Cache[roll]; + int l3 = sin2048Cache[roll + 1024]; + int k4 = i2 * i3 + l1 * l3 >> 15; + i2 = i2 * l3 - l1 * i3 >> 15; + l1 = k4; + } + cameraX = x - l1; + cameraY = z - i2; + cameraZ = y - j2; + } + + private void initialisePolygon3d(int i) { + Polygon polygon = visiblePolygons[i]; + GameModel gameModel = polygon.model; + int face = polygon.face; + int faceVertices[] = gameModel.faceVertices[face]; + int faceNumVertices = gameModel.faceNumVertices[face]; + int faceCameraNormalScale = gameModel.normalScale[face]; + int vcx = gameModel.projectVertexX[faceVertices[0]]; + int vcy = gameModel.projectVertexY[faceVertices[0]]; + int vcz = gameModel.projectVertexZ[faceVertices[0]]; + int vcx1 = gameModel.projectVertexX[faceVertices[1]] - vcx; + int vcy1 = gameModel.projectVertexY[faceVertices[1]] - vcy; + int vcz1 = gameModel.projectVertexZ[faceVertices[1]] - vcz; + int vcx2 = gameModel.projectVertexX[faceVertices[2]] - vcx; + int vcy2 = gameModel.projectVertexY[faceVertices[2]] - vcy; + int vcz2 = gameModel.projectVertexZ[faceVertices[2]] - vcz; + int t1 = vcy1 * vcz2 - vcy2 * vcz1; + int t2 = vcz1 * vcx2 - vcz2 * vcx1; + int t3 = vcx1 * vcy2 - vcx2 * vcy1; + if (faceCameraNormalScale == -1) { + faceCameraNormalScale = 0; + for (; t1 > 25000 || t2 > 25000 || t3 > 25000 || t1 < -25000 || t2 < -25000 || t3 < -25000; t3 >>= 1) { + faceCameraNormalScale++; + t1 >>= 1; + t2 >>= 1; + } + + gameModel.normalScale[face] = faceCameraNormalScale; + gameModel.normalMagnitude[face] = (int) ((double) normalMagnitude * Math.sqrt(t1 * t1 + t2 * t2 + t3 * t3)); + } else { + t1 >>= faceCameraNormalScale; + t2 >>= faceCameraNormalScale; + t3 >>= faceCameraNormalScale; + } + polygon.visibility = vcx * t1 + vcy * t2 + vcz * t3; + polygon.normalX = t1; + polygon.normalY = t2; + polygon.normalZ = t3; + int j4 = gameModel.projectVertexZ[faceVertices[0]]; + int k4 = j4; + int l4 = gameModel.vertexViewX[faceVertices[0]]; + int i5 = l4; + int j5 = gameModel.vertexViewY[faceVertices[0]]; + int k5 = j5; + for (int l5 = 1; l5 < faceNumVertices; l5++) { + int i1 = gameModel.projectVertexZ[faceVertices[l5]]; + if (i1 > k4) + k4 = i1; + else if (i1 < j4) + j4 = i1; + i1 = gameModel.vertexViewX[faceVertices[l5]]; + if (i1 > i5) + i5 = i1; + else if (i1 < l4) + l4 = i1; + i1 = gameModel.vertexViewY[faceVertices[l5]]; + if (i1 > k5) + k5 = i1; + else if (i1 < j5) + j5 = i1; + } + + polygon.minZ = j4; + polygon.maxZ = k4; + polygon.minPlaneX = l4; + polygon.maxPlaneX = i5; + polygon.minPlaneY = j5; + polygon.maxPlaneY = k5; + } + + private void initialisePolygon2d(int i) { + Polygon polygon = visiblePolygons[i]; + GameModel gameModel = polygon.model; + int j = polygon.face; + int ai[] = gameModel.faceVertices[j]; + int l = 0; + int i1 = 0; + int j1 = 1; + int k1 = gameModel.projectVertexX[ai[0]]; + int l1 = gameModel.projectVertexY[ai[0]]; + int i2 = gameModel.projectVertexZ[ai[0]]; + gameModel.normalMagnitude[j] = 1; + gameModel.normalScale[j] = 0; + polygon.visibility = k1 * l + l1 * i1 + i2 * j1; + polygon.normalX = l; + polygon.normalY = i1; + polygon.normalZ = j1; + int j2 = gameModel.projectVertexZ[ai[0]]; + int k2 = j2; + int l2 = gameModel.vertexViewX[ai[0]]; + int i3 = l2; + if (gameModel.vertexViewX[ai[1]] < l2) + l2 = gameModel.vertexViewX[ai[1]]; + else + i3 = gameModel.vertexViewX[ai[1]]; + int j3 = gameModel.vertexViewY[ai[1]]; + int k3 = gameModel.vertexViewY[ai[0]]; + int k = gameModel.projectVertexZ[ai[1]]; + if (k > k2) + k2 = k; + else if (k < j2) + j2 = k; + k = gameModel.vertexViewX[ai[1]]; + if (k > i3) + i3 = k; + else if (k < l2) + l2 = k; + k = gameModel.vertexViewY[ai[1]]; + if (k > k3) + k3 = k; + else if (k < j3) + j3 = k; + polygon.minZ = j2; + polygon.maxZ = k2; + polygon.minPlaneX = l2 - 20; + polygon.maxPlaneX = i3 + 20; + polygon.minPlaneY = j3; + polygon.maxPlaneY = k3; + } + + private boolean separatePolygon(Polygon polygon, Polygon polygon_1) { + if (polygon.minPlaneX >= polygon_1.maxPlaneX) + return true; + if (polygon_1.minPlaneX >= polygon.maxPlaneX) + return true; + if (polygon.minPlaneY >= polygon_1.maxPlaneY) + return true; + if (polygon_1.minPlaneY >= polygon.maxPlaneY) + return true; + if (polygon.minZ >= polygon_1.maxZ) + return true; + if (polygon_1.minZ > polygon.maxZ) + return false; + GameModel gameModel = polygon.model; + GameModel gameModel_1 = polygon_1.model; + int i = polygon.face; + int j = polygon_1.face; + int ai[] = gameModel.faceVertices[i]; + int ai1[] = gameModel_1.faceVertices[j]; + int k = gameModel.faceNumVertices[i]; + int l = gameModel_1.faceNumVertices[j]; + int k2 = gameModel_1.projectVertexX[ai1[0]]; + int l2 = gameModel_1.projectVertexY[ai1[0]]; + int i3 = gameModel_1.projectVertexZ[ai1[0]]; + int j3 = polygon_1.normalX; + int k3 = polygon_1.normalY; + int l3 = polygon_1.normalZ; + int i4 = gameModel_1.normalMagnitude[j]; + int j4 = polygon_1.visibility; + boolean flag = false; + for (int k4 = 0; k4 < k; k4++) { + int i1 = ai[k4]; + int i2 = (k2 - gameModel.projectVertexX[i1]) * j3 + (l2 - gameModel.projectVertexY[i1]) * k3 + (i3 - gameModel.projectVertexZ[i1]) * l3; + if ((i2 >= -i4 || j4 >= 0) && (i2 <= i4 || j4 <= 0)) + continue; + flag = true; + break; + } + + if (!flag) + return true; + k2 = gameModel.projectVertexX[ai[0]]; + l2 = gameModel.projectVertexY[ai[0]]; + i3 = gameModel.projectVertexZ[ai[0]]; + j3 = polygon.normalX; + k3 = polygon.normalY; + l3 = polygon.normalZ; + i4 = gameModel.normalMagnitude[i]; + j4 = polygon.visibility; + flag = false; + for (int l4 = 0; l4 < l; l4++) { + int j1 = ai1[l4]; + int j2 = (k2 - gameModel_1.projectVertexX[j1]) * j3 + (l2 - gameModel_1.projectVertexY[j1]) * k3 + (i3 - gameModel_1.projectVertexZ[j1]) * l3; + if ((j2 >= -i4 || j4 <= 0) && (j2 <= i4 || j4 >= 0)) + continue; + flag = true; + break; + } + + if (!flag) + return true; + int ai2[]; + int ai3[]; + if (k == 2) { + ai2 = new int[4]; + ai3 = new int[4]; + int i5 = ai[0]; + int k1 = ai[1]; + ai2[0] = gameModel.vertexViewX[i5] - 20; + ai2[1] = gameModel.vertexViewX[k1] - 20; + ai2[2] = gameModel.vertexViewX[k1] + 20; + ai2[3] = gameModel.vertexViewX[i5] + 20; + ai3[0] = ai3[3] = gameModel.vertexViewY[i5]; + ai3[1] = ai3[2] = gameModel.vertexViewY[k1]; + } else { + ai2 = new int[k]; + ai3 = new int[k]; + for (int j5 = 0; j5 < k; j5++) { + int i6 = ai[j5]; + ai2[j5] = gameModel.vertexViewX[i6]; + ai3[j5] = gameModel.vertexViewY[i6]; + } + + } + int ai4[]; + int ai5[]; + if (l == 2) { + ai4 = new int[4]; + ai5 = new int[4]; + int k5 = ai1[0]; + int l1 = ai1[1]; + ai4[0] = gameModel_1.vertexViewX[k5] - 20; + ai4[1] = gameModel_1.vertexViewX[l1] - 20; + ai4[2] = gameModel_1.vertexViewX[l1] + 20; + ai4[3] = gameModel_1.vertexViewX[k5] + 20; + ai5[0] = ai5[3] = gameModel_1.vertexViewY[k5]; + ai5[1] = ai5[2] = gameModel_1.vertexViewY[l1]; + } else { + ai4 = new int[l]; + ai5 = new int[l]; + for (int l5 = 0; l5 < l; l5++) { + int j6 = ai1[l5]; + ai4[l5] = gameModel_1.vertexViewX[j6]; + ai5[l5] = gameModel_1.vertexViewY[j6]; + } + + } + return !intersect(ai2, ai3, ai4, ai5); + } + + private boolean heuristicPolygon(Polygon polygon, Polygon polygon_1) { + GameModel gameModel = polygon.model; + GameModel gameModel_1 = polygon_1.model; + int i = polygon.face; + int j = polygon_1.face; + int ai[] = gameModel.faceVertices[i]; + int ai1[] = gameModel_1.faceVertices[j]; + int k = gameModel.faceNumVertices[i]; + int l = gameModel_1.faceNumVertices[j]; + int i2 = gameModel_1.projectVertexX[ai1[0]]; + int j2 = gameModel_1.projectVertexY[ai1[0]]; + int k2 = gameModel_1.projectVertexZ[ai1[0]]; + int l2 = polygon_1.normalX; + int i3 = polygon_1.normalY; + int j3 = polygon_1.normalZ; + int k3 = gameModel_1.normalMagnitude[j]; + int l3 = polygon_1.visibility; + boolean flag = false; + for (int i4 = 0; i4 < k; i4++) { + int i1 = ai[i4]; + int k1 = (i2 - gameModel.projectVertexX[i1]) * l2 + (j2 - gameModel.projectVertexY[i1]) * i3 + (k2 - gameModel.projectVertexZ[i1]) * j3; + if ((k1 >= -k3 || l3 >= 0) && (k1 <= k3 || l3 <= 0)) + continue; + flag = true; + break; + } + + if (!flag) + return true; + i2 = gameModel.projectVertexX[ai[0]]; + j2 = gameModel.projectVertexY[ai[0]]; + k2 = gameModel.projectVertexZ[ai[0]]; + l2 = polygon.normalX; + i3 = polygon.normalY; + j3 = polygon.normalZ; + k3 = gameModel.normalMagnitude[i]; + l3 = polygon.visibility; + flag = false; + for (int j4 = 0; j4 < l; j4++) { + int j1 = ai1[j4]; + int l1 = (i2 - gameModel_1.projectVertexX[j1]) * l2 + (j2 - gameModel_1.projectVertexY[j1]) * i3 + (k2 - gameModel_1.projectVertexZ[j1]) * j3; + if ((l1 >= -k3 || l3 <= 0) && (l1 <= k3 || l3 >= 0)) + continue; + flag = true; + break; + } + + return !flag; + } + + public void allocateTextures(int count, int something7, int something11) { + textureCount = count; + textureColoursUsed = new byte[count][]; + textureColourList = new int[count][]; + textureDimension = new int[count]; + textureLoadedNumber = new long[count]; + textureBackTransparent = new boolean[count]; + texturePixels = new int[count][]; + textureCountLoaded = 0L; + textureColours64 = new int[something7][];// 64x64 rgba + textureColours128 = new int[something11][];// 128x128 rgba + } + + public void defineTexture(int id, byte usedColours[], int colours[], int wide128) { + textureColoursUsed[id] = usedColours; + textureColourList[id] = colours; + textureDimension[id] = wide128;// is 1 if the texture is 128+ pixels wide, 0 if <128 + textureLoadedNumber[id] = 0L;// as in the current loaded texture count when its loaded + textureBackTransparent[id] = false; + texturePixels[id] = null; + prepareTexture(id); + } + + public void prepareTexture(int id) { + if (id < 0) + return; + textureLoadedNumber[id] = textureCountLoaded++; + if (texturePixels[id] != null) + return; + if (textureDimension[id] == 0) {// is 64 pixels wide + for (int j = 0; j < textureColours64.length; j++) + if (textureColours64[j] == null) { + textureColours64[j] = new int[16384]; + texturePixels[id] = textureColours64[j]; + setTexturePixels(id); + return; + } + + long GIGALONG = 1L << 30;// almost as large as exemplar's nas storage + int wut = 0; + for (int k1 = 0; k1 < textureCount; k1++) + if (k1 != id && textureDimension[k1] == 0 && texturePixels[k1] != null && textureLoadedNumber[k1] < GIGALONG) { + GIGALONG = textureLoadedNumber[k1]; + wut = k1; + } + + texturePixels[id] = texturePixels[wut]; + texturePixels[wut] = null; + setTexturePixels(id); + return; + } + // is 128 wide + for (int k = 0; k < textureColours128.length; k++) + if (textureColours128[k] == null) { + textureColours128[k] = new int[0x10000]; + texturePixels[id] = textureColours128[k]; + setTexturePixels(id); + return; + } + + long GIGALONG = 1L << 30;// 1G 2G 3G... 4G? + int wat = 0; + for (int i2 = 0; i2 < textureCount; i2++) + if (i2 != id && textureDimension[i2] == 1 && texturePixels[i2] != null && textureLoadedNumber[i2] < GIGALONG) { + GIGALONG = textureLoadedNumber[i2]; + wat = i2; + } + + texturePixels[id] = texturePixels[wat]; + texturePixels[wat] = null; + setTexturePixels(id); + } + + private void setTexturePixels(int id) { + char textureWidth; + if (textureDimension[id] == 0) + textureWidth = 64;//'@'; + else + textureWidth = 128;//'\200'; + int colours[] = texturePixels[id]; + int colourCount = 0; + for (int x = 0; x < textureWidth; x++) { + for (int y = 0; y < textureWidth; y++) { + int colour = textureColourList[id][textureColoursUsed[id][y + x * textureWidth] & 0xff]; + colour &= 0xf8f8ff; + if (colour == 0) + colour = 1; + else if (colour == 0xf800ff) { + colour = 0; + textureBackTransparent[id] = true; + } + colours[colourCount++] = colour; + } + + } + + for (int i1 = 0; i1 < colourCount; i1++) { + int colour = colours[i1];// ?? + colours[colourCount + i1] = colour - (colour >>> 3) & 0xf8f8ff; + colours[colourCount * 2 + i1] = colour - (colour >>> 2) & 0xf8f8ff; + colours[colourCount * 3 + i1] = colour - (colour >>> 2) - (colour >>> 3) & 0xf8f8ff; + } + } + + public void doSOemthingWithTheFuckinFountainFuck(int id) { + if (texturePixels[id] == null) + return; + int colours[] = texturePixels[id]; + for (int i = 0; i < 64; i++) { + int k = i + 4032; + int l = colours[k]; + for (int j1 = 0; j1 < 63; j1++) { + colours[k] = colours[k - 64]; + k -= 64; + } + + texturePixels[id][k] = l; + } + + char c = 4096; + for (int i1 = 0; i1 < c; i1++) { + int k1 = colours[i1]; + colours[c + i1] = k1 - (k1 >>> 3) & 0xf8f8ff; + colours[c * 2 + i1] = k1 - (k1 >>> 2) & 0xf8f8ff; + colours[c * 3 + i1] = k1 - (k1 >>> 2) - (k1 >>> 3) & 0xf8f8ff; + } + + } + + public int method302(int i) { + if (i == World.colourTransparent) + return 0; + prepareTexture(i); + if (i >= 0) + return texturePixels[i][0]; + if (i < 0) { + i = -(i + 1); + int j = i >> 10 & 0x1f; + int k = i >> 5 & 0x1f; + int l = i & 0x1f; + return (j << 19) + (k << 11) + (l << 3); + } else { + return 0; + } + } + + public void setLight(int i, int j, int k) { + if (i == 0 && j == 0 && k == 0) + i = 32; + for (int l = 0; l < modelCount; l++) + models[l].setLight(i, j, k); + + } + + public void setLight(int i, int j, int k, int l, int i1) { + if (k == 0 && l == 0 && i1 == 0) + k = 32; + for (int j1 = 0; j1 < modelCount; j1++) + models[j1].setLight(i, j, k, l, i1); + + } + + public int method306(int i, int j, int k, int l, int i1) { + if (l == j) + return i; + else + return i + ((k - i) * (i1 - j)) / (l - j); + } + + public boolean method307(int i, int j, int k, int l, boolean flag) { + if (flag && i <= k || i < k) { + if (i > l) + return true; + if (j > k) + return true; + if (j > l) + return true; + return !flag; + } + if (i < l) + return true; + if (j < k) + return true; + if (j < l) + return true; + else + return flag; + } + + public boolean method308(int i, int j, int k, boolean flag) { + if (flag && i <= k || i < k) { + if (j > k) + return true; + return !flag; + } + if (j < k) + return true; + else + return flag; + } + + public boolean intersect(int ai[], int ai1[], int ai2[], int ai3[]) { + int i = ai.length; + int j = ai2.length; + byte byte0 = 0; + int i20; + int k20 = i20 = ai1[0]; + int k = 0; + int j20; + int l20 = j20 = ai3[0]; + int i1 = 0; + for (int i21 = 1; i21 < i; i21++) + if (ai1[i21] < i20) { + i20 = ai1[i21]; + k = i21; + } else if (ai1[i21] > k20) + k20 = ai1[i21]; + + for (int j21 = 1; j21 < j; j21++) + if (ai3[j21] < j20) { + j20 = ai3[j21]; + i1 = j21; + } else if (ai3[j21] > l20) + l20 = ai3[j21]; + + if (j20 >= k20) + return false; + if (i20 >= l20) + return false; + int l; + int j1; + boolean flag; + if (ai1[k] < ai3[i1]) { + for (l = k; ai1[l] < ai3[i1]; l = (l + 1) % i) ; + for (; ai1[k] < ai3[i1]; k = ((k - 1) + i) % i) ; + int k1 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[i1]); + int k6 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[i1]); + int l10 = ai2[i1]; + flag = (k1 < l10) | (k6 < l10); + if (method308(k1, k6, l10, flag)) + return true; + j1 = (i1 + 1) % j; + i1 = ((i1 - 1) + j) % j; + if (k == l) + byte0 = 1; + } else { + for (j1 = i1; ai3[j1] < ai1[k]; j1 = (j1 + 1) % j) ; + for (; ai3[i1] < ai1[k]; i1 = ((i1 - 1) + j) % j) ; + int l1 = ai[k]; + int i11 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[k]); + int l15 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[k]); + flag = (l1 < i11) | (l1 < l15); + if (method308(i11, l15, l1, !flag)) + return true; + l = (k + 1) % i; + k = ((k - 1) + i) % i; + if (i1 == j1) + byte0 = 2; + } + while (byte0 == 0) + if (ai1[k] < ai1[l]) { + if (ai1[k] < ai3[i1]) { + if (ai1[k] < ai3[j1]) { + int i2 = ai[k]; + int l6 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai1[k]); + int j11 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[k]); + int i16 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[k]); + if (method307(i2, l6, j11, i16, flag)) + return true; + k = ((k - 1) + i) % i; + if (k == l) + byte0 = 1; + } else { + int j2 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[j1]); + int i7 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[j1]); + int k11 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai3[j1]); + int j16 = ai2[j1]; + if (method307(j2, i7, k11, j16, flag)) + return true; + j1 = (j1 + 1) % j; + if (i1 == j1) + byte0 = 2; + } + } else if (ai3[i1] < ai3[j1]) { + int k2 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[i1]); + int j7 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[i1]); + int l11 = ai2[i1]; + int k16 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai3[i1]); + if (method307(k2, j7, l11, k16, flag)) + return true; + i1 = ((i1 - 1) + j) % j; + if (i1 == j1) + byte0 = 2; + } else { + int l2 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[j1]); + int k7 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[j1]); + int i12 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai3[j1]); + int l16 = ai2[j1]; + if (method307(l2, k7, i12, l16, flag)) + return true; + j1 = (j1 + 1) % j; + if (i1 == j1) + byte0 = 2; + } + } else if (ai1[l] < ai3[i1]) { + if (ai1[l] < ai3[j1]) { + int i3 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai1[l]); + int l7 = ai[l]; + int j12 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[l]); + int i17 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[l]); + if (method307(i3, l7, j12, i17, flag)) + return true; + l = (l + 1) % i; + if (k == l) + byte0 = 1; + } else { + int j3 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[j1]); + int i8 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[j1]); + int k12 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai3[j1]); + int j17 = ai2[j1]; + if (method307(j3, i8, k12, j17, flag)) + return true; + j1 = (j1 + 1) % j; + if (i1 == j1) + byte0 = 2; + } + } else if (ai3[i1] < ai3[j1]) { + int k3 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[i1]); + int j8 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[i1]); + int l12 = ai2[i1]; + int k17 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai3[i1]); + if (method307(k3, j8, l12, k17, flag)) + return true; + i1 = ((i1 - 1) + j) % j; + if (i1 == j1) + byte0 = 2; + } else { + int l3 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[j1]); + int k8 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[j1]); + int i13 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai3[j1]); + int l17 = ai2[j1]; + if (method307(l3, k8, i13, l17, flag)) + return true; + j1 = (j1 + 1) % j; + if (i1 == j1) + byte0 = 2; + } + while (byte0 == 1) + if (ai1[k] < ai3[i1]) { + if (ai1[k] < ai3[j1]) { + int i4 = ai[k]; + int j13 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[k]); + int i18 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[k]); + return method308(j13, i18, i4, !flag); + } + int j4 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[j1]); + int l8 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[j1]); + int k13 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai3[j1]); + int j18 = ai2[j1]; + if (method307(j4, l8, k13, j18, flag)) + return true; + j1 = (j1 + 1) % j; + if (i1 == j1) + byte0 = 0; + } else if (ai3[i1] < ai3[j1]) { + int k4 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[i1]); + int i9 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[i1]); + int l13 = ai2[i1]; + int k18 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai3[i1]); + if (method307(k4, i9, l13, k18, flag)) + return true; + i1 = ((i1 - 1) + j) % j; + if (i1 == j1) + byte0 = 0; + } else { + int l4 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[j1]); + int j9 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[j1]); + int i14 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai3[j1]); + int l18 = ai2[j1]; + if (method307(l4, j9, i14, l18, flag)) + return true; + j1 = (j1 + 1) % j; + if (i1 == j1) + byte0 = 0; + } + while (byte0 == 2) + if (ai3[i1] < ai1[k]) { + if (ai3[i1] < ai1[l]) { + int i5 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[i1]); + int k9 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[i1]); + int j14 = ai2[i1]; + return method308(i5, k9, j14, flag); + } + int j5 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai1[l]); + int l9 = ai[l]; + int k14 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[l]); + int i19 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[l]); + if (method307(j5, l9, k14, i19, flag)) + return true; + l = (l + 1) % i; + if (k == l) + byte0 = 0; + } else if (ai1[k] < ai1[l]) { + int k5 = ai[k]; + int i10 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai1[k]); + int l14 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[k]); + int j19 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[k]); + if (method307(k5, i10, l14, j19, flag)) + return true; + k = ((k - 1) + i) % i; + if (k == l) + byte0 = 0; + } else { + int l5 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai1[l]); + int j10 = ai[l]; + int i15 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[l]); + int k19 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[l]); + if (method307(l5, j10, i15, k19, flag)) + return true; + l = (l + 1) % i; + if (k == l) + byte0 = 0; + } + if (ai1[k] < ai3[i1]) { + int i6 = ai[k]; + int j15 = method306(ai2[(i1 + 1) % j], ai3[(i1 + 1) % j], ai2[i1], ai3[i1], ai1[k]); + int l19 = method306(ai2[((j1 - 1) + j) % j], ai3[((j1 - 1) + j) % j], ai2[j1], ai3[j1], ai1[k]); + return method308(j15, l19, i6, !flag); + } + int j6 = method306(ai[(k + 1) % i], ai1[(k + 1) % i], ai[k], ai1[k], ai3[i1]); + int k10 = method306(ai[((l - 1) + i) % i], ai1[((l - 1) + i) % i], ai[l], ai1[l], ai3[i1]); + int k15 = ai2[i1]; + return method308(j6, k10, k15, flag); + } + +} diff --git a/mudclient204-threadless/StreamAudioPlayer.java b/mudclient204-threadless/StreamAudioPlayer.java new file mode 100644 index 0000000..11c78ec --- /dev/null +++ b/mudclient204-threadless/StreamAudioPlayer.java @@ -0,0 +1,6 @@ +public class StreamAudioPlayer { + public void stopPlayer() {} + + public synchronized void writeStream(byte buff[], int off, int len) { + } +} diff --git a/mudclient204-threadless/Surface.java b/mudclient204-threadless/Surface.java new file mode 100644 index 0000000..8e761fb --- /dev/null +++ b/mudclient204-threadless/Surface.java @@ -0,0 +1,2016 @@ +public class Surface { + + public static int anInt346; + public static int anInt347; + public static int anInt348; + static byte gameFonts[][] = new byte[50][]; + static int characterWidth[]; + public int width2; + public int height2; + public int area; + public int width1; + public int height1; + public int pixels[]; + //private Component unused; + //public Image image; + public int surfacePixels[][]; + public byte spriteColoursUsed[][]; + public int spriteColourList[][]; + public int spriteWidth[]; + public int spriteHeight[]; + public int spriteTranslateX[]; + public int spriteTranslateY[]; + public int spriteWidthFull[]; + public int spriteHeightFull[]; + public boolean spriteTranslate[]; + public boolean interlace; + public boolean loggedIn; + //ColorModel colorModel; + //ImageConsumer imageconsumer; + int landscapeColours[]; + int anIntArray340[]; + int anIntArray341[]; + int anIntArray342[]; + int anIntArray343[]; + int anIntArray344[]; + int anIntArray345[]; + private int boundsTopY; + private int boundsBottomY; + private int boundsTopX; + private int boundsBottomX; + + static { + String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"\243$%^&*()-_=+[{]};:'@#~,<.>/?\\| "; + characterWidth = new int[256]; + for (int i = 0; i < 256; i++) { + int j = s.indexOf(i); + if (j == -1) + j = 74; + characterWidth[i] = j * 9; + } + + } + + public Surface(int width, int height, int limit, mudclient component) { + interlace = false; + loggedIn = false; + //unused = component; + boundsBottomY = height; + boundsBottomX = width; + width1 = width2 = width; + height1 = height2 = height; + area = width * height; + pixels = new int[width * height]; + surfacePixels = new int[limit][]; + spriteTranslate = new boolean[limit]; + spriteColoursUsed = new byte[limit][]; + spriteColourList = new int[limit][]; + spriteWidth = new int[limit]; + spriteHeight = new int[limit]; + spriteWidthFull = new int[limit]; + spriteHeightFull = new int[limit]; + spriteTranslateX = new int[limit]; + spriteTranslateY = new int[limit]; + + /* + if (width > 1 && height > 1 && component != null) { + colorModel = new DirectColorModel(32, 0xff0000, 65280, 255); + int l = width2 * height2; + for (int i1 = 0; i1 < l; i1++) + pixels[i1] = 0; + + image = component.createImage(this); + setcomplete(); + component.prepareImage(image, component); + setcomplete(); + component.prepareImage(image, component); + setcomplete(); + component.prepareImage(image, component); + }*/ + } + + public static int rgb2long(int red, int green, int blue) { + return (red << 16) + (green << 8) + blue; + } + + public static void createFont(byte bytes[], int id) { + gameFonts[id] = bytes; + } + + /*public synchronized void addConsumer(ImageConsumer imageconsumer) { + this.imageconsumer = imageconsumer; + imageconsumer.setDimensions(width2, height2); + imageconsumer.setProperties(null); + imageconsumer.setColorModel(colorModel); + imageconsumer.setHints(14); + } + + public synchronized boolean isConsumer(ImageConsumer imageconsumer) { + return this.imageconsumer == imageconsumer; + } + + public synchronized void removeConsumer(ImageConsumer imageconsumer) { + if (this.imageconsumer == imageconsumer) + this.imageconsumer = null; + } + + public void startProduction(ImageConsumer imageconsumer) { + addConsumer(imageconsumer); + } + + public void requestTopDownLeftRightResend(ImageConsumer imageconsumer) { + System.out.println("TDLR"); + }*/ + + public synchronized void setcomplete() { + /*if (imageconsumer == null) { + return; + } else { + imageconsumer.setPixels(0, 0, width2, height2, colorModel, pixels, 0, width2); + imageconsumer.imageComplete(2); + return; + }*/ + } + + public void setBounds(int x1, int y1, int x2, int y2) { + if (x1 < 0) + x1 = 0; + if (y1 < 0) + y1 = 0; + if (x2 > width2) + x2 = width2; + if (y2 > height2) + y2 = height2; + boundsTopX = x1; + boundsTopY = y1; + boundsBottomX = x2; + boundsBottomY = y2; + } + + public void resetBounds() { + boundsTopX = 0; + boundsTopY = 0; + boundsBottomX = width2; + boundsBottomY = height2; + } + + public void draw(/*Graphics g,*/int x, int y) { + setcomplete(); + System.out.println("draw"); + //g.drawImage(image, x, y, this); + } + + public void blackScreen() { + int area = width2 * height2; + if (!interlace) { + for (int j = 0; j < area; j++) + pixels[j] = 0; + + return; + } + int k = 0; + for (int l = -height2; l < 0; l += 2) { + for (int i1 = -width2; i1 < 0; i1++) + pixels[k++] = 0; + + k += width2; + } + + } + + public void drawCircle(int x, int y, int radius, int colour, int alpha) { + int bgAlpha = 256 - alpha; + int red = (colour >> 16 & 0xff) * alpha; + int green = (colour >> 8 & 0xff) * alpha; + int blue = (colour & 0xff) * alpha; + int top = y - radius; + if (top < 0) + top = 0; + int bottom = y + radius; + if (bottom >= height2) + bottom = height2 - 1; + byte vertInc = 1; + if (interlace) { + vertInc = 2; + if ((top & 1) != 0) + top++; + } + for (int yy = top; yy <= bottom; yy += vertInc) { + int l3 = yy - y; + int i4 = (int) Math.sqrt(radius * radius - l3 * l3); + int j4 = x - i4; + if (j4 < 0) + j4 = 0; + int k4 = x + i4; + if (k4 >= width2) + k4 = width2 - 1; + int pixelIdx = j4 + yy * width2; + for (int i5 = j4; i5 <= k4; i5++) { + int bgRed = (pixels[pixelIdx] >> 16 & 0xff) * bgAlpha; + int bgGreen = (pixels[pixelIdx] >> 8 & 0xff) * bgAlpha; + int bgBlue = (pixels[pixelIdx] & 0xff) * bgAlpha; + int newColour = ((red + bgRed >> 8) << 16) + ((green + bgGreen >> 8) << 8) + (blue + bgBlue >> 8); + pixels[pixelIdx++] = newColour; + } + + } + + } + + public void drawBoxAlpha(int x, int y, int width, int height, int colour, int alpha) { + if (x < boundsTopX) { + width -= boundsTopX - x; + x = boundsTopX; + } + if (y < boundsTopY) { + height -= boundsTopY - y; + y = boundsTopY; + } + if (x + width > boundsBottomX) + width = boundsBottomX - x; + if (y + height > boundsBottomY) + height = boundsBottomY - y; + int bgAlpha = 256 - alpha; + int red = (colour >> 16 & 0xff) * alpha; + int green = (colour >> 8 & 0xff) * alpha; + int blue = (colour & 0xff) * alpha; + int j3 = width2 - width;// wat + byte vertInc = 1; + if (interlace) { + vertInc = 2; + j3 += width2; + if ((y & 1) != 0) { + y++; + height--; + } + } + int pixelIdx = x + y * width2; + for (int l3 = 0; l3 < height; l3 += vertInc) { + for (int i4 = -width; i4 < 0; i4++) { + int bgRed = (pixels[pixelIdx] >> 16 & 0xff) * bgAlpha; + int bgGreen = (pixels[pixelIdx] >> 8 & 0xff) * bgAlpha; + int bgBlue = (pixels[pixelIdx] & 0xff) * bgAlpha; + int newColour = ((red + bgRed >> 8) << 16) + ((green + bgGreen >> 8) << 8) + (blue + bgBlue >> 8); + pixels[pixelIdx++] = newColour; + } + + pixelIdx += j3; + } + + } + + public void drawGradient(int x, int y, int width, int height, int colourTop, int colourBottom) { + if (x < boundsTopX) { + width -= boundsTopX - x; + x = boundsTopX; + } + if (x + width > boundsBottomX) + width = boundsBottomX - x; + int btmRed = colourBottom >> 16 & 0xff; + int btmGreen = colourBottom >> 8 & 0xff; + int btmBlue = colourBottom & 0xff; + int topRed = colourTop >> 16 & 0xff; + int topGreen = colourTop >> 8 & 0xff; + int topBlue = colourTop & 0xff; + int i3 = width2 - width;// wat + byte vertInc = 1; + if (interlace) { + vertInc = 2; + i3 += width2; + if ((y & 1) != 0) { + y++; + height--; + } + } + int pixelIdx = x + y * width2; + for (int k3 = 0; k3 < height; k3 += vertInc) + if (k3 + y >= boundsTopY && k3 + y < boundsBottomY) { + int newColour = ((btmRed * k3 + topRed * (height - k3)) / height << 16) + ((btmGreen * k3 + topGreen * (height - k3)) / height << 8) + (btmBlue * k3 + topBlue * (height - k3)) / height; + for (int i4 = -width; i4 < 0; i4++) + pixels[pixelIdx++] = newColour; + + pixelIdx += i3; + } else { + pixelIdx += width2; + } + + } + + public void drawBox(int x, int y, int w, int h, int colour) { + if (x < boundsTopX) { + w -= boundsTopX - x; + x = boundsTopX; + } + if (y < boundsTopY) { + h -= boundsTopY - y; + y = boundsTopY; + } + if (x + w > boundsBottomX) + w = boundsBottomX - x; + if (y + h > boundsBottomY) + h = boundsBottomY - y; + int j1 = width2 - w;// wat + byte vertInc = 1; + if (interlace) { + vertInc = 2; + j1 += width2; + if ((y & 1) != 0) { + y++; + h--; + } + } + int pixelIdx = x + y * width2; + for (int l1 = -h; l1 < 0; l1 += vertInc) { + for (int i2 = -w; i2 < 0; i2++) + pixels[pixelIdx++] = colour; + + pixelIdx += j1; + } + + } + + public void drawBoxEdge(int x, int y, int width, int height, int colour) { + drawLineHoriz(x, y, width, colour); + drawLineHoriz(x, (y + height) - 1, width, colour); + drawLineVert(x, y, height, colour); + drawLineVert((x + width) - 1, y, height, colour); + } + + public void drawLineHoriz(int x, int y, int width, int colour) { + if (y < boundsTopY || y >= boundsBottomY) + return; + if (x < boundsTopX) { + width -= boundsTopX - x; + x = boundsTopX; + } + if (x + width > boundsBottomX) + width = boundsBottomX - x; + int i1 = x + y * width2; + for (int j1 = 0; j1 < width; j1++) + pixels[i1 + j1] = colour; + + } + + public void drawLineVert(int x, int y, int height, int colour) { + if (x < boundsTopX || x >= boundsBottomX) + return; + if (y < boundsTopY) { + height -= boundsTopY - y; + y = boundsTopY; + } + if (y + height > boundsBottomX) + height = boundsBottomY - y; + int i1 = x + y * width2; + for (int j1 = 0; j1 < height; j1++) + pixels[i1 + j1 * width2] = colour; + + } + + public void setPixel(int x, int y, int colour) { + if (x < boundsTopX || y < boundsTopY || x >= boundsBottomX || y >= boundsBottomY) { + return; + } else { + pixels[x + y * width2] = colour; + return; + } + } + + public void fade2black() { + int k = width2 * height2; + for (int j = 0; j < k; j++) { + int i = pixels[j] & 0xffffff; + pixels[j] = (i >>> 1 & 0x7f7f7f) + (i >>> 2 & 0x3f3f3f) + (i >>> 3 & 0x1f1f1f) + (i >>> 4 & 0xf0f0f); + } + + } + + public void drawLineAlpha(int i, int j, int x, int y, int width, int height) { + for (int xx = x; xx < x + width; xx++) { + for (int yy = y; yy < y + height; yy++) { + int i2 = 0; + int j2 = 0; + int k2 = 0; + int l2 = 0; + for (int i3 = xx - i; i3 <= xx + i; i3++) + if (i3 >= 0 && i3 < width2) { + for (int j3 = yy - j; j3 <= yy + j; j3++) + if (j3 >= 0 && j3 < height2) { + int k3 = pixels[i3 + width2 * j3]; + i2 += k3 >> 16 & 0xff; + j2 += k3 >> 8 & 0xff; + k2 += k3 & 0xff; + l2++; + } + + } + + pixels[xx + width2 * yy] = (i2 / l2 << 16) + (j2 / l2 << 8) + k2 / l2; + } + + } + + } + + public void clear() { + for (int i = 0; i < surfacePixels.length; i++) { + surfacePixels[i] = null; + spriteWidth[i] = 0; + spriteHeight[i] = 0; + spriteColoursUsed[i] = null; + spriteColourList[i] = null; + } + + } + + public void parseSprite(int spriteId, byte spriteData[], byte indexData[], int frameCount) { + int indexOff = Utility.getUnsignedShort(spriteData, 0); + int fullWidth = Utility.getUnsignedShort(indexData, indexOff); + indexOff += 2; + int fullHeight = Utility.getUnsignedShort(indexData, indexOff); + indexOff += 2; + int colourCount = indexData[indexOff++] & 0xff; + int colours[] = new int[colourCount]; + colours[0] = 0xff00ff; + for (int i = 0; i < colourCount - 1; i++) { + colours[i + 1] = ((indexData[indexOff] & 0xff) << 16) + ((indexData[indexOff + 1] & 0xff) << 8) + (indexData[indexOff + 2] & 0xff); + indexOff += 3; + } + + int spriteOff = 2; + for (int id = spriteId; id < spriteId + frameCount; id++) { + spriteTranslateX[id] = indexData[indexOff++] & 0xff; + spriteTranslateY[id] = indexData[indexOff++] & 0xff; + spriteWidth[id] = Utility.getUnsignedShort(indexData, indexOff); + indexOff += 2; + spriteHeight[id] = Utility.getUnsignedShort(indexData, indexOff); + indexOff += 2; + int unknown = indexData[indexOff++] & 0xff; + int size = spriteWidth[id] * spriteHeight[id]; + spriteColoursUsed[id] = new byte[size]; + spriteColourList[id] = colours; + spriteWidthFull[id] = fullWidth; + spriteHeightFull[id] = fullHeight; + surfacePixels[id] = null; + spriteTranslate[id] = false; + if (spriteTranslateX[id] != 0 || spriteTranslateY[id] != 0) + spriteTranslate[id] = true; + if (unknown == 0) { + for (int pixel = 0; pixel < size; pixel++) { + spriteColoursUsed[id][pixel] = spriteData[spriteOff++]; + if (spriteColoursUsed[id][pixel] == 0) + spriteTranslate[id] = true; + } + + } else if (unknown == 1) { + for (int x = 0; x < spriteWidth[id]; x++) { + for (int y = 0; y < spriteHeight[id]; y++) { + spriteColoursUsed[id][x + y * spriteWidth[id]] = spriteData[spriteOff++]; + if (spriteColoursUsed[id][x + y * spriteWidth[id]] == 0) + spriteTranslate[id] = true; + } + + } + + } + } + + } + + public void readSleepWord(int spriteId, byte spriteData[]) { + int pixels[] = surfacePixels[spriteId] = new int[10200]; + spriteWidth[spriteId] = 255; + spriteHeight[spriteId] = 40; + spriteTranslateX[spriteId] = 0; + spriteTranslateY[spriteId] = 0; + spriteWidthFull[spriteId] = 255; + spriteHeightFull[spriteId] = 40; + spriteTranslate[spriteId] = false; + int j = 0; + int k = 1; + int l; + for (l = 0; l < 255; ) { + int i1 = spriteData[k++] & 0xff; + for (int k1 = 0; k1 < i1; k1++) + pixels[l++] = j; + + j = 0xffffff - j; + } + + for (int y = 1; y < 40; y++) { + for (int x = 0; x < 255; ) { + int i2 = spriteData[k++] & 0xff; + for (int j2 = 0; j2 < i2; j2++) { + pixels[l] = pixels[l - 255]; + l++; + x++; + } + + if (x < 255) { + pixels[l] = 0xffffff - pixels[l - 255]; + l++; + x++; + } + } + + } + + } + + public void drawWorld(int spriteId) { + int spriteSize = spriteWidth[spriteId] * spriteHeight[spriteId]; + int spritePixels[] = this.surfacePixels[spriteId]; + int ai1[] = new int[32768]; + for (int k = 0; k < spriteSize; k++) { + int l = spritePixels[k]; + ai1[((l & 0xf80000) >> 9) + ((l & 0xf800) >> 6) + ((l & 0xf8) >> 3)]++; + } + + int ai2[] = new int[256]; + ai2[0] = 0xff00ff; + int ai3[] = new int[256]; + for (int i1 = 0; i1 < 32768; i1++) { + int j1 = ai1[i1]; + if (j1 > ai3[255]) { + for (int k1 = 1; k1 < 256; k1++) { + if (j1 <= ai3[k1]) + continue; + for (int i2 = 255; i2 > k1; i2--) { + ai2[i2] = ai2[i2 - 1]; + ai3[i2] = ai3[i2 - 1]; + } + + ai2[k1] = ((i1 & 0x7c00) << 9) + ((i1 & 0x3e0) << 6) + ((i1 & 0x1f) << 3) + 0x40404; + ai3[k1] = j1; + break; + } + + } + ai1[i1] = -1; + } + + byte abyte0[] = new byte[spriteSize]; + for (int l1 = 0; l1 < spriteSize; l1++) { + int j2 = spritePixels[l1]; + int k2 = ((j2 & 0xf80000) >> 9) + ((j2 & 0xf800) >> 6) + ((j2 & 0xf8) >> 3); + int l2 = ai1[k2]; + if (l2 == -1) { + int i3 = 0x3b9ac9ff; + int j3 = j2 >> 16 & 0xff; + int k3 = j2 >> 8 & 0xff; + int l3 = j2 & 0xff; + for (int i4 = 0; i4 < 256; i4++) { + int j4 = ai2[i4]; + int k4 = j4 >> 16 & 0xff; + int l4 = j4 >> 8 & 0xff; + int i5 = j4 & 0xff; + int j5 = (j3 - k4) * (j3 - k4) + (k3 - l4) * (k3 - l4) + (l3 - i5) * (l3 - i5); + if (j5 < i3) { + i3 = j5; + l2 = i4; + } + } + + ai1[k2] = l2; + } + abyte0[l1] = (byte) l2; + } + + spriteColoursUsed[spriteId] = abyte0; + spriteColourList[spriteId] = ai2; + this.surfacePixels[spriteId] = null; + } + + public void loadSprite(int spriteId) { + if (spriteColoursUsed[spriteId] == null) + return; + int size = spriteWidth[spriteId] * spriteHeight[spriteId]; + byte idx[] = spriteColoursUsed[spriteId]; + int cols[] = spriteColourList[spriteId]; + int pixels[] = new int[size]; + for (int pixel = 0; pixel < size; pixel++) { + int colour = cols[idx[pixel] & 0xff]; + if (colour == 0) + colour = 1; + else if (colour == 0xff00ff) + colour = 0; + pixels[pixel] = colour; + } + + surfacePixels[spriteId] = pixels; + spriteColoursUsed[spriteId] = null; + spriteColourList[spriteId] = null; + } + + public void drawSpriteMinimap(int sprite, int x, int y, int width, int height) {// used from World + spriteWidth[sprite] = width; + spriteHeight[sprite] = height; + spriteTranslate[sprite] = false; + spriteTranslateX[sprite] = 0; + spriteTranslateY[sprite] = 0; + spriteWidthFull[sprite] = width; + spriteHeightFull[sprite] = height; + int area = width * height; + int pixel = 0; + surfacePixels[sprite] = new int[area]; + for (int xx = x; xx < x + width; xx++) { + for (int yy = y; yy < y + height; yy++) { + surfacePixels[sprite][pixel++] = pixels[xx + yy * width2]; + } + } + } + + public void drawSprite(int sprite, int x, int y, int width, int height) {// used from mudclient + spriteWidth[sprite] = width; + spriteHeight[sprite] = height; + spriteTranslate[sprite] = false; + spriteTranslateX[sprite] = 0; + spriteTranslateY[sprite] = 0; + spriteWidthFull[sprite] = width; + spriteHeightFull[sprite] = height; + int area = width * height; + int pixel = 0; + surfacePixels[sprite] = new int[area]; + for (int yy = y; yy < y + height; yy++) { + for (int xx = x; xx < x + width; xx++) + surfacePixels[sprite][pixel++] = pixels[xx + yy * width2]; + + } + + } + + public void drawSprite(int x, int y, int id) { + if (spriteTranslate[id]) { + x += spriteTranslateX[id]; + y += spriteTranslateY[id]; + } + int rY = x + y * width2; + int rX = 0; + int height = spriteHeight[id]; + int width = spriteWidth[id]; + int w2 = width2 - width; + int h2 = 0; + if (y < boundsTopY) { + int j2 = boundsTopY - y; + height -= j2; + y = boundsTopY; + rX += j2 * width; + rY += j2 * width2; + } + if (y + height >= boundsBottomY) + height -= ((y + height) - boundsBottomY) + 1; + if (x < boundsTopX) { + int k2 = boundsTopX - x; + width -= k2; + x = boundsTopX; + rX += k2; + rY += k2; + h2 += k2; + w2 += k2; + } + if (x + width >= boundsBottomX) { + int l2 = ((x + width) - boundsBottomX) + 1; + width -= l2; + h2 += l2; + w2 += l2; + } + if (width <= 0 || height <= 0) + return; + byte inc = 1; + if (interlace) { + inc = 2; + w2 += width2; + h2 += spriteWidth[id]; + if ((y & 1) != 0) { + rY += width2; + height--; + } + } + if (surfacePixels[id] == null) { + drawSprite(pixels, spriteColoursUsed[id], spriteColourList[id], rX, rY, width, height, w2, h2, inc); + return; + } else { + drawSprite(pixels, surfacePixels[id], 0, rX, rY, width, height, w2, h2, inc); + return; + } + } + + public void spriteClipping(int x, int y, int width, int height, int spriteId) { + try { + int spriteWidth = this.spriteWidth[spriteId]; + int spriteHeight = this.spriteHeight[spriteId]; + int l1 = 0; + int i2 = 0; + int j2 = (spriteWidth << 16) / width; + int k2 = (spriteHeight << 16) / height; + if (spriteTranslate[spriteId]) { + int l2 = spriteWidthFull[spriteId]; + int j3 = spriteHeightFull[spriteId]; + j2 = (l2 << 16) / width; + k2 = (j3 << 16) / height; + x += ((spriteTranslateX[spriteId] * width + l2) - 1) / l2; + y += ((spriteTranslateY[spriteId] * height + j3) - 1) / j3; + if ((spriteTranslateX[spriteId] * width) % l2 != 0) + l1 = (l2 - (spriteTranslateX[spriteId] * width) % l2 << 16) / width; + if ((spriteTranslateY[spriteId] * height) % j3 != 0) + i2 = (j3 - (spriteTranslateY[spriteId] * height) % j3 << 16) / height; + width = (width * (this.spriteWidth[spriteId] - (l1 >> 16))) / l2; + height = (height * (this.spriteHeight[spriteId] - (i2 >> 16))) / j3; + } + int i3 = x + y * width2; + int k3 = width2 - width; + if (y < boundsTopY) { + int l3 = boundsTopY - y; + height -= l3; + y = 0; + i3 += l3 * width2; + i2 += k2 * l3; + } + if (y + height >= boundsBottomY) + height -= ((y + height) - boundsBottomY) + 1; + if (x < boundsTopX) { + int i4 = boundsTopX - x; + width -= i4; + x = 0; + i3 += i4; + l1 += j2 * i4; + k3 += i4; + } + if (x + width >= boundsBottomX) { + int j4 = ((x + width) - boundsBottomX) + 1; + width -= j4; + k3 += j4; + } + byte yInc = 1; + if (interlace) { + yInc = 2; + k3 += width2; + k2 += k2; + if ((y & 1) != 0) { + i3 += width2; + height--; + } + } + plotScale(pixels, surfacePixels[spriteId], 0, l1, i2, i3, k3, width, height, j2, k2, spriteWidth, yInc); + return; + } catch (Exception Ex) { + System.out.println("error in sprite clipping routine"); + } + } + + public void drawSpriteAlpha(int x, int y, int spriteId, int alpha) { + if (spriteTranslate[spriteId]) { + x += spriteTranslateX[spriteId]; + y += spriteTranslateY[spriteId]; + } + int size = x + y * width2; + int j1 = 0; + int height = spriteHeight[spriteId]; + int width = spriteWidth[spriteId]; + int extraXSpace = width2 - width; + int j2 = 0; + if (y < boundsTopY) { + int k2 = boundsTopY - y; + height -= k2; + y = boundsTopY; + j1 += k2 * width; + size += k2 * width2; + } + if (y + height >= boundsBottomY) + height -= ((y + height) - boundsBottomY) + 1; + if (x < boundsTopX) { + int l2 = boundsTopX - x; + width -= l2; + x = boundsTopX; + j1 += l2; + size += l2; + j2 += l2; + extraXSpace += l2; + } + if (x + width >= boundsBottomX) { + int i3 = ((x + width) - boundsBottomX) + 1; + width -= i3; + j2 += i3; + extraXSpace += i3; + } + if (width <= 0 || height <= 0) + return; + byte yInc = 1; + if (this.interlace) { + yInc = 2; + extraXSpace += width2; + j2 += spriteWidth[spriteId]; + if ((y & 1) != 0) { + size += width2; + height--; + } + } + if (surfacePixels[spriteId] == null) { + drawSpriteAlpha(pixels, spriteColoursUsed[spriteId], spriteColourList[spriteId], j1, size, width, height, extraXSpace, j2, yInc, alpha); + return; + } else { + drawSpriteAlpha(pixels, surfacePixels[spriteId], 0, j1, size, width, height, extraXSpace, j2, yInc, alpha); + return; + } + } + + public void drawActionBubble(int x, int y, int scaleX, int scaleY, int sprite, int alpha) { + try { + int spriteWidth = this.spriteWidth[sprite]; + int spriteHeight = this.spriteHeight[sprite]; + int i2 = 0; + int j2 = 0; + int k2 = (spriteWidth << 16) / scaleX; + int l2 = (spriteHeight << 16) / scaleY; + if (spriteTranslate[sprite]) { + int i3 = spriteWidthFull[sprite]; + int k3 = spriteHeightFull[sprite]; + k2 = (i3 << 16) / scaleX; + l2 = (k3 << 16) / scaleY; + x += ((spriteTranslateX[sprite] * scaleX + i3) - 1) / i3; + y += ((spriteTranslateY[sprite] * scaleY + k3) - 1) / k3; + if ((spriteTranslateX[sprite] * scaleX) % i3 != 0) + i2 = (i3 - (spriteTranslateX[sprite] * scaleX) % i3 << 16) / scaleX; + if ((spriteTranslateY[sprite] * scaleY) % k3 != 0) + j2 = (k3 - (spriteTranslateY[sprite] * scaleY) % k3 << 16) / scaleY; + scaleX = (scaleX * (this.spriteWidth[sprite] - (i2 >> 16))) / i3; + scaleY = (scaleY * (this.spriteHeight[sprite] - (j2 >> 16))) / k3; + } + int j3 = x + y * width2; + int l3 = width2 - scaleX; + if (y < boundsTopY) { + int i4 = boundsTopY - y; + scaleY -= i4; + y = 0; + j3 += i4 * width2; + j2 += l2 * i4; + } + if (y + scaleY >= boundsBottomY) + scaleY -= ((y + scaleY) - boundsBottomY) + 1; + if (x < boundsTopX) { + int j4 = boundsTopX - x; + scaleX -= j4; + x = 0; + j3 += j4; + i2 += k2 * j4; + l3 += j4; + } + if (x + scaleX >= boundsBottomX) { + int k4 = ((x + scaleX) - boundsBottomX) + 1; + scaleX -= k4; + l3 += k4; + } + byte yInc = 1; + if (interlace) { + yInc = 2; + l3 += width2; + l2 += l2; + if ((y & 1) != 0) { + j3 += width2; + scaleY--; + } + } + transparentScale(pixels, surfacePixels[sprite], 0, i2, j2, j3, l3, scaleX, scaleY, k2, l2, spriteWidth, yInc, alpha); + return; + } catch (Exception ex) { + System.out.println("error in sprite clipping routine"); + } + } + + public void spriteClipping(int x, int y, int width, int height, int spriteId, int colour) { + try { + int k1 = spriteWidth[spriteId]; + int l1 = spriteHeight[spriteId]; + int i2 = 0; + int j2 = 0; + int k2 = (k1 << 16) / width; + int l2 = (l1 << 16) / height; + if (spriteTranslate[spriteId]) { + int i3 = spriteWidthFull[spriteId]; + int k3 = spriteHeightFull[spriteId]; + k2 = (i3 << 16) / width; + l2 = (k3 << 16) / height; + x += ((spriteTranslateX[spriteId] * width + i3) - 1) / i3; + y += ((spriteTranslateY[spriteId] * height + k3) - 1) / k3; + if ((spriteTranslateX[spriteId] * width) % i3 != 0) + i2 = (i3 - (spriteTranslateX[spriteId] * width) % i3 << 16) / width; + if ((spriteTranslateY[spriteId] * height) % k3 != 0) + j2 = (k3 - (spriteTranslateY[spriteId] * height) % k3 << 16) / height; + width = (width * (spriteWidth[spriteId] - (i2 >> 16))) / i3; + height = (height * (spriteHeight[spriteId] - (j2 >> 16))) / k3; + } + int j3 = x + y * width2; + int l3 = width2 - width; + if (y < boundsTopY) { + int i4 = boundsTopY - y; + height -= i4; + y = 0; + j3 += i4 * width2; + j2 += l2 * i4; + } + if (y + height >= boundsBottomY) + height -= ((y + height) - boundsBottomY) + 1; + if (x < boundsTopX) { + int j4 = boundsTopX - x; + width -= j4; + x = 0; + j3 += j4; + i2 += k2 * j4; + l3 += j4; + } + if (x + width >= boundsBottomX) { + int k4 = ((x + width) - boundsBottomX) + 1; + width -= k4; + l3 += k4; + } + byte yInc = 1; + if (interlace) { + yInc = 2; + l3 += width2; + l2 += l2; + if ((y & 1) != 0) { + j3 += width2; + height--; + } + } + plotScale(pixels, surfacePixels[spriteId], 0, i2, j2, j3, l3, width, height, k2, l2, k1, yInc, colour); + return; + } catch (Exception Ex) { + System.out.println("error in sprite clipping routine"); + } + } + + private void drawSprite(int dest[], int src[], int i, int srcPos, int destPos, int width, int height, + int j1, int k1, int yInc) { + int i2 = -(width >> 2); + width = -(width & 3); + for (int j2 = -height; j2 < 0; j2 += yInc) { + for (int k2 = i2; k2 < 0; k2++) { + i = src[srcPos++]; + if (i != 0) + dest[destPos++] = i; + else + destPos++; + i = src[srcPos++]; + if (i != 0) + dest[destPos++] = i; + else + destPos++; + i = src[srcPos++]; + if (i != 0) + dest[destPos++] = i; + else + destPos++; + i = src[srcPos++]; + if (i != 0) + dest[destPos++] = i; + else + destPos++; + } + + for (int l2 = width; l2 < 0; l2++) { + i = src[srcPos++]; + if (i != 0) + dest[destPos++] = i; + else + destPos++; + } + + destPos += j1; + srcPos += k1; + } + + } + + private void drawSprite(int target[], byte colourIdx[], int colours[], int srcPos, int destPos, int width, int height, + int w2, int h2, int rowInc) { + int l1 = -(width >> 2); + width = -(width & 3); + for (int i2 = -height; i2 < 0; i2 += rowInc) { + for (int j2 = l1; j2 < 0; j2++) { + byte byte0 = colourIdx[srcPos++]; + if (byte0 != 0) + target[destPos++] = colours[byte0 & 0xff]; + else + destPos++; + byte0 = colourIdx[srcPos++]; + if (byte0 != 0) + target[destPos++] = colours[byte0 & 0xff]; + else + destPos++; + byte0 = colourIdx[srcPos++]; + if (byte0 != 0) + target[destPos++] = colours[byte0 & 0xff]; + else + destPos++; + byte0 = colourIdx[srcPos++]; + if (byte0 != 0) + target[destPos++] = colours[byte0 & 0xff]; + else + destPos++; + } + + for (int k2 = width; k2 < 0; k2++) { + byte byte1 = colourIdx[srcPos++]; + if (byte1 != 0) + target[destPos++] = colours[byte1 & 0xff]; + else + destPos++; + } + + destPos += w2; + srcPos += h2; + } + + } + + private void plotScale(int dest[], int src[], int i, int j, int k, int destPos, int i1, + int j1, int k1, int l1, int i2, int j2, int k2) { + try { + int l2 = j; + for (int i3 = -k1; i3 < 0; i3 += k2) { + int j3 = (k >> 16) * j2; + for (int k3 = -j1; k3 < 0; k3++) { + i = src[(j >> 16) + j3]; + if (i != 0) + dest[destPos++] = i; + else + destPos++; + j += l1; + } + + k += i2; + j = l2; + destPos += i1; + } + + return; + } catch (Exception Ex) { + System.out.println("error in plotScale"); + } + } + + private void drawSpriteAlpha(int dest[], int src[], int i, int srcPos, int size, int width, int height, + int extraXSpace, int k1, int yInc, int alpha) { + int j2 = 256 - alpha; + for (int k2 = -height; k2 < 0; k2 += yInc) { + for (int l2 = -width; l2 < 0; l2++) { + i = src[srcPos++]; + if (i != 0) { + int i3 = dest[size]; + dest[size++] = ((i & 0xff00ff) * alpha + (i3 & 0xff00ff) * j2 & 0xff00ff00) + ((i & 0xff00) * alpha + (i3 & 0xff00) * j2 & 0xff0000) >> 8; + } else { + size++; + } + } + + size += extraXSpace; + srcPos += k1; + } + + } + + private void drawSpriteAlpha(int dest[], byte coloursUsed[], int colourList[], int listPos, int size, int width, int height, + int extraXSpace, int j1, int yInc, int alpha) { + int i2 = 256 - alpha; + for (int j2 = -height; j2 < 0; j2 += yInc) { + for (int k2 = -width; k2 < 0; k2++) { + int l2 = coloursUsed[listPos++]; + if (l2 != 0) { + l2 = colourList[l2 & 0xff]; + int i3 = dest[size]; + dest[size++] = ((l2 & 0xff00ff) * alpha + (i3 & 0xff00ff) * i2 & 0xff00ff00) + ((l2 & 0xff00) * alpha + (i3 & 0xff00) * i2 & 0xff0000) >> 8; + } else { + size++; + } + } + + size += extraXSpace; + listPos += j1; + } + + } + + private void transparentScale(int dest[], int src[], int i, int j, int k, int destPos, int i1, + int j1, int k1, int l1, int i2, int j2, int yInc, int alpha) { + int i3 = 256 - alpha; + try { + int j3 = j; + for (int k3 = -k1; k3 < 0; k3 += yInc) { + int l3 = (k >> 16) * j2; + for (int i4 = -j1; i4 < 0; i4++) { + i = src[(j >> 16) + l3]; + if (i != 0) { + int j4 = dest[destPos]; + dest[destPos++] = ((i & 0xff00ff) * alpha + (j4 & 0xff00ff) * i3 & 0xff00ff00) + ((i & 0xff00) * alpha + (j4 & 0xff00) * i3 & 0xff0000) >> 8; + } else { + destPos++; + } + j += l1; + } + + k += i2; + j = j3; + destPos += i1; + } + + return; + } catch (Exception Ex) { + System.out.println("error in tranScale"); + } + } + + private void plotScale(int target[], int pixels[], int i, int j, int k, int l, int i1, + int width, int height, int l1, int i2, int j2, int yInc, int colour) { + int i3 = colour >> 16 & 0xff; + int j3 = colour >> 8 & 0xff; + int k3 = colour & 0xff; + try { + int l3 = j; + for (int i4 = -height; i4 < 0; i4 += yInc) { + int j4 = (k >> 16) * j2; + for (int k4 = -width; k4 < 0; k4++) { + i = pixels[(j >> 16) + j4]; + if (i != 0) { + int l4 = i >> 16 & 0xff; + int i5 = i >> 8 & 0xff; + int j5 = i & 0xff; + if (l4 == i5 && i5 == j5) + target[l++] = ((l4 * i3 >> 8) << 16) + ((i5 * j3 >> 8) << 8) + (j5 * k3 >> 8); + else + target[l++] = i; + } else { + l++; + } + j += l1; + } + + k += i2; + j = l3; + l += i1; + } + + return; + } catch (Exception Ex) { + System.out.println("error in plotScale"); + } + } + + public void drawMinimapSprite(int x, int y, int sprite, int rotation, int scale) {// "scale" is not actually scaling when it comes to the landscape + int j1 = width2; + int k1 = height2; + if (landscapeColours == null) { + landscapeColours = new int[512]; + for (int l1 = 0; l1 < 256; l1++) { + landscapeColours[l1] = (int) (Math.sin((double) l1 * 0.02454369D) * 32768D); + landscapeColours[l1 + 256] = (int) (Math.cos((double) l1 * 0.02454369D) * 32768D); + } + + } + int i2 = -spriteWidthFull[sprite] / 2; + int j2 = -spriteHeightFull[sprite] / 2; + if (spriteTranslate[sprite]) { + i2 += spriteTranslateX[sprite]; + j2 += spriteTranslateY[sprite]; + } + int k2 = i2 + spriteWidth[sprite]; + int l2 = j2 + spriteHeight[sprite]; + int i3 = k2; + int j3 = j2; + int k3 = i2; + int l3 = l2; + rotation &= 0xff; + int i4 = landscapeColours[rotation] * scale; + int j4 = landscapeColours[rotation + 256] * scale; + int k4 = x + (j2 * i4 + i2 * j4 >> 22); + int l4 = y + (j2 * j4 - i2 * i4 >> 22); + int i5 = x + (j3 * i4 + i3 * j4 >> 22); + int j5 = y + (j3 * j4 - i3 * i4 >> 22); + int k5 = x + (l2 * i4 + k2 * j4 >> 22); + int l5 = y + (l2 * j4 - k2 * i4 >> 22); + int i6 = x + (l3 * i4 + k3 * j4 >> 22); + int j6 = y + (l3 * j4 - k3 * i4 >> 22); + if (scale == 192 && (rotation & 0x3f) == (anInt348 & 0x3f)) + anInt346++; + else if (scale == 128) + anInt348 = rotation; + else + anInt347++; + int k6 = l4; + int l6 = l4; + if (j5 < k6) + k6 = j5; + else if (j5 > l6) + l6 = j5; + if (l5 < k6) + k6 = l5; + else if (l5 > l6) + l6 = l5; + if (j6 < k6) + k6 = j6; + else if (j6 > l6) + l6 = j6; + if (k6 < boundsTopY) + k6 = boundsTopY; + if (l6 > boundsBottomY) + l6 = boundsBottomY; + if (anIntArray340 == null || anIntArray340.length != k1 + 1) { + anIntArray340 = new int[k1 + 1]; + anIntArray341 = new int[k1 + 1]; + anIntArray342 = new int[k1 + 1]; + anIntArray343 = new int[k1 + 1]; + anIntArray344 = new int[k1 + 1]; + anIntArray345 = new int[k1 + 1]; + } + for (int i7 = k6; i7 <= l6; i7++) { + anIntArray340[i7] = 99999999; + anIntArray341[i7] = 0xfa0a1f01; + } + + int i8 = 0; + int k8 = 0; + int i9 = 0; + int j9 = spriteWidth[sprite]; + int k9 = spriteHeight[sprite]; + i2 = 0; + j2 = 0; + i3 = j9 - 1; + j3 = 0; + k2 = j9 - 1; + l2 = k9 - 1; + k3 = 0; + l3 = k9 - 1; + if (j6 != l4) { + i8 = (i6 - k4 << 8) / (j6 - l4); + i9 = (l3 - j2 << 8) / (j6 - l4); + } + int j7; + int k7; + int l7; + int l8; + if (l4 > j6) { + l7 = i6 << 8; + l8 = l3 << 8; + j7 = j6; + k7 = l4; + } else { + l7 = k4 << 8; + l8 = j2 << 8; + j7 = l4; + k7 = j6; + } + if (j7 < 0) { + l7 -= i8 * j7; + l8 -= i9 * j7; + j7 = 0; + } + if (k7 > k1 - 1) + k7 = k1 - 1; + for (int l9 = j7; l9 <= k7; l9++) { + anIntArray340[l9] = anIntArray341[l9] = l7; + l7 += i8; + anIntArray342[l9] = anIntArray343[l9] = 0; + anIntArray344[l9] = anIntArray345[l9] = l8; + l8 += i9; + } + + if (j5 != l4) { + i8 = (i5 - k4 << 8) / (j5 - l4); + k8 = (i3 - i2 << 8) / (j5 - l4); + } + int j8; + if (l4 > j5) { + l7 = i5 << 8; + j8 = i3 << 8; + j7 = j5; + k7 = l4; + } else { + l7 = k4 << 8; + j8 = i2 << 8; + j7 = l4; + k7 = j5; + } + if (j7 < 0) { + l7 -= i8 * j7; + j8 -= k8 * j7; + j7 = 0; + } + if (k7 > k1 - 1) + k7 = k1 - 1; + for (int i10 = j7; i10 <= k7; i10++) { + if (l7 < anIntArray340[i10]) { + anIntArray340[i10] = l7; + anIntArray342[i10] = j8; + anIntArray344[i10] = 0; + } + if (l7 > anIntArray341[i10]) { + anIntArray341[i10] = l7; + anIntArray343[i10] = j8; + anIntArray345[i10] = 0; + } + l7 += i8; + j8 += k8; + } + + if (l5 != j5) { + i8 = (k5 - i5 << 8) / (l5 - j5); + i9 = (l2 - j3 << 8) / (l5 - j5); + } + if (j5 > l5) { + l7 = k5 << 8; + j8 = k2 << 8; + l8 = l2 << 8; + j7 = l5; + k7 = j5; + } else { + l7 = i5 << 8; + j8 = i3 << 8; + l8 = j3 << 8; + j7 = j5; + k7 = l5; + } + if (j7 < 0) { + l7 -= i8 * j7; + l8 -= i9 * j7; + j7 = 0; + } + if (k7 > k1 - 1) + k7 = k1 - 1; + for (int j10 = j7; j10 <= k7; j10++) { + if (l7 < anIntArray340[j10]) { + anIntArray340[j10] = l7; + anIntArray342[j10] = j8; + anIntArray344[j10] = l8; + } + if (l7 > anIntArray341[j10]) { + anIntArray341[j10] = l7; + anIntArray343[j10] = j8; + anIntArray345[j10] = l8; + } + l7 += i8; + l8 += i9; + } + + if (j6 != l5) { + i8 = (i6 - k5 << 8) / (j6 - l5); + k8 = (k3 - k2 << 8) / (j6 - l5); + } + if (l5 > j6) { + l7 = i6 << 8; + j8 = k3 << 8; + l8 = l3 << 8; + j7 = j6; + k7 = l5; + } else { + l7 = k5 << 8; + j8 = k2 << 8; + l8 = l2 << 8; + j7 = l5; + k7 = j6; + } + if (j7 < 0) { + l7 -= i8 * j7; + j8 -= k8 * j7; + j7 = 0; + } + if (k7 > k1 - 1) + k7 = k1 - 1; + for (int k10 = j7; k10 <= k7; k10++) { + if (l7 < anIntArray340[k10]) { + anIntArray340[k10] = l7; + anIntArray342[k10] = j8; + anIntArray344[k10] = l8; + } + if (l7 > anIntArray341[k10]) { + anIntArray341[k10] = l7; + anIntArray343[k10] = j8; + anIntArray345[k10] = l8; + } + l7 += i8; + j8 += k8; + } + + int l10 = k6 * j1; + int ai[] = surfacePixels[sprite]; + for (int i11 = k6; i11 < l6; i11++) { + int j11 = anIntArray340[i11] >> 8; + int k11 = anIntArray341[i11] >> 8; + if (k11 - j11 <= 0) { + l10 += j1; + } else { + int l11 = anIntArray342[i11] << 9; + int i12 = ((anIntArray343[i11] << 9) - l11) / (k11 - j11); + int j12 = anIntArray344[i11] << 9; + int k12 = ((anIntArray345[i11] << 9) - j12) / (k11 - j11); + if (j11 < boundsTopX) { + l11 += (boundsTopX - j11) * i12; + j12 += (boundsTopX - j11) * k12; + j11 = boundsTopX; + } + if (k11 > boundsBottomX) + k11 = boundsBottomX; + if (!interlace || (i11 & 1) == 0) + if (!spriteTranslate[sprite]) + drawMinimap(pixels, ai, 0, l10 + j11, l11, j12, i12, k12, j11 - k11, j9); + else + drawMinimapTranslate(pixels, ai, 0, l10 + j11, l11, j12, i12, k12, j11 - k11, j9); + l10 += j1; + } + } + + } + + private void drawMinimap(int ai[], int ai1[], int i, int j, int k, int l, int i1, + int j1, int k1, int l1) { + for (i = k1; i < 0; i++) { + pixels[j++] = ai1[(k >> 17) + (l >> 17) * l1]; + k += i1; + l += j1; + } + + } + + private void drawMinimapTranslate(int ai[], int ai1[], int i, int j, int k, int l, int i1, + int j1, int k1, int l1) { + for (int i2 = k1; i2 < 0; i2++) { + i = ai1[(k >> 17) + (l >> 17) * l1]; + if (i != 0) + pixels[j++] = i; + else + j++; + k += i1; + l += j1; + } + + } + + public void spriteClipping(int x, int y, int w, int h, int id, int tx, int ty) { + spriteClipping(x, y, w, h, id); + } + + public void spriteClipping(int x, int y, int w, int h, int sprite, int colour1, int colour2, + int l1, boolean flag) { + try { + if (colour1 == 0) + colour1 = 0xffffff; + if (colour2 == 0) + colour2 = 0xffffff; + int width = spriteWidth[sprite]; + int height = spriteHeight[sprite]; + int k2 = 0; + int l2 = 0; + int i3 = l1 << 16; + int j3 = (width << 16) / w; + int k3 = (height << 16) / h; + int l3 = -(l1 << 16) / h; + if (spriteTranslate[sprite]) { + int fullWidth = spriteWidthFull[sprite]; + int fullHeight = spriteHeightFull[sprite]; + j3 = (fullWidth << 16) / w; + k3 = (fullHeight << 16) / h; + int j5 = spriteTranslateX[sprite]; + int k5 = spriteTranslateY[sprite]; + if (flag) + j5 = fullWidth - spriteWidth[sprite] - j5; + x += ((j5 * w + fullWidth) - 1) / fullWidth; + int l5 = ((k5 * h + fullHeight) - 1) / fullHeight; + y += l5; + i3 += l5 * l3; + if ((j5 * w) % fullWidth != 0) + k2 = (fullWidth - (j5 * w) % fullWidth << 16) / w; + if ((k5 * h) % fullHeight != 0) + l2 = (fullHeight - (k5 * h) % fullHeight << 16) / h; + w = ((((spriteWidth[sprite] << 16) - k2) + j3) - 1) / j3; + h = ((((spriteHeight[sprite] << 16) - l2) + k3) - 1) / k3; + } + int j4 = y * width2; + i3 += x << 16; + if (y < boundsTopY) { + int l4 = boundsTopY - y; + h -= l4; + y = boundsTopY; + j4 += l4 * width2; + l2 += k3 * l4; + i3 += l3 * l4; + } + if (y + h >= boundsBottomY) + h -= ((y + h) - boundsBottomY) + 1; + int i5 = j4 / width2 & 1; + if (!interlace) + i5 = 2; + if (colour2 == 0xffffff) { + if (surfacePixels[sprite] != null) + if (!flag) { + transparentSpritePlot(pixels, surfacePixels[sprite], 0, k2, l2, j4, w, h, j3, k3, width, colour1, i3, l3, i5); + return; + } else { + transparentSpritePlot(pixels, surfacePixels[sprite], 0, (spriteWidth[sprite] << 16) - k2 - 1, l2, j4, w, h, -j3, k3, width, colour1, i3, l3, i5); + return; + } + if (!flag) { + transparentSpritePlot(pixels, spriteColoursUsed[sprite], spriteColourList[sprite], 0, k2, l2, j4, w, h, j3, k3, width, colour1, i3, l3, i5); + return; + } else { + transparentSpritePlot(pixels, spriteColoursUsed[sprite], spriteColourList[sprite], 0, (spriteWidth[sprite] << 16) - k2 - 1, l2, j4, w, h, -j3, k3, width, colour1, i3, l3, i5); + return; + } + } + if (surfacePixels[sprite] != null) + if (!flag) { + transparentSpritePlot(pixels, surfacePixels[sprite], 0, k2, l2, j4, w, h, j3, k3, width, colour1, colour2, i3, l3, i5); + return; + } else { + transparentSpritePlot(pixels, surfacePixels[sprite], 0, (spriteWidth[sprite] << 16) - k2 - 1, l2, j4, w, h, -j3, k3, width, colour1, colour2, i3, l3, i5); + return; + } + if (!flag) { + transparentSpritePlot(pixels, spriteColoursUsed[sprite], spriteColourList[sprite], 0, k2, l2, j4, w, h, j3, k3, width, colour1, colour2, i3, l3, i5); + return; + } else { + transparentSpritePlot(pixels, spriteColoursUsed[sprite], spriteColourList[sprite], 0, (spriteWidth[sprite] << 16) - k2 - 1, l2, j4, w, h, -j3, k3, width, colour1, colour2, i3, l3, i5); + return; + } + } catch (Exception Ex) { + System.out.println("error in sprite clipping routine"); + } + } + + private void transparentSpritePlot(int dest[], int src[], int i, int j, int k, int destPos, int i1, + int j1, int k1, int l1, int i2, int j2, int k2, int l2, + int i3) { + int i4 = j2 >> 16 & 0xff; + int j4 = j2 >> 8 & 0xff; + int k4 = j2 & 0xff; + try { + int l4 = j; + for (int i5 = -j1; i5 < 0; i5++) { + int j5 = (k >> 16) * i2; + int k5 = k2 >> 16; + int l5 = i1; + if (k5 < boundsTopX) { + int i6 = boundsTopX - k5; + l5 -= i6; + k5 = boundsTopX; + j += k1 * i6; + } + if (k5 + l5 >= boundsBottomX) { + int j6 = (k5 + l5) - boundsBottomX; + l5 -= j6; + } + i3 = 1 - i3; + if (i3 != 0) { + for (int k6 = k5; k6 < k5 + l5; k6++) { + i = src[(j >> 16) + j5]; + if (i != 0) { + int j3 = i >> 16 & 0xff; + int k3 = i >> 8 & 0xff; + int l3 = i & 0xff; + if (j3 == k3 && k3 == l3) + dest[k6 + destPos] = ((j3 * i4 >> 8) << 16) + ((k3 * j4 >> 8) << 8) + (l3 * k4 >> 8); + else + dest[k6 + destPos] = i; + } + j += k1; + } + + } + k += l1; + j = l4; + destPos += width2; + k2 += l2; + } + + return; + } catch (Exception Ex) { + System.out.println("error in transparent sprite plot routine"); + } + } + + private void transparentSpritePlot(int dest[], int src[], int i, int j, int k, int destPos, int i1, + int j1, int k1, int l1, int i2, int j2, int k2, int l2, + int i3, int j3) { + int j4 = j2 >> 16 & 0xff; + int k4 = j2 >> 8 & 0xff; + int l4 = j2 & 0xff; + int i5 = k2 >> 16 & 0xff; + int j5 = k2 >> 8 & 0xff; + int k5 = k2 & 0xff; + try { + int l5 = j; + for (int i6 = -j1; i6 < 0; i6++) { + int j6 = (k >> 16) * i2; + int k6 = l2 >> 16; + int l6 = i1; + if (k6 < boundsTopX) { + int i7 = boundsTopX - k6; + l6 -= i7; + k6 = boundsTopX; + j += k1 * i7; + } + if (k6 + l6 >= boundsBottomX) { + int j7 = (k6 + l6) - boundsBottomX; + l6 -= j7; + } + j3 = 1 - j3; + if (j3 != 0) { + for (int k7 = k6; k7 < k6 + l6; k7++) { + i = src[(j >> 16) + j6]; + if (i != 0) { + int k3 = i >> 16 & 0xff; + int l3 = i >> 8 & 0xff; + int i4 = i & 0xff; + if (k3 == l3 && l3 == i4) + dest[k7 + destPos] = ((k3 * j4 >> 8) << 16) + ((l3 * k4 >> 8) << 8) + (i4 * l4 >> 8); + else if (k3 == 255 && l3 == i4) + dest[k7 + destPos] = ((k3 * i5 >> 8) << 16) + ((l3 * j5 >> 8) << 8) + (i4 * k5 >> 8); + else + dest[k7 + destPos] = i; + } + j += k1; + } + + } + k += l1; + j = l5; + destPos += width2; + l2 += i3; + } + + return; + } catch (Exception Ex) { + System.out.println("error in transparent sprite plot routine"); + } + } + + private void transparentSpritePlot(int dest[], byte colourIdx[], int colours[], int i, int j, int k, int l, + int i1, int j1, int k1, int l1, int i2, int j2, int k2, + int l2, int i3) { + int i4 = j2 >> 16 & 0xff; + int j4 = j2 >> 8 & 0xff; + int k4 = j2 & 0xff; + try { + int l4 = j; + for (int i5 = -j1; i5 < 0; i5++) { + int j5 = (k >> 16) * i2; + int k5 = k2 >> 16; + int l5 = i1; + if (k5 < boundsTopX) { + int i6 = boundsTopX - k5; + l5 -= i6; + k5 = boundsTopX; + j += k1 * i6; + } + if (k5 + l5 >= boundsBottomX) { + int j6 = (k5 + l5) - boundsBottomX; + l5 -= j6; + } + i3 = 1 - i3; + if (i3 != 0) { + for (int k6 = k5; k6 < k5 + l5; k6++) { + i = colourIdx[(j >> 16) + j5] & 0xff; + if (i != 0) { + i = colours[i]; + int j3 = i >> 16 & 0xff; + int k3 = i >> 8 & 0xff; + int l3 = i & 0xff; + if (j3 == k3 && k3 == l3) + dest[k6 + l] = ((j3 * i4 >> 8) << 16) + ((k3 * j4 >> 8) << 8) + (l3 * k4 >> 8); + else + dest[k6 + l] = i; + } + j += k1; + } + + } + k += l1; + j = l4; + l += width2; + k2 += l2; + } + + return; + } catch (Exception Ex) { + System.out.println("error in transparent sprite plot routine"); + } + } + + private void transparentSpritePlot(int dest[], byte coloursUsed[], int colourList[], int i, int j, int k, int l, + int i1, int j1, int k1, int l1, int i2, int j2, int k2, + int l2, int i3, int j3) { + int j4 = j2 >> 16 & 0xff; + int k4 = j2 >> 8 & 0xff; + int l4 = j2 & 0xff; + int i5 = k2 >> 16 & 0xff; + int j5 = k2 >> 8 & 0xff; + int k5 = k2 & 0xff; + try { + int l5 = j; + for (int i6 = -j1; i6 < 0; i6++) { + int j6 = (k >> 16) * i2; + int k6 = l2 >> 16; + int l6 = i1; + if (k6 < boundsTopX) { + int i7 = boundsTopX - k6; + l6 -= i7; + k6 = boundsTopX; + j += k1 * i7; + } + if (k6 + l6 >= boundsBottomX) { + int j7 = (k6 + l6) - boundsBottomX; + l6 -= j7; + } + j3 = 1 - j3; + if (j3 != 0) { + for (int k7 = k6; k7 < k6 + l6; k7++) { + i = coloursUsed[(j >> 16) + j6] & 0xff; + if (i != 0) { + i = colourList[i]; + int k3 = i >> 16 & 0xff; + int l3 = i >> 8 & 0xff; + int i4 = i & 0xff; + if (k3 == l3 && l3 == i4) + dest[k7 + l] = ((k3 * j4 >> 8) << 16) + ((l3 * k4 >> 8) << 8) + (i4 * l4 >> 8); + else if (k3 == 255 && l3 == i4) + dest[k7 + l] = ((k3 * i5 >> 8) << 16) + ((l3 * j5 >> 8) << 8) + (i4 * k5 >> 8); + else + dest[k7 + l] = i; + } + j += k1; + } + + } + k += l1; + j = l5; + l += width2; + l2 += i3; + } + + return; + } catch (Exception Ex) { + System.out.println("error in transparent sprite plot routine"); + } + } + + public void drawstringRight(String text, int x, int y, int font, int colour) { + drawstring(text, x - textWidth(text, font), y, font, colour); + } + + public void drawStringCenter(String text, int x, int y, int font, int colour) { + drawstring(text, x - textWidth(text, font) / 2, y, font, colour); + } + + public void centrepara(String text, int x, int y, int font, int colour, int max) { + try { + int width = 0; + byte fontdata[] = gameFonts[font]; + int start = 0; + int end = 0; + for (int index = 0; index < text.length(); index++) { + if (text.charAt(index) == '@' && index + 4 < text.length() && text.charAt(index + 4) == '@') + index += 4; + else if (text.charAt(index) == '~' && index + 4 < text.length() && text.charAt(index + 4) == '~') + index += 4; + else + width += fontdata[characterWidth[text.charAt(index)] + 7]; + if (text.charAt(index) == ' ') + end = index; + if (text.charAt(index) == '%') { + end = index; + width = 1000; + } + if (width > max) { + if (end <= start) + end = index; + drawStringCenter(text.substring(start, end), x, y, font, colour); + width = 0; + start = index = end + 1; + y += textHeight(font); + } + } + + if (width > 0) { + drawStringCenter(text.substring(start), x, y, font, colour); + return; + } + } catch (Exception exception) { + System.out.println("centrepara: " + exception); + exception.printStackTrace(); + } + } + + public void drawstring(String text, int x, int y, int font, int colour) { + try { + byte fontData[] = gameFonts[font]; + for (int idx = 0; idx < text.length(); idx++) + if (text.charAt(idx) == '@' && idx + 4 < text.length() && text.charAt(idx + 4) == '@') { + if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("red")) + colour = 0xff0000; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("lre")) + colour = 0xff9040; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("yel")) + colour = 0xffff00; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("gre")) + colour = 65280; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("blu")) + colour = 255; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("cya")) + colour = 65535; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("mag")) + colour = 0xff00ff; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("whi")) + colour = 0xffffff; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("bla")) + colour = 0; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("dre")) + colour = 0xc00000; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("ora")) + colour = 0xff9040; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("ran")) + colour = (int) (Math.random() * 16777215D); + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("or1")) + colour = 0xffb000; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("or2")) + colour = 0xff7000; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("or3")) + colour = 0xff3000; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("gr1")) + colour = 0xc0ff00; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("gr2")) + colour = 0x80ff00; + else if (text.substring(idx + 1, idx + 4).equalsIgnoreCase("gr3")) + colour = 0x40ff00; + idx += 4; + } else if (text.charAt(idx) == '~' && idx + 4 < text.length() && text.charAt(idx + 4) == '~') { + char c = text.charAt(idx + 1); + char c1 = text.charAt(idx + 2); + char c2 = text.charAt(idx + 3); + if (c >= '0' && c <= '9' && c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9') + x = Integer.parseInt(text.substring(idx + 1, idx + 4)); + idx += 4; + } else { + int width = characterWidth[text.charAt(idx)]; + if (loggedIn && colour != 0) { + drawCharacter(width, x + 1, y, 0, fontData); + drawCharacter(width, x, y + 1, 0, fontData); + } + drawCharacter(width, x, y, colour, fontData); + x += fontData[width + 7]; + } + + return; + } catch (Exception exception) { + System.out.println("drawstring: " + exception); + exception.printStackTrace(); + return; + } + } + + private void drawCharacter(int width, int x, int y, int colour, byte font[]) { + int i1 = x + font[width + 5]; + int j1 = y - font[width + 6]; + int k1 = font[width + 3]; + int l1 = font[width + 4]; + int i2 = font[width] * 16384 + font[width + 1] * 128 + font[width + 2]; + int j2 = i1 + j1 * width2; + int k2 = width2 - k1; + int l2 = 0; + if (j1 < boundsTopY) { + int i3 = boundsTopY - j1; + l1 -= i3; + j1 = boundsTopY; + i2 += i3 * k1; + j2 += i3 * width2; + } + if (j1 + l1 >= boundsBottomY) + l1 -= ((j1 + l1) - boundsBottomY) + 1; + if (i1 < boundsTopX) { + int j3 = boundsTopX - i1; + k1 -= j3; + i1 = boundsTopX; + i2 += j3; + j2 += j3; + l2 += j3; + k2 += j3; + } + if (i1 + k1 >= boundsBottomX) { + int k3 = ((i1 + k1) - boundsBottomX) + 1; + k1 -= k3; + l2 += k3; + k2 += k3; + } + if (k1 > 0 && l1 > 0) { + plotLetter(pixels, font, colour, i2, j2, k1, l1, k2, l2); + } + } + + private void plotLetter(int ai[], byte abyte0[], int i, int j, int k, int l, int i1, + int j1, int k1) { + try { + int l1 = -(l >> 2); + l = -(l & 3); + for (int i2 = -i1; i2 < 0; i2++) { + for (int j2 = l1; j2 < 0; j2++) { + if (abyte0[j++] != 0) + ai[k++] = i; + else + k++; + if (abyte0[j++] != 0) + ai[k++] = i; + else + k++; + if (abyte0[j++] != 0) + ai[k++] = i; + else + k++; + if (abyte0[j++] != 0) + ai[k++] = i; + else + k++; + } + + for (int k2 = l; k2 < 0; k2++) + if (abyte0[j++] != 0) + ai[k++] = i; + else + k++; + + k += j1; + j += k1; + } + + return; + } catch (Exception exception) { + System.out.println("plotletter: " + exception); + exception.printStackTrace(); + return; + } + } + + private void method259(int ai[], byte abyte0[], int i, int j, int k, int l, int i1, + int j1, int k1) {// todo + for (int l1 = -i1; l1 < 0; l1++) { + for (int i2 = -l; i2 < 0; i2++) { + int j2 = abyte0[j++] & 0xff; + if (j2 > 30) { + if (j2 >= 230) { + ai[k++] = i; + } else { + int k2 = ai[k]; + ai[k++] = ((i & 0xff00ff) * j2 + (k2 & 0xff00ff) * (256 - j2) & 0xff00ff00) + ((i & 0xff00) * j2 + (k2 & 0xff00) * (256 - j2) & 0xff0000) >> 8; + } + } else { + k++; + } + } + + k += j1; + j += k1; + } + + } + + public int textHeight(int fontId) { + if (fontId == 0) + return 12; + if (fontId == 1) + return 14; + if (fontId == 2) + return 14; + if (fontId == 3) + return 15; + if (fontId == 4) + return 15; + if (fontId == 5) + return 19; + if (fontId == 6) + return 24; + if (fontId == 7) + return 29; + else + return textHeightFont(fontId); + } + + public int textHeightFont(int fontId) { + if (fontId == 0) + return gameFonts[fontId][8] - 2; + else + return gameFonts[fontId][8] - 1; + } + + public int textWidth(String text, int fontId) { + int total = 0; + byte font[] = gameFonts[fontId]; + for (int idx = 0; idx < text.length(); idx++) + if (text.charAt(idx) == '@' && idx + 4 < text.length() && text.charAt(idx + 4) == '@') + idx += 4; + else if (text.charAt(idx) == '~' && idx + 4 < text.length() && text.charAt(idx + 4) == '~') + idx += 4; + else + total += font[characterWidth[text.charAt(idx)] + 7]; + + return total; + } + + /*public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { + return true; + }*/ +} diff --git a/mudclient204-threadless/SurfaceSprite.java b/mudclient204-threadless/SurfaceSprite.java new file mode 100644 index 0000000..99091e9 --- /dev/null +++ b/mudclient204-threadless/SurfaceSprite.java @@ -0,0 +1,32 @@ +//import java.awt.*; + +public class SurfaceSprite extends Surface { + + public mudclient mudclientref; + + public SurfaceSprite(int width, int height, int k, mudclient component) { + super(width, height, k, component); + } + + public void spriteClipping(int x, int y, int w, int h, int id, int tx, int ty) { + if (id >= 50000) { + mudclientref.drawTeleportBubble(x, y, w, h, id - 50000, tx, ty); + return; + } + if (id >= 40000) { + mudclientref.drawItem(x, y, w, h, id - 40000, tx, ty); + return; + } + if (id >= 20000) { + mudclientref.drawNpc(x, y, w, h, id - 20000, tx, ty); + return; + } + if (id >= 5000) { + mudclientref.drawPlayer(x, y, w, h, id - 5000, tx, ty); + return; + } else { + super.spriteClipping(x, y, w, h, id); + return; + } + } +} diff --git a/mudclient204-threadless/Utility.java b/mudclient204-threadless/Utility.java new file mode 100644 index 0000000..7952c69 --- /dev/null +++ b/mudclient204-threadless/Utility.java @@ -0,0 +1,238 @@ +import java.io.*; +import java.net.URL; + +public class Utility { + + //public static String lastFile; + + public static URL appletCodeBase = null; + public static boolean aBoolean546; + private static int bitmask[] = { + 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, + 1023, 2047, 4095, 8191, 16383, 32767, 65535, 0x1ffff, 0x3ffff, 0x7ffff, + 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, + 0x3fffffff, 0x7fffffff, -1 + }; + + public static InputStream openFile(String s) + throws IOException { + //lastFile = s; + Object obj; + if (appletCodeBase == null) { + obj = new BufferedInputStream(new FileInputStream(s)); + } else { + URL url = new URL(appletCodeBase, s); + obj = url.openStream(); + } + return ((InputStream) (obj)); + } + + public static void readFully(String s, byte abyte0[], int i) + throws IOException { + InputStream inputstream = openFile(s); + DataInputStream datainputstream = new DataInputStream(inputstream); + try { + datainputstream.readFully(abyte0, 0, i); + } catch (EOFException Ex) { + } + datainputstream.close(); + } + + public static int getUnsignedByte(byte byte0) { + return byte0 & 0xff; + } + + public static int getUnsignedShort(byte abyte0[], int i) { + return ((abyte0[i] & 0xff) << 8) + (abyte0[i + 1] & 0xff); + } + + public static int getUnsignedInt(byte abyte0[], int i) { + return ((abyte0[i] & 0xff) << 24) + ((abyte0[i + 1] & 0xff) << 16) + ((abyte0[i + 2] & 0xff) << 8) + (abyte0[i + 3] & 0xff); + } + + public static long getUnsignedLong(byte buff[], int off) { + return (((long) getUnsignedInt(buff, off) & 0xffffffffL) << 32) + ((long) getUnsignedInt(buff, off + 4) & 0xffffffffL); + } + + public static int getSignedShort(byte abyte0[], int i) { + int j = getUnsignedByte(abyte0[i]) * 256 + getUnsignedByte(abyte0[i + 1]); + if (j > 32767) + j -= 0x10000; + return j; + } + + public static int getUnsignedInt2(byte abyte0[], int i) { + if ((abyte0[i] & 0xff) < 128) + return abyte0[i]; + else + return ((abyte0[i] & 0xff) - 128 << 24) + ((abyte0[i + 1] & 0xff) << 16) + ((abyte0[i + 2] & 0xff) << 8) + (abyte0[i + 3] & 0xff); + } + + public static int getBitMask(byte buff[], int off, int len) { + int k = off >> 3; + int l = 8 - (off & 7); + int i1 = 0; + for (; len > l; l = 8) { + i1 += (buff[k++] & bitmask[l]) << len - l; + len -= l; + } + + if (len == l) + i1 += buff[k] & bitmask[l]; + else + i1 += buff[k] >> l - len & bitmask[len]; + return i1; + } + + public static String formatAuthString(String s, int maxlen) { + String s1 = ""; + for (int j = 0; j < maxlen; j++) + if (j >= s.length()) { + s1 = s1 + " "; + } else { + char c = s.charAt(j); + if (c >= 'a' && c <= 'z') + s1 = s1 + c; + else if (c >= 'A' && c <= 'Z') + s1 = s1 + c; + else if (c >= '0' && c <= '9') + s1 = s1 + c; + else + s1 = s1 + '_'; + } + + return s1; + } + + public static String ip2string(int i) { + return (i >> 24 & 0xff) + "." + (i >> 16 & 0xff) + "." + (i >> 8 & 0xff) + "." + (i & 0xff); + } + + public static long username2hash(String s) { + String s1 = ""; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c >= 'a' && c <= 'z') + s1 = s1 + c; + else if (c >= 'A' && c <= 'Z') + s1 = s1 + (char) ((c + 97) - 65); + else if (c >= '0' && c <= '9') + s1 = s1 + c; + else + s1 = s1 + ' '; + } + + s1 = s1.trim(); + if (s1.length() > 12) + s1 = s1.substring(0, 12); + long hash = 0L; + for (int j = 0; j < s1.length(); j++) { + char c1 = s1.charAt(j); + hash *= 37L; + if (c1 >= 'a' && c1 <= 'z') + hash += (1 + c1) - 97; + else if (c1 >= '0' && c1 <= '9') + hash += (27 + c1) - 48; + } + + return hash; + } + + public static String hash2username(long hash) { + if (hash < 0L) + return "invalidName"; + String s = ""; + while (hash != 0L) { + int i = (int) (hash % 37L); + hash /= 37L; + if (i == 0) + s = " " + s; + else if (i < 27) { + if (hash % 37L == 0L) + s = (char) ((i + 65) - 1) + s; + else + s = (char) ((i + 97) - 1) + s; + } else { + s = (char) ((i + 48) - 27) + s; + } + } + return s; + } + + public static int getDataFileOffset(String filename, byte data[]) { + int numEntries = getUnsignedShort(data, 0); + int wantedHash = 0; + filename = filename.toUpperCase(); + for (int k = 0; k < filename.length(); k++) + wantedHash = (wantedHash * 61 + filename.charAt(k)) - 32; + + int offset = 2 + numEntries * 10; + for (int entry = 0; entry < numEntries; entry++) { + int fileHash = (data[entry * 10 + 2] & 0xff) * 0x1000000 + (data[entry * 10 + 3] & 0xff) * 0x10000 + (data[entry * 10 + 4] & 0xff) * 256 + (data[entry * 10 + 5] & 0xff); + int fileSize = (data[entry * 10 + 9] & 0xff) * 0x10000 + (data[entry * 10 + 10] & 0xff) * 256 + (data[entry * 10 + 11] & 0xff); + if (fileHash == wantedHash) + return offset; + offset += fileSize; + } + + return 0; + } + + public static int getDataFileLength(String filename, byte data[]) { + int numEntries = getUnsignedShort(data, 0); + int wantedHash = 0; + filename = filename.toUpperCase(); + for (int k = 0; k < filename.length(); k++) + wantedHash = (wantedHash * 61 + filename.charAt(k)) - 32; + + int offset = 2 + numEntries * 10; + for (int i1 = 0; i1 < numEntries; i1++) { + int fileHash = (data[i1 * 10 + 2] & 0xff) * 0x1000000 + (data[i1 * 10 + 3] & 0xff) * 0x10000 + (data[i1 * 10 + 4] & 0xff) * 256 + (data[i1 * 10 + 5] & 0xff); + int fileSize = (data[i1 * 10 + 6] & 0xff) * 0x10000 + (data[i1 * 10 + 7] & 0xff) * 256 + (data[i1 * 10 + 8] & 0xff); + int fileSizeCompressed = (data[i1 * 10 + 9] & 0xff) * 0x10000 + (data[i1 * 10 + 10] & 0xff) * 256 + (data[i1 * 10 + 11] & 0xff); + if (fileHash == wantedHash) + return fileSize; + offset += fileSizeCompressed; + } + + return 0; + } + + public static byte[] loadData(String s, int i, byte abyte0[]) { + byte[] b = unpackData(s, i, abyte0, null); + return b; + } + + public static byte[] unpackData(String filename, int i, byte archiveData[], byte fileData[]) { + int numEntries = (archiveData[0] & 0xff) * 256 + (archiveData[1] & 0xff); + int wantedHash = 0; + filename = filename.toUpperCase(); + + for (int l = 0; l < filename.length(); l++){ + wantedHash = (wantedHash * 61 + filename.charAt(l)) - 32; + } + + int offset = 2 + numEntries * 10; + for (int entry = 0; entry < numEntries; entry++) { + int fileHash = (archiveData[entry * 10 + 2] & 0xff) * 0x1000000 + (archiveData[entry * 10 + 3] & 0xff) * 0x10000 + (archiveData[entry * 10 + 4] & 0xff) * 256 + (archiveData[entry * 10 + 5] & 0xff); + int fileSize = (archiveData[entry * 10 + 6] & 0xff) * 0x10000 + (archiveData[entry * 10 + 7] & 0xff) * 256 + (archiveData[entry * 10 + 8] & 0xff); + int fileSizeCompressed = (archiveData[entry * 10 + 9] & 0xff) * 0x10000 + (archiveData[entry * 10 + 10] & 0xff) * 256 + (archiveData[entry * 10 + 11] & 0xff); + if (fileHash == wantedHash) { + if (fileData == null) + fileData = new byte[fileSize + i]; + if (fileSize != fileSizeCompressed) { + BZLib.decompress(fileData, fileSize, archiveData, fileSizeCompressed, offset); + } else { + for (int j = 0; j < fileSize; j++) + fileData[j] = archiveData[offset + j]; + + } + return fileData; + } + offset += fileSizeCompressed; + } + + return null; + } + +} diff --git a/mudclient204-threadless/Version.java b/mudclient204-threadless/Version.java new file mode 100644 index 0000000..6e1f0d1 --- /dev/null +++ b/mudclient204-threadless/Version.java @@ -0,0 +1,15 @@ +public class Version { + + //public static int unused = 203; + public static int CLIENT = 204; + public static int CONFIG = 85; + public static int MAPS = 63; + public static int MEDIA = 58; + public static int MODELS = 36; + public static int TEXTURES = 17; + public static int ENTITY = 24; + public static int SOUNDS = 1; + public static int FILTER = 2; + public static int FONTS = 1; + +} diff --git a/mudclient204-threadless/WordFilter.java b/mudclient204-threadless/WordFilter.java new file mode 100644 index 0000000..92f6444 --- /dev/null +++ b/mudclient204-threadless/WordFilter.java @@ -0,0 +1,711 @@ +public class WordFilter { + + static boolean DEBUGTLD; + static boolean DEBUGWORD; + static boolean forceLowercase = true; + //static int unused = 3;// todo + static int hashFragments[]; + static char badList[][]; + static byte badCharIds[][][]; + static char hostList[][]; + static byte hostCharIds[][][]; + static char tldList[][]; + static int tldType[]; + static String ignoreList[] = { + "cook", "cook's", "cooks", "seeks", "sheet" + }; + + public static void loadFilters(Buffer fragments, Buffer bad, Buffer host, Buffer tld) { + loadBad(bad); + loadHost(host); + loadFragments(fragments); + loadTld(tld); + } + + public static void loadTld(Buffer buffer) { + int wordcount = buffer.getUnsignedInt(); + tldList = new char[wordcount][]; + tldType = new int[wordcount]; + for (int idx = 0; idx < wordcount; idx++) { + tldType[idx] = buffer.getUnsignedByte(); + char ac[] = new char[buffer.getUnsignedByte()]; + for (int k = 0; k < ac.length; k++) + ac[k] = (char) buffer.getUnsignedByte(); + + tldList[idx] = ac; + } + + } + + public static void loadBad(Buffer buffer) { + int wordcount = buffer.getUnsignedInt(); + badList = new char[wordcount][]; + badCharIds = new byte[wordcount][][]; + readBuffer(buffer, badList, badCharIds); + } + + public static void loadHost(Buffer buffer) { + int wordcount = buffer.getUnsignedInt(); + hostList = new char[wordcount][]; + hostCharIds = new byte[wordcount][][]; + readBuffer(buffer, hostList, hostCharIds); + } + + public static void loadFragments(Buffer buffer) { + hashFragments = new int[buffer.getUnsignedInt()]; + for (int i = 0; i < hashFragments.length; i++) { + hashFragments[i] = buffer.getUnsignedShort(); + } + + } + + public static void readBuffer(Buffer buffer, char wordList[][], byte charIds[][][]) { + for (int i = 0; i < wordList.length; i++) { + char currentWord[] = new char[buffer.getUnsignedByte()]; + for (int j = 0; j < currentWord.length; j++) + currentWord[j] = (char) buffer.getUnsignedByte(); + + wordList[i] = currentWord; + byte ids[][] = new byte[buffer.getUnsignedInt()][2]; + for (int j = 0; j < ids.length; j++) { + ids[j][0] = (byte) buffer.getUnsignedByte(); + ids[j][1] = (byte) buffer.getUnsignedByte(); + } + + if (ids.length > 0) + charIds[i] = ids; + } + + } + + public static String filter(String input) { + char inputChars[] = input.toLowerCase().toCharArray(); + applyDotSlashFilter(inputChars); + applyBadwordFilter(inputChars); + applyHostFilter(inputChars); + heywhathteufck(inputChars); + for (int ignoreIdx = 0; ignoreIdx < ignoreList.length; ignoreIdx++) { + for (int inputIgnoreIdx = -1; (inputIgnoreIdx = input.indexOf(ignoreList[ignoreIdx], inputIgnoreIdx + 1)) != -1; ) { + char ignorewordChars[] = ignoreList[ignoreIdx].toCharArray(); + for (int ignorewordIdx = 0; ignorewordIdx < ignorewordChars.length; ignorewordIdx++) + inputChars[ignorewordIdx + inputIgnoreIdx] = ignorewordChars[ignorewordIdx]; + + } + + } + + if (forceLowercase) { + stripLowercase(input.toCharArray(), inputChars); + toLowercase(inputChars); + } + return new String(inputChars); + } + + public static void stripLowercase(char input[], char output[]) { + for (int i = 0; i < input.length; i++) + if (output[i] != '*' && isUppercase(input[i])) + output[i] = input[i]; + + } + + public static void toLowercase(char input[]) { + boolean isUppercase = true; + for (int i = 0; i < input.length; i++) { + char current = input[i]; + if (isLetter(current)) { + if (isUppercase) { + if (isLowercase(current)) + isUppercase = false; + } else if (isUppercase(current)) + input[i] = (char) ((current + 97) - 65); + } else { + isUppercase = true; + } + } + + } + + public static void applyBadwordFilter(char input[]) { + for (int i = 0; i < 2; i++) {// why lol + for (int j = badList.length - 1; j >= 0; j--) + applyWordFilter(input, badList[j], badCharIds[j]); + + } + + } + + public static void applyHostFilter(char input[]) { + for (int i = hostList.length - 1; i >= 0; i--) + applyWordFilter(input, hostList[i], hostCharIds[i]); + + } + + public static void applyDotSlashFilter(char input[]) { + char input1[] = input.clone(); + char dot[] = { + 'd', 'o', 't' + }; + applyWordFilter(input1, dot, null); + char input2[] = input.clone(); + char slash[] = { + 's', 'l', 'a', 's', 'h' + }; + applyWordFilter(input2, slash, null); + for (int i = 0; i < tldList.length; i++) + applyTldFilter(input, input1, input2, tldList[i], tldType[i]); + + } + + public static void applyTldFilter(char input[], char input1[], char input2[], char tld[], int type) { + if (tld.length > input.length) + return; + for (int charIndex = 0; charIndex <= input.length - tld.length; charIndex++) { + int inputCharCount = charIndex; + int l = 0; + while (inputCharCount < input.length) { + int i1 = 0; + char current = input[inputCharCount]; + char next = '\0'; + if (inputCharCount + 1 < input.length) + next = input[inputCharCount + 1]; + if (l < tld.length && (i1 = compareLettersNumbers(tld[l], current, next)) > 0) { + inputCharCount += i1; + l++; + continue; + } + if (l == 0) + break; + if ((i1 = compareLettersNumbers(tld[l - 1], current, next)) > 0) { + inputCharCount += i1; + continue; + } + if (l >= tld.length || !isSpecial(current)) + break; + inputCharCount++; + } + if (l >= tld.length) { + boolean flag = false; + int startMatch = getAsteriskCount(input, input1, charIndex); + int endMatch = getAsteriskCount2(input, input2, inputCharCount - 1); + if (DEBUGTLD) + System.out.println("Potential tld: " + tld + " at char " + charIndex + " (type=" + type + ", startmatch=" + startMatch + ", endmatch=" + endMatch + ")"); + if (type == 1 && startMatch > 0 && endMatch > 0) + flag = true; + if (type == 2 && (startMatch > 2 && endMatch > 0 || startMatch > 0 && endMatch > 2)) + flag = true; + if (type == 3 && startMatch > 0 && endMatch > 2) + flag = true; + boolean tmp = type == 3 && startMatch > 2 && endMatch > 0; + if (flag) { + if (DEBUGTLD) + System.out.println("Filtered tld: " + tld + " at char " + charIndex); + int l1 = charIndex; + int i2 = inputCharCount - 1; + if (startMatch > 2) { + if (startMatch == 4) { + boolean flag1 = false; + for (int k2 = l1 - 1; k2 >= 0; k2--) + if (flag1) { + if (input1[k2] != '*') + break; + l1 = k2; + } else if (input1[k2] == '*') { + l1 = k2; + flag1 = true; + } + + } + boolean flag2 = false; + for (int l2 = l1 - 1; l2 >= 0; l2--) + if (flag2) { + if (isSpecial(input[l2])) + break; + l1 = l2; + } else if (!isSpecial(input[l2])) { + flag2 = true; + l1 = l2; + } + + } + if (endMatch > 2) { + if (endMatch == 4) { + boolean flag3 = false; + for (int i3 = i2 + 1; i3 < input.length; i3++) + if (flag3) { + if (input2[i3] != '*') + break; + i2 = i3; + } else if (input2[i3] == '*') { + i2 = i3; + flag3 = true; + } + + } + boolean flag4 = false; + for (int j3 = i2 + 1; j3 < input.length; j3++) + if (flag4) { + if (isSpecial(input[j3])) + break; + i2 = j3; + } else if (!isSpecial(input[j3])) { + flag4 = true; + i2 = j3; + } + + } + for (int j2 = l1; j2 <= i2; j2++) + input[j2] = '*'; + + } + } + } + + } + + public static int getAsteriskCount(char input[], char input1[], int len) {// fldajmolfmiALFKM + if (len == 0) + return 2; + for (int j = len - 1; j >= 0; j--) { + if (!isSpecial(input[j])) + break; + if (input[j] == ',' || input[j] == '.') + return 3; + } + + int filtered = 0; + for (int l = len - 1; l >= 0; l--) { + if (!isSpecial(input1[l])) + break; + if (input1[l] == '*') + filtered++; + } + + if (filtered >= 3) + return 4; + return isSpecial(input[len - 1]) ? 1 : 0; + } + + public static int getAsteriskCount2(char input[], char input1[], int len) {// lolmnafomLMAFOA + if (len + 1 == input.length) + return 2; + for (int j = len + 1; j < input.length; j++) { + if (!isSpecial(input[j])) + break; + if (input[j] == '\\' || input[j] == '/') + return 3; + } + + int filtered = 0; + for (int l = len + 1; l < input.length; l++) { + if (!isSpecial(input1[l])) + break; + if (input1[l] == '*') + filtered++; + } + + if (filtered >= 5) + return 4; + return isSpecial(input[len + 1]) ? 1 : 0; + } + + public static void applyWordFilter(char input[], char wordlist[], byte charIds[][]) { + if (wordlist.length > input.length) + return; + for (int charIndex = 0; charIndex <= input.length - wordlist.length; charIndex++) { + int inputCharCount = charIndex; + int k = 0; + boolean specialChar = false; + while (inputCharCount < input.length) { + int l = 0; + char inputChar = input[inputCharCount]; + char nextChar = '\0'; + if (inputCharCount + 1 < input.length) + nextChar = input[inputCharCount + 1]; + if (k < wordlist.length && (l = compareLettersSymbols(wordlist[k], inputChar, nextChar)) > 0) { + inputCharCount += l; + k++; + continue; + } + if (k == 0) + break; + if ((l = compareLettersSymbols(wordlist[k - 1], inputChar, nextChar)) > 0) { + inputCharCount += l; + continue; + } + if (k >= wordlist.length || !isNotLowercase(inputChar)) + break; + if (isSpecial(inputChar) && inputChar != '\'') + specialChar = true; + inputCharCount++; + } + if (k >= wordlist.length) { + boolean filter = true; + if (DEBUGTLD) + System.out.println("Potential word: " + wordlist + " at char " + charIndex); + if (!specialChar) { + char prevChar = ' '; + if (charIndex - 1 >= 0) + prevChar = input[charIndex - 1]; + char curChar = ' '; + if (inputCharCount < input.length) + curChar = input[inputCharCount]; + byte prevId = getCharId(prevChar); + byte curId = getCharId(curChar); + if (charIds != null && compareCharIds(charIds, prevId, curId)) + filter = false; + } else { + boolean flag2 = false; + boolean flag3 = false; + if (charIndex - 1 < 0 || isSpecial(input[charIndex - 1]) && input[charIndex - 1] != '\'') + flag2 = true; + if (inputCharCount >= input.length || isSpecial(input[inputCharCount]) && input[inputCharCount] != '\'') + flag3 = true; + if (!flag2 || !flag3) { + boolean flag4 = false; + int j1 = charIndex - 2; + if (flag2) + j1 = charIndex; + for (; !flag4 && j1 < inputCharCount; j1++) + if (j1 >= 0 && (!isSpecial(input[j1]) || input[j1] == '\'')) { + char ac2[] = new char[3]; + int k1; + for (k1 = 0; k1 < 3; k1++) { + if (j1 + k1 >= input.length || isSpecial(input[j1 + k1]) && input[j1 + k1] != '\'') + break; + ac2[k1] = input[j1 + k1]; + } + + boolean flag5 = true; + if (k1 == 0) + flag5 = false; + if (k1 < 3 && j1 - 1 >= 0 && (!isSpecial(input[j1 - 1]) || input[j1 - 1] == '\'')) + flag5 = false; + if (flag5 && !containsFragmentHashes(ac2)) + flag4 = true; + } + + if (!flag4) + filter = false; + } + } + if (filter) { + if (DEBUGWORD) + System.out.println("Filtered word: " + wordlist + " at char " + charIndex); + for (int i1 = charIndex; i1 < inputCharCount; i1++) + input[i1] = '*'; + + } + } + } + + } + + public static boolean compareCharIds(byte charIdData[][], byte prevCharId, byte curCharId) { + int first = 0; + if (charIdData[first][0] == prevCharId && charIdData[first][1] == curCharId) + return true; + int last = charIdData.length - 1; + if (charIdData[last][0] == prevCharId && charIdData[last][1] == curCharId) + return true; + while (first != last && first + 1 != last) { + int middle = (first + last) / 2; + if (charIdData[middle][0] == prevCharId && charIdData[middle][1] == curCharId) + return true; + if (prevCharId < charIdData[middle][0] || prevCharId == charIdData[middle][0] && curCharId < charIdData[middle][1]) + last = middle; + else + first = middle; + } + return false; + } + + /** + * @param filterChar + * @param currentChar + * @param nextChar + * @return 0 for no match, 1 for currentChar matches, 2 for both currentChar and nextChar matching + */ + public static int compareLettersNumbers(char filterChar, char currentChar, char nextChar) { + if (filterChar == currentChar) + return 1; + if (filterChar == 'e' && currentChar == '3') + return 1; + if (filterChar == 't' && (currentChar == '7' || currentChar == '+')) + return 1; + if (filterChar == 'a' && (currentChar == '4' || currentChar == '@')) + return 1; + if (filterChar == 'o' && currentChar == '0') + return 1; + if (filterChar == 'i' && currentChar == '1') + return 1; + if (filterChar == 's' && currentChar == '5') + return 1; + if (filterChar == 'f' && currentChar == 'p' && nextChar == 'h') + return 2; + return filterChar == 'g' && currentChar == '9' ? 1 : 0; + } + + /** + * @param filterChar character to compare against + * @param currentChar current character + * @param nextChar next character + * @return 0 for no match, 1 for currentChar matches, 2 for both currentChar and nextChar matching + */ + public static int compareLettersSymbols(char filterChar, char currentChar, char nextChar) { + if (filterChar == '*') + return 0; + if (filterChar == currentChar) + return 1; + if (filterChar >= 'a' && filterChar <= 'z') { + if (filterChar == 'e') + return currentChar == '3' ? 1 : 0; + if (filterChar == 't') + return currentChar == '7' ? 1 : 0; + if (filterChar == 'a') + return currentChar == '4' || currentChar == '@' ? 1 : 0; + if (filterChar == 'o') { + if (currentChar == '0' || currentChar == '*') + return 1; + return currentChar == '(' && nextChar == ')' ? 2 : 0; + } + if (filterChar == 'i') + return currentChar == 'y' || currentChar == 'l' || currentChar == 'j' || currentChar == 'l' || currentChar == '!' || currentChar == ':' || currentChar == ';' ? 1 : 0; + if (filterChar == 'n') + return 0; + if (filterChar == 's') + return currentChar == '5' || currentChar == 'z' || currentChar == '$' ? 1 : 0; + if (filterChar == 'r') + return 0; + if (filterChar == 'h') + return 0; + if (filterChar == 'l') + return currentChar == '1' ? 1 : 0; + if (filterChar == 'd') + return 0; + if (filterChar == 'c') + return currentChar == '(' ? 1 : 0; + if (filterChar == 'u') + return currentChar == 'v' ? 1 : 0; + if (filterChar == 'm') + return 0; + if (filterChar == 'f') + return currentChar == 'p' && nextChar == 'h' ? 2 : 0; + if (filterChar == 'p') + return 0; + if (filterChar == 'g') + return currentChar == '9' || currentChar == '6' ? 1 : 0; + if (filterChar == 'w') + return currentChar == 'v' && nextChar == 'v' ? 2 : 0; + if (filterChar == 'y') + return 0; + if (filterChar == 'b') + return currentChar == '1' && nextChar == '3' ? 2 : 0; + if (filterChar == 'v') + return 0; + if (filterChar == 'k') + return 0; + if (filterChar == 'x') + return currentChar == ')' && nextChar == '(' ? 2 : 0; + if (filterChar == 'j') + return 0; + if (filterChar == 'q') + return 0; + if (filterChar == 'z') + return 0; + } + if (filterChar >= '0' && filterChar <= '9') { + if (filterChar == '0') { + if (currentChar == 'o' || currentChar == 'O') + return 1; + return currentChar == '(' && nextChar == ')' ? 2 : 0; + } + if (filterChar == '1') + return currentChar != 'l' ? 0 : 1; + if (filterChar == '2') + return 0; + if (filterChar == '3') + return 0; + if (filterChar == '4') + return 0; + if (filterChar == '5') + return 0; + if (filterChar == '6') + return 0; + if (filterChar == '7') + return 0; + if (filterChar == '8') + return 0; + if (filterChar == '9') + return 0; + } + if (filterChar == '-') + return 0; + if (filterChar == ',') + return currentChar == '.' ? 1 : 0; + if (filterChar == '.') + return currentChar == ',' ? 1 : 0; + if (filterChar == '(') + return 0; + if (filterChar == ')') + return 0; + if (filterChar == '!') + return currentChar == 'i' ? 1 : 0; + if (filterChar == '\'') + return 0; + if (DEBUGWORD) + System.out.println("Letter=" + filterChar + " not matched"); + return 0; + } + + /** + * Returns the id for the given char, ranging from {@code 1} to {@code 38}. + *

+ *

+     * id     range
+     * 1-26   a-z
+     * 27     unknown
+     * 28     apostrophe
+     * 29-38  0-9
+     * 
+ * + * @param c + * @return id for char {@code c} + */ + public static byte getCharId(char c) { + if (c >= 'a' && c <= 'z') + return (byte) (c - 97 + 1); + if (c == '\'') + return 28; + if (c >= '0' && c <= '9') + return (byte) (c - 48 + 29); + else + return 27; + } + + public static void heywhathteufck(char input[]) { + int digitIndex = 0; + int fromIndex = 0; + int k = 0; + int l = 0; + while ((digitIndex = indexOfDigit(input, fromIndex)) != -1) { + boolean flag = false; + for (int i = fromIndex; i >= 0 && i < digitIndex && !flag; i++) + if (!isSpecial(input[i]) && !isNotLowercase(input[i])) + flag = true; + + if (flag) + k = 0; + if (k == 0) + l = digitIndex; + fromIndex = indexOfNonDigit(input, digitIndex); + int j1 = 0; + for (int k1 = digitIndex; k1 < fromIndex; k1++) + j1 = (j1 * 10 + input[k1]) - 48; + + if (j1 > 255 || fromIndex - digitIndex > 8) + k = 0; + else + k++; + if (k == 4) { + for (int i = l; i < fromIndex; i++) + input[i] = '*'; + + k = 0; + } + } + } + + public static int indexOfDigit(char input[], int fromIndex) { + for (int i = fromIndex; i < input.length && i >= 0; i++) + if (input[i] >= '0' && input[i] <= '9') + return i; + + return -1; + } + + public static int indexOfNonDigit(char input[], int fromIndex) { + for (int i = fromIndex; i < input.length && i >= 0; i++) + if (input[i] < '0' || input[i] > '9') + return i; + + return input.length; + } + + public static boolean isSpecial(char c) { + return !isLetter(c) && !isDigit(c); + } + + public static boolean isNotLowercase(char c) { + if (c < 'a' || c > 'z') + return true; + return c == 'v' || c == 'x' || c == 'j' || c == 'q' || c == 'z'; + } + + public static boolean isLetter(char c) { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'; + } + + public static boolean isDigit(char c) { + return c >= '0' && c <= '9'; + } + + public static boolean isLowercase(char c) { + return c >= 'a' && c <= 'z'; + } + + public static boolean isUppercase(char c) { + return c >= 'A' && c <= 'Z'; + } + + public static boolean containsFragmentHashes(char input[]) { + boolean notNum = true; + for (int i = 0; i < input.length; i++) + if (!isDigit(input[i]) && input[i] != 0) + notNum = false; + + if (notNum) + return true; + int inputHash = word2hash(input); + int first = 0; + int last = hashFragments.length - 1; + if (inputHash == hashFragments[first] || inputHash == hashFragments[last]) + return true; + while (first != last && first + 1 != last) { + int middle = (first + last) / 2; + if (inputHash == hashFragments[middle]) + return true; + if (inputHash < hashFragments[middle]) + last = middle; + else + first = middle; + } + return false; + } + + /** + * @param word + * @return + * @see WordFilter#getCharId(char) + */ + public static int word2hash(char word[]) { + if (word.length > 6) + return 0; + int hash = 0; + for (int i = 0; i < word.length; i++) { + char c = word[word.length - i - 1]; + if (c >= 'a' && c <= 'z') + hash = hash * 38 + c - 97 + 1; + else if (c == '\'') + hash = hash * 38 + 27; + else if (c >= '0' && c <= '9') + hash = hash * 38 + c - 48 + 28; + else if (c != 0) { + if (DEBUGWORD) + System.out.println("word2hash failed on " + new String(word)); + return 0; + } + } + + return hash; + } +} diff --git a/mudclient204-threadless/World.java b/mudclient204-threadless/World.java new file mode 100644 index 0000000..ea79f8b --- /dev/null +++ b/mudclient204-threadless/World.java @@ -0,0 +1,1484 @@ +import java.io.IOException; + +public class World { + + static final int colourTransparent = 12345678;// usewd by gamemodel.magic and diameter + final int regionWidth = 96;// could be the other way + final int regionHeight = 96;// around, im not sure + final int anInt585 = 128;// two possibilities; either where the region data is loaded, + boolean worldInitialised; + int objectAdjacency[][]; + byte tileDirection[][]; + GameModel wallModels[][]; + int terrainColours[]; + byte wallsNorthsouth[][]; + GameModel parentModel; + byte wallsRoof[][]; + byte terrainHeight[][]; + GameModel roofModels[][]; + // or in relation with models. im going with models + byte terrainColour[][]; + int localY[]; + byte tileDecoration[][]; + int routeVia[][]; + int wallsDiagonal[][]; + byte wallsEastwest[][]; + boolean aBoolean592; + boolean playerAlive; + int terrainHeightLocal[][]; + byte landscapePack[]; + byte mapPack[]; + Surface surface; + Scene scene; + GameModel terrainModels[]; + int localX[]; + byte memberLandscapePack[]; + byte memberMapPack[]; + int baseMediaSprite; + + public World(Scene scene, Surface surface) { + worldInitialised = true; + objectAdjacency = new int[regionWidth][regionHeight]; + tileDirection = new byte[4][2304]; + wallModels = new GameModel[4][64]; + terrainColours = new int[256]; + wallsNorthsouth = new byte[4][2304]; + wallsRoof = new byte[4][2304]; + terrainHeight = new byte[4][2304]; + roofModels = new GameModel[4][64]; + terrainColour = new byte[4][2304]; + localY = new int[18432]; + tileDecoration = new byte[4][2304]; + routeVia = new int[regionWidth][regionHeight]; + wallsDiagonal = new int[4][2304]; + wallsEastwest = new byte[4][2304]; + aBoolean592 = false; + playerAlive = false; + terrainHeightLocal = new int[regionWidth][regionHeight]; + terrainModels = new GameModel[64]; + localX = new int[18432]; + baseMediaSprite = 750; + this.scene = scene; + this.surface = surface; + for (int i = 0; i < 64; i++) + terrainColours[i] = Scene.rgb(255 - i * 4, 255 - (int) ((double) i * 1.75D), 255 - i * 4); + + for (int j = 0; j < 64; j++) + terrainColours[j + 64] = Scene.rgb(j * 3, 144, 0); + + for (int k = 0; k < 64; k++) + terrainColours[k + 128] = Scene.rgb(192 - (int) ((double) k * 1.5D), 144 - (int) ((double) k * 1.5D), 0); + + for (int l = 0; l < 64; l++) + terrainColours[l + 192] = Scene.rgb(96 - (int) ((double) l * 1.5D), 48 + (int) ((double) l * 1.5D), 0); + + } + + public int getWallEastwest(int x, int y) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte h = 0; + if (x >= 48 && y < 48) { + h = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + h = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + h = 3; + x -= 48; + y -= 48; + } + return wallsEastwest[h][x * 48 + y] & 0xff; + } + + public void setTerrainAmbience(int x, int y, int x2, int y2, int ambience) { + GameModel gameModel = terrainModels[x + y * 8]; + for (int j1 = 0; j1 < gameModel.numVertices; j1++) + if (gameModel.vertexX[j1] == x2 * anInt585 && gameModel.vertexZ[j1] == y2 * anInt585) { + gameModel.setVertexAmbience(j1, ambience); + return; + } + + } + + public int getWallRoof(int x, int y) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte h = 0; + if (x >= 48 && y < 48) { + h = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + h = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + h = 3; + x -= 48; + y -= 48; + } + return wallsRoof[h][x * 48 + y]; + } + + public int getElevation(int x, int y) { + int sX = x >> 7; + int sY = y >> 7; + int aX = x & 0x7f; + int aY = y & 0x7f; + if (sX < 0 || sY < 0 || sX >= 95 || sY >= 95) + return 0; + int h; + int hx; + int hy; + if (aX <= anInt585 - aY) { + h = getTerrainHeight(sX, sY); + hx = getTerrainHeight(sX + 1, sY) - h; + hy = getTerrainHeight(sX, sY + 1) - h; + } else { + h = getTerrainHeight(sX + 1, sY + 1); + hx = getTerrainHeight(sX, sY + 1) - h; + hy = getTerrainHeight(sX + 1, sY) - h; + aX = anInt585 - aX; + aY = anInt585 - aY; + } + int elevation = h + (hx * aX) / anInt585 + (hy * aY) / anInt585; + return elevation; + } + + public int getWallDiagonal(int x, int y) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte h = 0; + if (x >= 48 && y < 48) { + h = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + h = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + h = 3; + x -= 48; + y -= 48; + } + return wallsDiagonal[h][x * 48 + y]; + } + + public void removeObject2(int x, int y, int id) {// todo set object osmething something something + if (x < 0 || y < 0 || x >= 95 || y >= 95) + return; + if (GameData.objectType[id] == 1 || GameData.objectType[id] == 2) { + int tileDir = getTileDirection(x, y); + int modelWidth; + int modelHeight; + if (tileDir == 0 || tileDir == 4) { + modelWidth = GameData.objectWidth[id]; + modelHeight = GameData.objectHeight[id]; + } else { + modelHeight = GameData.objectWidth[id]; + modelWidth = GameData.objectHeight[id]; + } + for (int mx = x; mx < x + modelWidth; mx++) { + for (int my = y; my < y + modelHeight; my++) + if (GameData.objectType[id] == 1) + objectAdjacency[mx][my] |= 0x40; + else if (tileDir == 0) { + objectAdjacency[mx][my] |= 2; + if (mx > 0) + setObjectAdjacency(mx - 1, my, 8); + } else if (tileDir == 2) { + objectAdjacency[mx][my] |= 4; + if (my < 95) + setObjectAdjacency(mx, my + 1, 1); + } else if (tileDir == 4) { + objectAdjacency[mx][my] |= 8; + if (mx < 95) + setObjectAdjacency(mx + 1, my, 2); + } else if (tileDir == 6) { + objectAdjacency[mx][my] |= 1; + if (my > 0) + setObjectAdjacency(mx, my - 1, 4); + } + + } + + method404(x, y, modelWidth, modelHeight); + } + } + + public void removeWallObject(int x, int y, int k, int id) { + if (x < 0 || y < 0 || x >= 95 || y >= 95) + return; + if (GameData.wallObjectAdjacent[id] == 1) { + if (k == 0) { + objectAdjacency[x][y] &= 0xfffe; + if (y > 0) + method407(x, y - 1, 4); + } else if (k == 1) { + objectAdjacency[x][y] &= 0xfffd; + if (x > 0) + method407(x - 1, y, 8); + } else if (k == 2) + objectAdjacency[x][y] &= 0xffef; + else if (k == 3) + objectAdjacency[x][y] &= 0xffdf; + method404(x, y, 1, 1); + } + } + + public void method402(int i, int j, int k, int l, int i1) { + int j1 = i * 3; + int k1 = j * 3; + int l1 = scene.method302(l); + int i2 = scene.method302(i1); + l1 = l1 >> 1 & 0x7f7f7f; + i2 = i2 >> 1 & 0x7f7f7f; + if (k == 0) { + surface.drawLineHoriz(j1, k1, 3, l1); + surface.drawLineHoriz(j1, k1 + 1, 2, l1); + surface.drawLineHoriz(j1, k1 + 2, 1, l1); + surface.drawLineHoriz(j1 + 2, k1 + 1, 1, i2); + surface.drawLineHoriz(j1 + 1, k1 + 2, 2, i2); + return; + } + if (k == 1) { + surface.drawLineHoriz(j1, k1, 3, i2); + surface.drawLineHoriz(j1 + 1, k1 + 1, 2, i2); + surface.drawLineHoriz(j1 + 2, k1 + 2, 1, i2); + surface.drawLineHoriz(j1, k1 + 1, 1, l1); + surface.drawLineHoriz(j1, k1 + 2, 2, l1); + } + } + + public void loadSection(int x, int y, int plane, int chunk) { + String mapname = "m" + plane + x / 10 + x % 10 + y / 10 + y % 10; + try { + if (landscapePack != null) { + byte mapData[] = Utility.loadData(mapname + ".hei", 0, landscapePack); + if (mapData == null && memberLandscapePack != null) + mapData = Utility.loadData(mapname + ".hei", 0, memberLandscapePack); + if (mapData != null && mapData.length > 0) { + int off = 0; + int lastVal = 0; + for (int tile = 0; tile < 2304; ) { + int val = mapData[off++] & 0xff; + if (val < 128) { + terrainHeight[chunk][tile++] = (byte) val; + lastVal = val; + } + if (val >= 128) { + for (int i = 0; i < val - 128; i++) + terrainHeight[chunk][tile++] = (byte) lastVal; + + } + } + + lastVal = 64; + for (int tileY = 0; tileY < 48; tileY++) { + for (int tileX = 0; tileX < 48; tileX++) { + lastVal = terrainHeight[chunk][tileX * 48 + tileY] + lastVal & 0x7f; + terrainHeight[chunk][tileX * 48 + tileY] = (byte) (lastVal * 2); + } + + } + + lastVal = 0; + for (int tile = 0; tile < 2304; ) { + int val = mapData[off++] & 0xff; + if (val < 128) { + terrainColour[chunk][tile++] = (byte) val; + lastVal = val; + } + if (val >= 128) { + for (int i = 0; i < val - 128; i++) + terrainColour[chunk][tile++] = (byte) lastVal; + + } + } + + lastVal = 35; + for (int tileY = 0; tileY < 48; tileY++) { + for (int tileX = 0; tileX < 48; tileX++) { + lastVal = terrainColour[chunk][tileX * 48 + tileY] + lastVal & 0x7f;// ??? wat + terrainColour[chunk][tileX * 48 + tileY] = (byte) (lastVal * 2); + } + + } + + } else { + for (int tile = 0; tile < 2304; tile++) { + terrainHeight[chunk][tile] = 0; + terrainColour[chunk][tile] = 0; + } + + } + mapData = Utility.loadData(mapname + ".dat", 0, mapPack); + if (mapData == null && memberMapPack != null) + mapData = Utility.loadData(mapname + ".dat", 0, memberMapPack); + if (mapData == null || mapData.length == 0) + throw new IOException(); + int off = 0; + for (int tile = 0; tile < 2304; tile++) + wallsNorthsouth[chunk][tile] = mapData[off++]; + + for (int tile = 0; tile < 2304; tile++) + wallsEastwest[chunk][tile] = mapData[off++]; + + for (int tile = 0; tile < 2304; tile++) + wallsDiagonal[chunk][tile] = mapData[off++] & 0xff; + + for (int tile = 0; tile < 2304; tile++) { + int val = mapData[off++] & 0xff; + if (val > 0) + wallsDiagonal[chunk][tile] = val + 12000;// why?? + } + + for (int tile = 0; tile < 2304; ) { + int val = mapData[off++] & 0xff; + if (val < 128) { + wallsRoof[chunk][tile++] = (byte) val; + } else { + for (int i = 0; i < val - 128; i++) + wallsRoof[chunk][tile++] = 0; + + } + } + + int lastVal = 0; + for (int tile = 0; tile < 2304; ) { + int val = mapData[off++] & 0xff; + if (val < 128) { + tileDecoration[chunk][tile++] = (byte) val; + lastVal = val; + } else { + for (int i = 0; i < val - 128; i++) + tileDecoration[chunk][tile++] = (byte) lastVal; + + } + } + + for (int tile = 0; tile < 2304; ) { + int val = mapData[off++] & 0xff; + if (val < 128) { + tileDirection[chunk][tile++] = (byte) val; + } else { + for (int i = 0; i < val - 128; i++) + tileDirection[chunk][tile++] = 0; + + } + } + + mapData = Utility.loadData(mapname + ".loc", 0, mapPack); + if (mapData != null && mapData.length > 0) { + off = 0; + for (int tile = 0; tile < 2304; ) { + int val = mapData[off++] & 0xff; + if (val < 128) + wallsDiagonal[chunk][tile++] = val + 48000; + else + tile += val - 128; + } + + return; + } + } else { + byte mapData[] = new byte[20736]; + Utility.readFully("../gamedata/maps/" + mapname + ".jm", mapData, 20736); + int val = 0; + int off = 0; + for (int tile = 0; tile < 2304; tile++) { + val = val + mapData[off++] & 0xff; + terrainHeight[chunk][tile] = (byte) val; + } + + val = 0; + for (int tile = 0; tile < 2304; tile++) { + val = val + mapData[off++] & 0xff; + terrainColour[chunk][tile] = (byte) val; + } + + for (int tile = 0; tile < 2304; tile++) + wallsNorthsouth[chunk][tile] = mapData[off++]; + + for (int tile = 0; tile < 2304; tile++) + wallsEastwest[chunk][tile] = mapData[off++]; + + for (int tile = 0; tile < 2304; tile++) { + wallsDiagonal[chunk][tile] = (mapData[off] & 0xff) * 256 + (mapData[off + 1] & 0xff); + off += 2; + } + + for (int tile = 0; tile < 2304; tile++) + wallsRoof[chunk][tile] = mapData[off++]; + + for (int tile = 0; tile < 2304; tile++) + tileDecoration[chunk][tile] = mapData[off++]; + + for (int tile = 0; tile < 2304; tile++) + tileDirection[chunk][tile] = mapData[off++]; + + } + return; + } catch (IOException ex) { + } + for (int tile = 0; tile < 2304; tile++) { + terrainHeight[chunk][tile] = 0; + terrainColour[chunk][tile] = 0; + wallsNorthsouth[chunk][tile] = 0; + wallsEastwest[chunk][tile] = 0; + wallsDiagonal[chunk][tile] = 0; + wallsRoof[chunk][tile] = 0; + tileDecoration[chunk][tile] = 0; + if (plane == 0) + tileDecoration[chunk][tile] = -6; + if (plane == 3) + tileDecoration[chunk][tile] = 8; + tileDirection[chunk][tile] = 0; + } + + } + + public void method404(int x, int y, int k, int l) { + if (x < 1 || y < 1 || x + k >= regionWidth || y + l >= regionHeight) + return; + for (int xx = x; xx <= x + k; xx++) { + for (int yy = y; yy <= y + l; yy++) + if ((getObjectAdjacency(xx, yy) & 0x63) != 0 || (getObjectAdjacency(xx - 1, yy) & 0x59) != 0 || (getObjectAdjacency(xx, yy - 1) & 0x56) != 0 || (getObjectAdjacency(xx - 1, yy - 1) & 0x6c) != 0) + method425(xx, yy, 35); + else + method425(xx, yy, 0); + + } + + } + + public int getObjectAdjacency(int x, int y) { + if (x < 0 || y < 0 || x >= regionWidth || y >= regionHeight) + return 0; + else + return objectAdjacency[x][y]; + } + + public boolean hasRoof(int x, int y) { + return getWallRoof(x, y) > 0 && getWallRoof(x - 1, y) > 0 && getWallRoof(x - 1, y - 1) > 0 && getWallRoof(x, y - 1) > 0; + } + + public void method407(int i, int j, int k) { + objectAdjacency[i][j] &= 0xffff - k; + } + + public int getTerrainColour(int x, int y) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte byte0 = 0; + if (x >= 48 && y < 48) { + byte0 = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + byte0 = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + byte0 = 3; + x -= 48; + y -= 48; + } + return terrainColour[byte0][x * 48 + y] & 0xff; + } + + public void reset() { + if (worldInitialised) + scene.dispose(); + for (int i = 0; i < 64; i++) { + terrainModels[i] = null; + for (int j = 0; j < 4; j++) + wallModels[j][i] = null; + + for (int k = 0; k < 4; k++) + roofModels[k][i] = null; + + } + + System.gc(); + } + + public void setTiles() { + for (int x = 0; x < regionWidth; x++) { + for (int y = 0; y < regionHeight; y++) + if (getTileDecoration(x, y, 0) == 250) + if (x == 47 && getTileDecoration(x + 1, y, 0) != 250 && getTileDecoration(x + 1, y, 0) != 2) + setTileDecoration(x, y, 9); + else if (y == 47 && getTileDecoration(x, y + 1, 0) != 250 && getTileDecoration(x, y + 1, 0) != 2) + setTileDecoration(x, y, 9); + else + setTileDecoration(x, y, 2); + + } + + } + + public int getWallNorthsouth(int x, int y) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte h = 0; + if (x >= 48 && y < 48) { + h = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + h = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + h = 3; + x -= 48; + y -= 48; + } + return wallsNorthsouth[h][x * 48 + y] & 0xff; + } + + public int getTileDirection(int x, int y) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte h = 0; + if (x >= 48 && y < 48) { + h = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + h = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + h = 3; + x -= 48; + y -= 48; + } + return tileDirection[h][x * 48 + y]; + } + + public int getTileDecoration(int x, int y, int unused, int def) { + int deco = getTileDecoration(x, y, unused); + if (deco == 0) + return def; + else + return GameData.tileDecoration[deco - 1]; + } + + public int getTileDecoration(int x, int y, int unused) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte h = 0; + if (x >= 48 && y < 48) { + h = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + h = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + h = 3; + x -= 48; + y -= 48; + } + return tileDecoration[h][x * 48 + y] & 0xff; + } + + public void setTileDecoration(int x, int y, int v) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return; + byte h = 0; + if (x >= 48 && y < 48) { + h = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + h = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + h = 3; + x -= 48; + y -= 48; + } + tileDecoration[h][x * 48 + y] = (byte) v; + } + + public int route(int startX, int startY, int endX1, int endY1, int endX2, int endY2, int routeX[], int routeY[], boolean objects) { + for (int x = 0; x < regionWidth; x++) { + for (int y = 0; y < regionHeight; y++) + routeVia[x][y] = 0; + + } + + int writePtr = 0; + int readPtr = 0; + int x = startX; + int y = startY; + routeVia[startX][startY] = 99; + routeX[writePtr] = startX; + routeY[writePtr++] = startY; + int size = routeX.length; + boolean reached = false; + while (readPtr != writePtr) { + x = routeX[readPtr]; + y = routeY[readPtr]; + readPtr = (readPtr + 1) % size; + if (x >= endX1 && x <= endX2 && y >= endY1 && y <= endY2) { + reached = true; + break; + } + if (objects) { + if (x > 0 && x - 1 >= endX1 && x - 1 <= endX2 && y >= endY1 && y <= endY2 && (objectAdjacency[x - 1][y] & 8) == 0) { + reached = true; + break; + } + if (x < 95 && x + 1 >= endX1 && x + 1 <= endX2 && y >= endY1 && y <= endY2 && (objectAdjacency[x + 1][y] & 2) == 0) { + reached = true; + break; + } + if (y > 0 && x >= endX1 && x <= endX2 && y - 1 >= endY1 && y - 1 <= endY2 && (objectAdjacency[x][y - 1] & 4) == 0) { + reached = true; + break; + } + if (y < 95 && x >= endX1 && x <= endX2 && y + 1 >= endY1 && y + 1 <= endY2 && (objectAdjacency[x][y + 1] & 1) == 0) { + reached = true; + break; + } + } + if (x > 0 && routeVia[x - 1][y] == 0 && (objectAdjacency[x - 1][y] & 0x78) == 0) { + routeX[writePtr] = x - 1; + routeY[writePtr] = y; + writePtr = (writePtr + 1) % size; + routeVia[x - 1][y] = 2; + } + if (x < 95 && routeVia[x + 1][y] == 0 && (objectAdjacency[x + 1][y] & 0x72) == 0) { + routeX[writePtr] = x + 1; + routeY[writePtr] = y; + writePtr = (writePtr + 1) % size; + routeVia[x + 1][y] = 8; + } + if (y > 0 && routeVia[x][y - 1] == 0 && (objectAdjacency[x][y - 1] & 0x74) == 0) { + routeX[writePtr] = x; + routeY[writePtr] = y - 1; + writePtr = (writePtr + 1) % size; + routeVia[x][y - 1] = 1; + } + if (y < 95 && routeVia[x][y + 1] == 0 && (objectAdjacency[x][y + 1] & 0x71) == 0) { + routeX[writePtr] = x; + routeY[writePtr] = y + 1; + writePtr = (writePtr + 1) % size; + routeVia[x][y + 1] = 4; + } + if (x > 0 && y > 0 && (objectAdjacency[x][y - 1] & 0x74) == 0 && (objectAdjacency[x - 1][y] & 0x78) == 0 && (objectAdjacency[x - 1][y - 1] & 0x7c) == 0 && routeVia[x - 1][y - 1] == 0) { + routeX[writePtr] = x - 1; + routeY[writePtr] = y - 1; + writePtr = (writePtr + 1) % size; + routeVia[x - 1][y - 1] = 3; + } + if (x < 95 && y > 0 && (objectAdjacency[x][y - 1] & 0x74) == 0 && (objectAdjacency[x + 1][y] & 0x72) == 0 && (objectAdjacency[x + 1][y - 1] & 0x76) == 0 && routeVia[x + 1][y - 1] == 0) { + routeX[writePtr] = x + 1; + routeY[writePtr] = y - 1; + writePtr = (writePtr + 1) % size; + routeVia[x + 1][y - 1] = 9; + } + if (x > 0 && y < 95 && (objectAdjacency[x][y + 1] & 0x71) == 0 && (objectAdjacency[x - 1][y] & 0x78) == 0 && (objectAdjacency[x - 1][y + 1] & 0x79) == 0 && routeVia[x - 1][y + 1] == 0) { + routeX[writePtr] = x - 1; + routeY[writePtr] = y + 1; + writePtr = (writePtr + 1) % size; + routeVia[x - 1][y + 1] = 6; + } + if (x < 95 && y < 95 && (objectAdjacency[x][y + 1] & 0x71) == 0 && (objectAdjacency[x + 1][y] & 0x72) == 0 && (objectAdjacency[x + 1][y + 1] & 0x73) == 0 && routeVia[x + 1][y + 1] == 0) { + routeX[writePtr] = x + 1; + routeY[writePtr] = y + 1; + writePtr = (writePtr + 1) % size; + routeVia[x + 1][y + 1] = 12; + } + } + if (!reached) + return -1; + readPtr = 0; + routeX[readPtr] = x; + routeY[readPtr++] = y; + int stride; + for (int step = stride = routeVia[x][y]; x != startX || y != startY; step = routeVia[x][y]) { + if (step != stride) { + stride = step; + routeX[readPtr] = x; + routeY[readPtr++] = y; + } + if ((step & 2) != 0) + x++; + else if ((step & 8) != 0) + x--; + if ((step & 1) != 0) + y++; + else if ((step & 4) != 0) + y--; + } + + return readPtr; + } + + public void setObjectAdjacency(int x, int y, int dir, int id) { + if (x < 0 || y < 0 || x >= 95 || y >= 95) + return; + if (GameData.wallObjectAdjacent[id] == 1) { + if (dir == 0) { + objectAdjacency[x][y] |= 1; + if (y > 0) + setObjectAdjacency(x, y - 1, 4); + } else if (dir == 1) { + objectAdjacency[x][y] |= 2; + if (x > 0) + setObjectAdjacency(x - 1, y, 8); + } else if (dir == 2) + objectAdjacency[x][y] |= 0x10; + else if (dir == 3) + objectAdjacency[x][y] |= 0x20; + method404(x, y, 1, 1); + } + } + + public void loadSection(int x, int y, int plane, boolean flag) { + int l = (x + 24) / 48; + int i1 = (y + 24) / 48; + loadSection(l - 1, i1 - 1, plane, 0); + loadSection(l, i1 - 1, plane, 1); + loadSection(l - 1, i1, plane, 2); + loadSection(l, i1, plane, 3); + setTiles(); + if (parentModel == null) + parentModel = new GameModel(18688, 18688, true, true, false, false, true); + if (flag) { + surface.blackScreen(); + for (int j1 = 0; j1 < regionWidth; j1++) { + for (int l1 = 0; l1 < regionHeight; l1++) + objectAdjacency[j1][l1] = 0; + + } + + GameModel gameModel = parentModel; + gameModel.clear(); + for (int j2 = 0; j2 < regionWidth; j2++) { + for (int i3 = 0; i3 < regionHeight; i3++) { + int i4 = -getTerrainHeight(j2, i3); + if (getTileDecoration(j2, i3, plane) > 0 && GameData.tileType[getTileDecoration(j2, i3, plane) - 1] == 4) + i4 = 0; + if (getTileDecoration(j2 - 1, i3, plane) > 0 && GameData.tileType[getTileDecoration(j2 - 1, i3, plane) - 1] == 4) + i4 = 0; + if (getTileDecoration(j2, i3 - 1, plane) > 0 && GameData.tileType[getTileDecoration(j2, i3 - 1, plane) - 1] == 4) + i4 = 0; + if (getTileDecoration(j2 - 1, i3 - 1, plane) > 0 && GameData.tileType[getTileDecoration(j2 - 1, i3 - 1, plane) - 1] == 4) + i4 = 0; + int j5 = gameModel.vertexAt(j2 * anInt585, i4, i3 * anInt585); + int j7 = (int) (Math.random() * 10D) - 5; + gameModel.setVertexAmbience(j5, j7); + } + + } + + for (int lx = 0; lx < 95; lx++) { + for (int ly = 0; ly < 95; ly++) { + int colourindex = getTerrainColour(lx, ly); + int colour = terrainColours[colourindex]; + int colour_1 = colour; + int colour_2 = colour; + int l14 = 0; + if (plane == 1 || plane == 2) { + colour = colourTransparent; + colour_1 = colourTransparent; + colour_2 = colourTransparent; + } + if (getTileDecoration(lx, ly, plane) > 0) { + int decoration_type = getTileDecoration(lx, ly, plane); + int decoration_tile_type = GameData.tileType[decoration_type - 1]; + int tile_type = getTileType(lx, ly, plane); + colour = colour_1 = GameData.tileDecoration[decoration_type - 1]; + if (decoration_tile_type == 4) { + colour = 1; + colour_1 = 1; + if (decoration_type == 12) { + colour = 31; + colour_1 = 31; + } + } + if (decoration_tile_type == 5) { + if (getWallDiagonal(lx, ly) > 0 && getWallDiagonal(lx, ly) < 24000) + if (getTileDecoration(lx - 1, ly, plane, colour_2) != colourTransparent && getTileDecoration(lx, ly - 1, plane, colour_2) != colourTransparent) { + colour = getTileDecoration(lx - 1, ly, plane, colour_2); + l14 = 0; + } else if (getTileDecoration(lx + 1, ly, plane, colour_2) != colourTransparent && getTileDecoration(lx, ly + 1, plane, colour_2) != colourTransparent) { + colour_1 = getTileDecoration(lx + 1, ly, plane, colour_2); + l14 = 0; + } else if (getTileDecoration(lx + 1, ly, plane, colour_2) != colourTransparent && getTileDecoration(lx, ly - 1, plane, colour_2) != colourTransparent) { + colour_1 = getTileDecoration(lx + 1, ly, plane, colour_2); + l14 = 1; + } else if (getTileDecoration(lx - 1, ly, plane, colour_2) != colourTransparent && getTileDecoration(lx, ly + 1, plane, colour_2) != colourTransparent) { + colour = getTileDecoration(lx - 1, ly, plane, colour_2); + l14 = 1; + } + } else if (decoration_tile_type != 2 || getWallDiagonal(lx, ly) > 0 && getWallDiagonal(lx, ly) < 24000) + if (getTileType(lx - 1, ly, plane) != tile_type && getTileType(lx, ly - 1, plane) != tile_type) { + colour = colour_2; + l14 = 0; + } else if (getTileType(lx + 1, ly, plane) != tile_type && getTileType(lx, ly + 1, plane) != tile_type) { + colour_1 = colour_2; + l14 = 0; + } else if (getTileType(lx + 1, ly, plane) != tile_type && getTileType(lx, ly - 1, plane) != tile_type) { + colour_1 = colour_2; + l14 = 1; + } else if (getTileType(lx - 1, ly, plane) != tile_type && getTileType(lx, ly + 1, plane) != tile_type) { + colour = colour_2; + l14 = 1; + } + if (GameData.tileAdjacent[decoration_type - 1] != 0) + objectAdjacency[lx][ly] |= 0x40; + if (GameData.tileType[decoration_type - 1] == 2) + objectAdjacency[lx][ly] |= 0x80; + } + method402(lx, ly, l14, colour, colour_1); + int i17 = ((getTerrainHeight(lx + 1, ly + 1) - getTerrainHeight(lx + 1, ly)) + getTerrainHeight(lx, ly + 1)) - getTerrainHeight(lx, ly); + if (colour != colour_1 || i17 != 0) { + int ai[] = new int[3]; + int ai7[] = new int[3]; + if (l14 == 0) { + if (colour != colourTransparent) { + ai[0] = ly + lx * 96 + 96; + ai[1] = ly + lx * 96; + ai[2] = ly + lx * 96 + 1; + int l21 = gameModel.createFace(3, ai, colourTransparent, colour); + localX[l21] = lx; + localY[l21] = ly; + gameModel.faceTag[l21] = 0x30d40 + l21; + } + if (colour_1 != colourTransparent) { + ai7[0] = ly + lx * 96 + 1; + ai7[1] = ly + lx * 96 + 96 + 1; + ai7[2] = ly + lx * 96 + 96; + int i22 = gameModel.createFace(3, ai7, colourTransparent, colour_1); + localX[i22] = lx; + localY[i22] = ly; + gameModel.faceTag[i22] = 0x30d40 + i22; + } + } else { + if (colour != colourTransparent) { + ai[0] = ly + lx * 96 + 1; + ai[1] = ly + lx * 96 + 96 + 1; + ai[2] = ly + lx * 96; + int j22 = gameModel.createFace(3, ai, colourTransparent, colour); + localX[j22] = lx; + localY[j22] = ly; + gameModel.faceTag[j22] = 0x30d40 + j22; + } + if (colour_1 != colourTransparent) { + ai7[0] = ly + lx * 96 + 96; + ai7[1] = ly + lx * 96; + ai7[2] = ly + lx * 96 + 96 + 1; + int k22 = gameModel.createFace(3, ai7, colourTransparent, colour_1); + localX[k22] = lx; + localY[k22] = ly; + gameModel.faceTag[k22] = 0x30d40 + k22; + } + } + } else if (colour != colourTransparent) { + int ai1[] = new int[4]; + ai1[0] = ly + lx * 96 + 96; + ai1[1] = ly + lx * 96; + ai1[2] = ly + lx * 96 + 1; + ai1[3] = ly + lx * 96 + 96 + 1; + int l19 = gameModel.createFace(4, ai1, colourTransparent, colour); + localX[l19] = lx; + localY[l19] = ly; + gameModel.faceTag[l19] = 0x30d40 + l19; + } + } + + } + + for (int k4 = 1; k4 < 95; k4++) { + for (int i6 = 1; i6 < 95; i6++) + if (getTileDecoration(k4, i6, plane) > 0 && GameData.tileType[getTileDecoration(k4, i6, plane) - 1] == 4) { + int l7 = GameData.tileDecoration[getTileDecoration(k4, i6, plane) - 1]; + int j10 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6), i6 * anInt585); + int l12 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6), i6 * anInt585); + int i15 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6 + 1), (i6 + 1) * anInt585); + int j17 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6 + 1), (i6 + 1) * anInt585); + int ai2[] = { + j10, l12, i15, j17 + }; + int i20 = gameModel.createFace(4, ai2, l7, colourTransparent); + localX[i20] = k4; + localY[i20] = i6; + gameModel.faceTag[i20] = 0x30d40 + i20; + method402(k4, i6, 0, l7, l7); + } else if (getTileDecoration(k4, i6, plane) == 0 || GameData.tileType[getTileDecoration(k4, i6, plane) - 1] != 3) { + if (getTileDecoration(k4, i6 + 1, plane) > 0 && GameData.tileType[getTileDecoration(k4, i6 + 1, plane) - 1] == 4) { + int i8 = GameData.tileDecoration[getTileDecoration(k4, i6 + 1, plane) - 1]; + int k10 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6), i6 * anInt585); + int i13 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6), i6 * anInt585); + int j15 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6 + 1), (i6 + 1) * anInt585); + int k17 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6 + 1), (i6 + 1) * anInt585); + int ai3[] = { + k10, i13, j15, k17 + }; + int j20 = gameModel.createFace(4, ai3, i8, colourTransparent); + localX[j20] = k4; + localY[j20] = i6; + gameModel.faceTag[j20] = 0x30d40 + j20; + method402(k4, i6, 0, i8, i8); + } + if (getTileDecoration(k4, i6 - 1, plane) > 0 && GameData.tileType[getTileDecoration(k4, i6 - 1, plane) - 1] == 4) { + int j8 = GameData.tileDecoration[getTileDecoration(k4, i6 - 1, plane) - 1]; + int l10 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6), i6 * anInt585); + int j13 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6), i6 * anInt585); + int k15 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6 + 1), (i6 + 1) * anInt585); + int l17 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6 + 1), (i6 + 1) * anInt585); + int ai4[] = { + l10, j13, k15, l17 + }; + int k20 = gameModel.createFace(4, ai4, j8, colourTransparent); + localX[k20] = k4; + localY[k20] = i6; + gameModel.faceTag[k20] = 0x30d40 + k20; + method402(k4, i6, 0, j8, j8); + } + if (getTileDecoration(k4 + 1, i6, plane) > 0 && GameData.tileType[getTileDecoration(k4 + 1, i6, plane) - 1] == 4) { + int k8 = GameData.tileDecoration[getTileDecoration(k4 + 1, i6, plane) - 1]; + int i11 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6), i6 * anInt585); + int k13 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6), i6 * anInt585); + int l15 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6 + 1), (i6 + 1) * anInt585); + int i18 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6 + 1), (i6 + 1) * anInt585); + int ai5[] = { + i11, k13, l15, i18 + }; + int l20 = gameModel.createFace(4, ai5, k8, colourTransparent); + localX[l20] = k4; + localY[l20] = i6; + gameModel.faceTag[l20] = 0x30d40 + l20; + method402(k4, i6, 0, k8, k8); + } + if (getTileDecoration(k4 - 1, i6, plane) > 0 && GameData.tileType[getTileDecoration(k4 - 1, i6, plane) - 1] == 4) { + int l8 = GameData.tileDecoration[getTileDecoration(k4 - 1, i6, plane) - 1]; + int j11 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6), i6 * anInt585); + int l13 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6), i6 * anInt585); + int i16 = gameModel.vertexAt((k4 + 1) * anInt585, -getTerrainHeight(k4 + 1, i6 + 1), (i6 + 1) * anInt585); + int j18 = gameModel.vertexAt(k4 * anInt585, -getTerrainHeight(k4, i6 + 1), (i6 + 1) * anInt585); + int ai6[] = { + j11, l13, i16, j18 + }; + int i21 = gameModel.createFace(4, ai6, l8, colourTransparent); + localX[i21] = k4; + localY[i21] = i6; + gameModel.faceTag[i21] = 0x30d40 + i21; + method402(k4, i6, 0, l8, l8); + } + } + + } + + gameModel.setLight(true, 40, 48, -50, -10, -50); + terrainModels = parentModel.split(0, 0, 1536, 1536, 8, 64, 233, false); + for (int j6 = 0; j6 < 64; j6++) + scene.addModel(terrainModels[j6]); + + for (int X = 0; X < regionWidth; X++) { + for (int Y = 0; Y < regionHeight; Y++) + terrainHeightLocal[X][Y] = getTerrainHeight(X, Y); + + } + + } + parentModel.clear(); + int k1 = 0x606060; + for (int i2 = 0; i2 < 95; i2++) { + for (int k2 = 0; k2 < 95; k2++) { + int k3 = getWallEastwest(i2, k2); + if (k3 > 0 && (GameData.wallObjectInvisible[k3 - 1] == 0 || aBoolean592)) { + method422(parentModel, k3 - 1, i2, k2, i2 + 1, k2); + if (flag && GameData.wallObjectAdjacent[k3 - 1] != 0) { + objectAdjacency[i2][k2] |= 1; + if (k2 > 0) + setObjectAdjacency(i2, k2 - 1, 4); + } + if (flag) + surface.drawLineHoriz(i2 * 3, k2 * 3, 3, k1); + } + k3 = getWallNorthsouth(i2, k2); + if (k3 > 0 && (GameData.wallObjectInvisible[k3 - 1] == 0 || aBoolean592)) { + method422(parentModel, k3 - 1, i2, k2, i2, k2 + 1); + if (flag && GameData.wallObjectAdjacent[k3 - 1] != 0) { + objectAdjacency[i2][k2] |= 2; + if (i2 > 0) + setObjectAdjacency(i2 - 1, k2, 8); + } + if (flag) + surface.drawLineVert(i2 * 3, k2 * 3, 3, k1); + } + k3 = getWallDiagonal(i2, k2); + if (k3 > 0 && k3 < 12000 && (GameData.wallObjectInvisible[k3 - 1] == 0 || aBoolean592)) { + method422(parentModel, k3 - 1, i2, k2, i2 + 1, k2 + 1); + if (flag && GameData.wallObjectAdjacent[k3 - 1] != 0) + objectAdjacency[i2][k2] |= 0x20; + if (flag) { + surface.setPixel(i2 * 3, k2 * 3, k1); + surface.setPixel(i2 * 3 + 1, k2 * 3 + 1, k1); + surface.setPixel(i2 * 3 + 2, k2 * 3 + 2, k1); + } + } + if (k3 > 12000 && k3 < 24000 && (GameData.wallObjectInvisible[k3 - 12001] == 0 || aBoolean592)) { + method422(parentModel, k3 - 12001, i2 + 1, k2, i2, k2 + 1); + if (flag && GameData.wallObjectAdjacent[k3 - 12001] != 0) + objectAdjacency[i2][k2] |= 0x10; + if (flag) { + surface.setPixel(i2 * 3 + 2, k2 * 3, k1); + surface.setPixel(i2 * 3 + 1, k2 * 3 + 1, k1); + surface.setPixel(i2 * 3, k2 * 3 + 2, k1); + } + } + } + + } + + if (flag) + surface.drawSpriteMinimap(baseMediaSprite - 1, 0, 0, 285, 285); + parentModel.setLight(false, 60, 24, -50, -10, -50); + wallModels[plane] = parentModel.split(0, 0, 1536, 1536, 8, 64, 338, true); + for (int l2 = 0; l2 < 64; l2++) + scene.addModel(wallModels[plane][l2]); + + for (int l3 = 0; l3 < 95; l3++) { + for (int l4 = 0; l4 < 95; l4++) { + int k6 = getWallEastwest(l3, l4); + if (k6 > 0) + method428(k6 - 1, l3, l4, l3 + 1, l4); + k6 = getWallNorthsouth(l3, l4); + if (k6 > 0) + method428(k6 - 1, l3, l4, l3, l4 + 1); + k6 = getWallDiagonal(l3, l4); + if (k6 > 0 && k6 < 12000) + method428(k6 - 1, l3, l4, l3 + 1, l4 + 1); + if (k6 > 12000 && k6 < 24000) + method428(k6 - 12001, l3 + 1, l4, l3, l4 + 1); + } + + } + + for (int i5 = 1; i5 < 95; i5++) { + for (int l6 = 1; l6 < 95; l6++) { + int j9 = getWallRoof(i5, l6); + if (j9 > 0) { + int l11 = i5; + int i14 = l6; + int j16 = i5 + 1; + int k18 = l6; + int j19 = i5 + 1; + int j21 = l6 + 1; + int l22 = i5; + int j23 = l6 + 1; + int l23 = 0; + int j24 = terrainHeightLocal[l11][i14]; + int l24 = terrainHeightLocal[j16][k18]; + int j25 = terrainHeightLocal[j19][j21]; + int l25 = terrainHeightLocal[l22][j23]; + if (j24 > 0x13880) + j24 -= 0x13880; + if (l24 > 0x13880) + l24 -= 0x13880; + if (j25 > 0x13880) + j25 -= 0x13880; + if (l25 > 0x13880) + l25 -= 0x13880; + if (j24 > l23) + l23 = j24; + if (l24 > l23) + l23 = l24; + if (j25 > l23) + l23 = j25; + if (l25 > l23) + l23 = l25; + if (l23 >= 0x13880) + l23 -= 0x13880; + if (j24 < 0x13880) + terrainHeightLocal[l11][i14] = l23; + else + terrainHeightLocal[l11][i14] -= 0x13880; + if (l24 < 0x13880) + terrainHeightLocal[j16][k18] = l23; + else + terrainHeightLocal[j16][k18] -= 0x13880; + if (j25 < 0x13880) + terrainHeightLocal[j19][j21] = l23; + else + terrainHeightLocal[j19][j21] -= 0x13880; + if (l25 < 0x13880) + terrainHeightLocal[l22][j23] = l23; + else + terrainHeightLocal[l22][j23] -= 0x13880; + } + } + + } + + parentModel.clear(); + for (int i7 = 1; i7 < 95; i7++) { + for (int k9 = 1; k9 < 95; k9++) { + int roof_nvs = getWallRoof(i7, k9); + if (roof_nvs > 0) { + int j14 = i7; + int k16 = k9; + int l18 = i7 + 1; + int k19 = k9; + int k21 = i7 + 1; + int i23 = k9 + 1; + int k23 = i7; + int i24 = k9 + 1; + int k24 = i7 * anInt585; + int i25 = k9 * anInt585; + int k25 = k24 + anInt585; + int i26 = i25 + anInt585; + int j26 = k24; + int k26 = i25; + int l26 = k25; + int i27 = i26; + int j27 = terrainHeightLocal[j14][k16]; + int k27 = terrainHeightLocal[l18][k19]; + int l27 = terrainHeightLocal[k21][i23]; + int i28 = terrainHeightLocal[k23][i24]; + int unknown = GameData.roofHeight[roof_nvs - 1]; + if (hasRoof(j14, k16) && j27 < 0x13880) { + j27 += unknown + 0x13880; + terrainHeightLocal[j14][k16] = j27; + } + if (hasRoof(l18, k19) && k27 < 0x13880) { + k27 += unknown + 0x13880; + terrainHeightLocal[l18][k19] = k27; + } + if (hasRoof(k21, i23) && l27 < 0x13880) { + l27 += unknown + 0x13880; + terrainHeightLocal[k21][i23] = l27; + } + if (hasRoof(k23, i24) && i28 < 0x13880) { + i28 += unknown + 0x13880; + terrainHeightLocal[k23][i24] = i28; + } + if (j27 >= 0x13880) + j27 -= 0x13880; + if (k27 >= 0x13880) + k27 -= 0x13880; + if (l27 >= 0x13880) + l27 -= 0x13880; + if (i28 >= 0x13880) + i28 -= 0x13880; + byte byte0 = 16; + if (!method427(j14 - 1, k16)) + k24 -= byte0; + if (!method427(j14 + 1, k16)) + k24 += byte0; + if (!method427(j14, k16 - 1)) + i25 -= byte0; + if (!method427(j14, k16 + 1)) + i25 += byte0; + if (!method427(l18 - 1, k19)) + k25 -= byte0; + if (!method427(l18 + 1, k19)) + k25 += byte0; + if (!method427(l18, k19 - 1)) + k26 -= byte0; + if (!method427(l18, k19 + 1)) + k26 += byte0; + if (!method427(k21 - 1, i23)) + l26 -= byte0; + if (!method427(k21 + 1, i23)) + l26 += byte0; + if (!method427(k21, i23 - 1)) + i26 -= byte0; + if (!method427(k21, i23 + 1)) + i26 += byte0; + if (!method427(k23 - 1, i24)) + j26 -= byte0; + if (!method427(k23 + 1, i24)) + j26 += byte0; + if (!method427(k23, i24 - 1)) + i27 -= byte0; + if (!method427(k23, i24 + 1)) + i27 += byte0; + roof_nvs = GameData.roofNumVertices[roof_nvs - 1]; + j27 = -j27; + k27 = -k27; + l27 = -l27; + i28 = -i28; + if (getWallDiagonal(i7, k9) > 12000 && getWallDiagonal(i7, k9) < 24000 && getWallRoof(i7 - 1, k9 - 1) == 0) { + int ai8[] = new int[3]; + ai8[0] = parentModel.vertexAt(l26, l27, i26); + ai8[1] = parentModel.vertexAt(j26, i28, i27); + ai8[2] = parentModel.vertexAt(k25, k27, k26); + parentModel.createFace(3, ai8, roof_nvs, colourTransparent); + } else if (getWallDiagonal(i7, k9) > 12000 && getWallDiagonal(i7, k9) < 24000 && getWallRoof(i7 + 1, k9 + 1) == 0) { + int ai9[] = new int[3]; + ai9[0] = parentModel.vertexAt(k24, j27, i25); + ai9[1] = parentModel.vertexAt(k25, k27, k26); + ai9[2] = parentModel.vertexAt(j26, i28, i27); + parentModel.createFace(3, ai9, roof_nvs, colourTransparent); + } else if (getWallDiagonal(i7, k9) > 0 && getWallDiagonal(i7, k9) < 12000 && getWallRoof(i7 + 1, k9 - 1) == 0) { + int ai10[] = new int[3]; + ai10[0] = parentModel.vertexAt(j26, i28, i27); + ai10[1] = parentModel.vertexAt(k24, j27, i25); + ai10[2] = parentModel.vertexAt(l26, l27, i26); + parentModel.createFace(3, ai10, roof_nvs, colourTransparent); + } else if (getWallDiagonal(i7, k9) > 0 && getWallDiagonal(i7, k9) < 12000 && getWallRoof(i7 - 1, k9 + 1) == 0) { + int ai11[] = new int[3]; + ai11[0] = parentModel.vertexAt(k25, k27, k26); + ai11[1] = parentModel.vertexAt(l26, l27, i26); + ai11[2] = parentModel.vertexAt(k24, j27, i25); + parentModel.createFace(3, ai11, roof_nvs, colourTransparent); + } else if (j27 == k27 && l27 == i28) { + int ai12[] = new int[4]; + ai12[0] = parentModel.vertexAt(k24, j27, i25); + ai12[1] = parentModel.vertexAt(k25, k27, k26); + ai12[2] = parentModel.vertexAt(l26, l27, i26); + ai12[3] = parentModel.vertexAt(j26, i28, i27); + parentModel.createFace(4, ai12, roof_nvs, colourTransparent); + } else if (j27 == i28 && k27 == l27) { + int ai13[] = new int[4]; + ai13[0] = parentModel.vertexAt(j26, i28, i27); + ai13[1] = parentModel.vertexAt(k24, j27, i25); + ai13[2] = parentModel.vertexAt(k25, k27, k26); + ai13[3] = parentModel.vertexAt(l26, l27, i26); + parentModel.createFace(4, ai13, roof_nvs, colourTransparent); + } else { + boolean flag1 = true; + if (getWallRoof(i7 - 1, k9 - 1) > 0) + flag1 = false; + if (getWallRoof(i7 + 1, k9 + 1) > 0) + flag1 = false; + if (!flag1) { + int ai14[] = new int[3]; + ai14[0] = parentModel.vertexAt(k25, k27, k26); + ai14[1] = parentModel.vertexAt(l26, l27, i26); + ai14[2] = parentModel.vertexAt(k24, j27, i25); + parentModel.createFace(3, ai14, roof_nvs, colourTransparent); + int ai16[] = new int[3]; + ai16[0] = parentModel.vertexAt(j26, i28, i27); + ai16[1] = parentModel.vertexAt(k24, j27, i25); + ai16[2] = parentModel.vertexAt(l26, l27, i26); + parentModel.createFace(3, ai16, roof_nvs, colourTransparent); + } else { + int ai15[] = new int[3]; + ai15[0] = parentModel.vertexAt(k24, j27, i25); + ai15[1] = parentModel.vertexAt(k25, k27, k26); + ai15[2] = parentModel.vertexAt(j26, i28, i27); + parentModel.createFace(3, ai15, roof_nvs, colourTransparent); + int ai17[] = new int[3]; + ai17[0] = parentModel.vertexAt(l26, l27, i26); + ai17[1] = parentModel.vertexAt(j26, i28, i27); + ai17[2] = parentModel.vertexAt(k25, k27, k26); + parentModel.createFace(3, ai17, roof_nvs, colourTransparent); + } + } + } + } + + } + + parentModel.setLight(true, 50, 50, -50, -10, -50); + roofModels[plane] = parentModel.split(0, 0, 1536, 1536, 8, 64, 169, true); + for (int l9 = 0; l9 < 64; l9++) + scene.addModel(roofModels[plane][l9]); + + if (roofModels[plane][0] == null) + throw new RuntimeException("null roof!"); + for (int j12 = 0; j12 < regionWidth; j12++) { + for (int k14 = 0; k14 < regionHeight; k14++) + if (terrainHeightLocal[j12][k14] >= 0x13880) + terrainHeightLocal[j12][k14] -= 0x13880; + + } + + } + + public void setObjectAdjacency(int i, int j, int k) { + objectAdjacency[i][j] |= k; + } + + public int getTileType(int i, int j, int k) { + int l = getTileDecoration(i, j, k); + if (l == 0) + return -1; + int i1 = GameData.tileType[l - 1]; + return i1 != 2 ? 0 : 1; + } + + public void addModels(GameModel aclass5[]) { + for (int i = 0; i < 94; i++) { + for (int j = 0; j < 94; j++) + if (getWallDiagonal(i, j) > 48000 && getWallDiagonal(i, j) < 60000) { + int k = getWallDiagonal(i, j) - 48001; + int l = getTileDirection(i, j); + int i1; + int j1; + if (l == 0 || l == 4) { + i1 = GameData.objectWidth[k]; + j1 = GameData.objectHeight[k]; + } else { + j1 = GameData.objectWidth[k]; + i1 = GameData.objectHeight[k]; + } + removeObject2(i, j, k); + GameModel gameModel = aclass5[GameData.objectModelIndex[k]].copy(false, true, false, false); + int k1 = ((i + i + i1) * anInt585) / 2; + int i2 = ((j + j + j1) * anInt585) / 2; + gameModel.translate(k1, -getElevation(k1, i2), i2); + gameModel.orient(0, getTileDirection(i, j) * 32, 0); + scene.addModel(gameModel); + gameModel.setLight(48, 48, -50, -10, -50); + if (i1 > 1 || j1 > 1) { + for (int k2 = i; k2 < i + i1; k2++) { + for (int l2 = j; l2 < j + j1; l2++) + if ((k2 > i || l2 > j) && getWallDiagonal(k2, l2) - 48001 == k) { + int l1 = k2; + int j2 = l2; + byte byte0 = 0; + if (l1 >= 48 && j2 < 48) { + byte0 = 1; + l1 -= 48; + } else if (l1 < 48 && j2 >= 48) { + byte0 = 2; + j2 -= 48; + } else if (l1 >= 48 && j2 >= 48) { + byte0 = 3; + l1 -= 48; + j2 -= 48; + } + wallsDiagonal[byte0][l1 * 48 + j2] = 0; + } + + } + + } + } + + } + + } + + public void method422(GameModel gameModel, int i, int j, int k, int l, int i1) { + method425(j, k, 40); + method425(l, i1, 40); + int h = GameData.wallObjectHeight[i]; + int front = GameData.wallObjectTextureFront[i]; + int back = GameData.wallObjectTextureBack[i]; + int i2 = j * anInt585; + int j2 = k * anInt585; + int k2 = l * anInt585; + int l2 = i1 * anInt585; + int i3 = gameModel.vertexAt(i2, -terrainHeightLocal[j][k], j2); + int j3 = gameModel.vertexAt(i2, -terrainHeightLocal[j][k] - h, j2); + int k3 = gameModel.vertexAt(k2, -terrainHeightLocal[l][i1] - h, l2); + int l3 = gameModel.vertexAt(k2, -terrainHeightLocal[l][i1], l2); + int ai[] = { + i3, j3, k3, l3 + }; + int i4 = gameModel.createFace(4, ai, front, back); + if (GameData.wallObjectInvisible[i] == 5) { + gameModel.faceTag[i4] = 30000 + i; + return; + } else { + gameModel.faceTag[i4] = 0; + return; + } + } + + public int getTerrainHeight(int x, int y) { + if (x < 0 || x >= regionWidth || y < 0 || y >= regionHeight) + return 0; + byte d = 0; + if (x >= 48 && y < 48) { + d = 1; + x -= 48; + } else if (x < 48 && y >= 48) { + d = 2; + y -= 48; + } else if (x >= 48 && y >= 48) { + d = 3; + x -= 48; + y -= 48; + } + return (terrainHeight[d][x * 48 + y] & 0xff) * 3; + } + + public void loadSection(int x, int y, int plane) { + reset(); + int l = (x + 24) / 48; + int i1 = (y + 24) / 48; + loadSection(x, y, plane, true); + if (plane == 0) { + loadSection(x, y, 1, false); + loadSection(x, y, 2, false); + loadSection(l - 1, i1 - 1, plane, 0); + loadSection(l, i1 - 1, plane, 1); + loadSection(l - 1, i1, plane, 2); + loadSection(l, i1, plane, 3); + setTiles(); + } + } + + public void method425(int i, int j, int k) { + int l = i / 12; + int i1 = j / 12; + int j1 = (i - 1) / 12; + int k1 = (j - 1) / 12; + setTerrainAmbience(l, i1, i, j, k); + if (l != j1) + setTerrainAmbience(j1, i1, i, j, k); + if (i1 != k1) + setTerrainAmbience(l, k1, i, j, k); + if (l != j1 && i1 != k1) + setTerrainAmbience(j1, k1, i, j, k); + } + + public void removeObject(int x, int y, int id) { + if (x < 0 || y < 0 || x >= 95 || y >= 95) + return; + if (GameData.objectType[id] == 1 || GameData.objectType[id] == 2) { + int l = getTileDirection(x, y); + int i1; + int j1; + if (l == 0 || l == 4) { + i1 = GameData.objectWidth[id]; + j1 = GameData.objectHeight[id]; + } else { + j1 = GameData.objectWidth[id]; + i1 = GameData.objectHeight[id]; + } + for (int k1 = x; k1 < x + i1; k1++) { + for (int l1 = y; l1 < y + j1; l1++) + if (GameData.objectType[id] == 1) + objectAdjacency[k1][l1] &= 0xffbf; + else if (l == 0) { + objectAdjacency[k1][l1] &= 0xfffd; + if (k1 > 0) + method407(k1 - 1, l1, 8); + } else if (l == 2) { + objectAdjacency[k1][l1] &= 0xfffb; + if (l1 < 95) + method407(k1, l1 + 1, 1); + } else if (l == 4) { + objectAdjacency[k1][l1] &= 0xfff7; + if (k1 < 95) + method407(k1 + 1, l1, 2); + } else if (l == 6) { + objectAdjacency[k1][l1] &= 0xfffe; + if (l1 > 0) + method407(k1, l1 - 1, 4); + } + + } + + method404(x, y, i1, j1); + } + } + + public boolean method427(int i, int j) { + return getWallRoof(i, j) > 0 || getWallRoof(i - 1, j) > 0 || getWallRoof(i - 1, j - 1) > 0 || getWallRoof(i, j - 1) > 0; + } + + public void method428(int i, int j, int k, int l, int i1) { + int j1 = GameData.wallObjectHeight[i]; + if (terrainHeightLocal[j][k] < 0x13880) + terrainHeightLocal[j][k] += 0x13880 + j1; + if (terrainHeightLocal[l][i1] < 0x13880) + terrainHeightLocal[l][i1] += 0x13880 + j1; + } +} diff --git a/mudclient204-threadless/mudclient.java b/mudclient204-threadless/mudclient.java new file mode 100644 index 0000000..51a2a94 --- /dev/null +++ b/mudclient204-threadless/mudclient.java @@ -0,0 +1,7555 @@ +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.InetAddress; +import java.net.Socket; +import java.net.URL; + +public class mudclient extends GameConnection { + + /** + * Defines the maximum number of items in the right-click context menu. + * + * @see mudclient#menuIndices + * @see mudclient#menuItemX + * @see mudclient#menuItemY + * @see mudclient#menuItemText1 + * @see mudclient#menuSourceType + * @see mudclient#menuSourceIndex + * @see mudclient#menuTargetIndex + * @see mudclient#menuItemID + * @see mudclient#menuItemText2 + */ + private final int menuMaxSize = 250; + private final int pathStepsMax = 8000; + /** + * Defines the maximum number of player characters supported. + * + * @see mudclient#playerServerIndexes + * @see mudclient#players + * @see mudclient#knownPlayers + */ + private final int playersMax = 500; + /** + * Defines thet maximum number of non-player characters supported. + * + * @see mudclient#npcsCache + * @see mudclient#npcs + */ + private final int npcsMax = 500; + /** + * Defines the maximum number of wall objects supported. + * + * @see mudclient#wallObjectDirection + * @see mudclient#wallObjectId + * @see mudclient#wallObjectAlreadyInMenu + * @see mudclient#wallObjectModel + * @see mudclient#wallObjectX + * @see mudclient#wallObjectY + */ + private final int wallObjectsMax = 500; + private final int playersServerMax = 4000; + private final int groundItemsMax = 5000; + private final int npcsServerMax = 5000; + private final int objectsMax = 1500; + /** + * The number of player skills. + * + * @see mudclient#playerStatCurrent + * @see mudclient#playerStatBase + * @see mudclient#playerExperience + */ + private final int playerStatCount = 18; + /** + * The number of quests shown to the player and read from the server + * + * @see mudclient#questComplete + * @see mudclient#questName + */ + private final int questCount = 50;// seems most likely + private final int playerStatEquipmentCount = 5;// not sure, could also be the number of messages shown on the screen + /** + * Represents the players local x coordinate in the current region + *

+ * World coordinate obtained by localRegionX + {@link mudclient#regionX} + */ + int localRegionX; + /** + * @see mudclient#localRegionX + */ + int localRegionY; + /** + * The players index in the server's player array + *

+ * Used to create {@link mudclient#localPlayer}, the player's {@link GameCharacter} reference + */ + int localPlayerServerIndex; + /** + * Handle to the control on the {@link Panel} {@link mudclient#panelMessageTabs} + * for the chat history text list + * + * @see mudclient#messageTabSelected + */ + int controlTextListChat; + /** + * Handle to the control on the {@link Panel} {@link mudclient#panelMessageTabs} + * for all the history text list, as well as the text input + * + * @see mudclient#messageTabSelected + */ + int controlTextListAll; + /** + * Handle to the control on the {@link Panel} {@link mudclient#panelMessageTabs} + * for the quest history text list + * + * @see mudclient#messageTabSelected + */ + int controlTextListQuest; + /** + * Handle to the control on the {@link Panel} {@link mudclient#panelMessageTabs} + * for the private history text list + * + * @see mudclient#messageTabSelected + */ + int controlTextListPrivate; + /** + * Determines which chat history tab is active. + *

+ * Can be 0 through 3 to represent {@link mudclient#controlTextListAll}, {@link mudclient#controlTextListChat}, + * {@link mudclient#controlTextListQuest} or {@link mudclient#controlTextListPrivate} respetively + */ + int messageTabSelected; + /** + * Stores the x screen coordinate history of our mouse clicks. Only used in + * {@link mudclient#handleMouseDown(int, int, int)} to call {@link mudclient#sendLogout} + * if we've been clicking on the same place for a while (presumably to stop dumb powerminers + */ + int mouseClickXHistory[]; + /** + * @see mudclient#mouseClickXHistory + */ + int mouseClickYHistory[]; + /** + * Holds the message for messages the player has received that are to be shown above players or npcs heads + */ + String receivedMessages[]; + /** + * The screen x coordinate to draw the little x that comes up when the screen has been clicked + */ + int mouseClickXX; + /** + * @see mudclient#mouseClickXX + */ + int mouseClickXY; + /** + * Handle to the control on the {@link Panel} {@link mudclient#panelSocialList} + * to list friends or ignores based on {@link mudclient#uiTabSocialSubTab}. + *

+ * Shown when moused over the smiley face ui tab which sets {@link mudclient#showUiTab} = 5 + * + * @see mudclient#messageTabSelected + */ + int controlListSocialPlayers; + /** + * Which sub tab is selected on the {@link Panel} {@link mudclient#panelSocialList} + * 0 for friends, 1 for ignore + *

+ * Affects the list shown in {@link mudclient#controlListSocialPlayers} + */ + int uiTabSocialSubTab; + /** + * The hash of the target for the private message box. Set when clicked on an entry in the friend list and + * {@link mudclient#showDialogSocialInput} = 2 + * + * @see mudclient #controlListSocialPlayers + */ + long privateMessageTarget; + /** + * The name of the item selected from the inventory and ready to be used on something + */ + String selectedItemName; + /** + * Handle to the control on the {@link Panel} {@link mudclient#panelQuestList} + * to list stats or quests based on {@link mudclient#uiTabPlayerInfoSubTab}. + *

+ * Shown when moused over the chart ui tab which sets {@link mudclient#showUiTab} = 3 + * + * @see mudclient#messageTabSelected + */ + int controlListQuest; + /** + * Which sub tab is selected on the player info ui tab + * 0 for player stats, 1 for {@link mudclient#controlListQuest} + */ + int uiTabPlayerInfoSubTab; + int controlListMagic; + int tabMagicPrayer; + private int packetErrorCount; + private int menuIndices[]; + private boolean cameraAutoAngleDebug; + private int mouseButtonDownTime; + private int mouseButtonItemCountIncrement; + private int wallObjectDirection[]; + private int wallObjectId[]; + private int anInt659; + private int anInt660; + private int cameraRotationX; + private int cameraRotationXIncrement; + private Scene scene; + private int inventoryMaxItemCount; + private int bankItemsMax; + private String optionMenuEntry[]; + private int newBankItems[]; + private int newBankItemsCount[]; + private int showDialogReportAbuseStep; + private int loginScreen; + private int teleportBubbleTime[]; + private boolean showDialogTradeConfirm; + private boolean tradeConfirmAccepted; + private int receivedMessageX[]; + private int receivedMessageY[]; + private int receivedMessageMidPoint[]; + private int receivedMessageHeight[]; + private GameCharacter localPlayer; + private SurfaceSprite surface; + + /** + * The Panel instance for messaging tabs. + */ + private Panel panelMessageTabs; + + private int menuItemX[]; + private int menuItemY[]; + private boolean showDialogTrade; + private int bankItems[]; + private int bankItemsCount[]; + private StreamAudioPlayer audioPlayer; + private int appearanceHeadType; + private int appearanceBodyGender; + private int appearance2Colour; + private int appearanceHairColour; + private int appearanceTopColour; + private int appearanceBottomColour; + private int appearanceSkinColour; + private int appearanceHeadGender; + private String loginUser; + private String loginPass; + private int showDialogSocialInput; + private int cameraAngle; + private int anInt707; + private boolean members; + private int deathScreenTimeout; + private boolean optionSoundDisabled; + private boolean showRightClickMenu; + private int cameraRotationY; + private int cameraRotationYIncrement; + private boolean objectAlreadyInMenu[]; + private int combatStyle; + private String menuItemText1[]; + private int welcomeUnreadMessages; + private int controlButtonAppearanceHead1; + private int controlButtonAppearanceHead2; + private int controlButtonAppearanceHair1; + private int controlButtonAppearanceHair2; + private int controlButtonAppearanceGender1; + private int controlButtonAppearanceGender2; + private int controlButtonAppearanceTop1; + private int controlButtonAppearanceTop2; + private int controlButtonAppearanceSkin1; + private int controlButtonAppearanceSkin2; + private int controlButtonAppearanceBottom1; + private int controlButtonAppearanceBottom2; + private int controlButtonAppearanceAccept; + private int logoutTimeout; + private long tradeRecipientConfirmHash; + private int loginTimer; + private int npcCombatModelArray2[] = { + 0, 0, 0, 0, 0, 1, 2, 1 + }; + private int systemUpdate; + private String duelOpponentName; + private int lastObjectAnimationNumberFireLightningSpell; + private int lastObjectAnimationNumberTorch; + private int lastOjectAnimationNumberClaw; + //private Graphics graphics; + private int regionX; + private int regionY; + private int planeIndex; + //private String aString744;// unused + private boolean welcomScreenAlreadyShown; + private int mouseButtonClick; + private boolean isSleeping; + private int cameraRotation; + private String questName[] = { + "Black knight's fortress", "Cook's assistant", "Demon slayer", "Doric's quest", "The restless ghost", "Goblin diplomacy", "Ernest the chicken", "Imp catcher", "Pirate's treasure", "Prince Ali rescue", + "Romeo & Juliet", "Sheep shearer", "Shield of Arrav", "The knight's sword", "Vampire slayer", "Witch's potion", "Dragon slayer", "Witch's house (members)", "Lost city (members)", "Hero's quest (members)", + "Druidic ritual (members)", "Merlin's crystal (members)", "Scorpion catcher (members)", "Family crest (members)", "Tribal totem (members)", "Fishing contest (members)", "Monk's friend (members)", "Temple of Ikov (members)", "Clock tower (members)", "The Holy Grail (members)", + "Fight Arena (members)", "Tree Gnome Village (members)", "The Hazeel Cult (members)", "Sheep Herder (members)", "Plague City (members)", "Sea Slug (members)", "Waterfall quest (members)", "Biohazard (members)", "Jungle potion (members)", "Grand tree (members)", + "Shilo village (members)", "Underground pass (members)", "Observatory quest (members)", "Tourist trap (members)", "Watchtower (members)", "Dwarf Cannon (members)", "Murder Mystery (members)", "Digsite (members)", "Gertrude's Cat (members)", "Legend's Quest (members)" + }; + private int teleportBubbleX[]; + private boolean errorLoadingData; + private int playerExperience[]; + private int healthBarCount; + private int spriteMedia; + private int spriteUtil; + private int spriteItem; + private int spriteProjectile; + private int spriteTexture; + private int spriteTextureWorld; + private int spriteLogo; + private int controlLoginStatus; + private int controlLoginUser; + private int controlLoginPass; + private int controlLoginOk; + private int controlLoginCancel; + private boolean tradeRecipientAccepted; + private boolean tradeAccepted; + private int teleportBubbleCount; + private int mouseClickCount; + private int shopSellPriceMod; + private int shopBuyPriceMod; + private boolean showDialogWelcome; + private int duelOptionRetreat; + private int duelOptionMagic; + private int duelOptionPrayer; + private int duelOptionWeapons; + private int playerServerIndexes[]; + private int groundItemCount; + private int teleportBubbleY[]; + private int receivedMessagesCount; + private int messageTabFlashAll; + private int messageTabFlashHistory; + private int messtageTabFlashQuest; + private int messageTabFlashPrivate; + private boolean showDialogDuelConfirm; + private boolean duelAccepted; + private GameCharacter players[]; + private int bankItemCount; + private boolean prayerOn[]; + //private String aString793;// unused + private int menuSourceType[]; + private int menuSourceIndex[]; + private int menuTargetIndex[]; + private boolean wallObjectAlreadyInMenu[]; + private int objectAnimationNumberFireLightningSpell; + private int objectAnimationNumberTorch; + private int objectAnimationNumberClaw; + private int magicLoc; + private int loggedIn; + private int npcCount; + private int npcCacheCount; + private int objectAnimationCount; + private boolean errorLoadingMemory; + private boolean fogOfWar; + private int gameWidth; + private int gameHeight; + private int const_9; + private int tradeConfirmItemsCount; + private int tradeConfirmItems[]; + private int tradeConfirmItemCount[]; + private String tradeRecipientName; + private int selectedSpell; + private boolean showOptionMenu; + private int mouseClickXStep; + private int newBankItemCount; + private int npcAnimationArray[][] = { + { + 11, 2, 9, 7, 1, 6, 10, 0, 5, 8, + 3, 4 + }, { + 11, 2, 9, 7, 1, 6, 10, 0, 5, 8, + 3, 4 + }, { + 11, 3, 2, 9, 7, 1, 6, 10, 0, 5, + 8, 4 + }, { + 3, 4, 2, 9, 7, 1, 6, 10, 8, 11, + 0, 5 + }, { + 3, 4, 2, 9, 7, 1, 6, 10, 8, 11, + 0, 5 + }, { + 4, 3, 2, 9, 7, 1, 6, 10, 8, 11, + 0, 5 + }, { + 11, 4, 2, 9, 7, 1, 6, 10, 0, 5, + 8, 3 + }, { + 11, 2, 9, 7, 1, 6, 10, 0, 5, 8, + 4, 3 + } + }; + private int playerStatCurrent[]; + private int controlWelcomeNewuser; + private int controlWelcomeExistinguser; + private int npcWalkModel[] = { + 0, 1, 2, 1 + }; + private int referid; + private int anInt827; + private int controlLoginNewOk; + private int teleportBubbleType[]; + private Panel panelLoginWelcome; + private int combatTimeout; + private Panel panelLoginNewuser; + private int optionMenuCount; + private boolean errorLoadingCodebase; + private boolean showDialogShop; + private int shopItem[]; + private int shopItemCount[]; + private int shopItemPrice[]; + private boolean duelOfferOpponentAccepted; + private boolean duelOfferAccepted; + private GameModel gameModels[]; + private int reportAbuseOffence; + private boolean showDialogDuel; + private String serverMessage; + private boolean serverMessageBoxTop; + private int cameraRotationTime; + private int duelOpponentItemsCount; + private int duelOpponentItems[]; + private int duelOpponentItemCount[]; + private int duelItemsCount; + private int duelItems[]; + private int duelItemCount[]; + private Panel panelSocialList; + private int playerStatBase[]; + private GameCharacter npcsCache[]; + private boolean appletMode; + private int characterSkinColours[] = { + 0xecded0, 0xccb366, 0xb38c40, 0x997326, 0x906020 + }; + private int groundItemX[]; + private int groundItemY[]; + private int groundItemId[]; + private int groundItemZ[]; + private int bankSelectedItemSlot; + private int bankSelectedItem; + private int duelOfferOpponentItemCount; + private int duelOfferOpponentItemId[]; + private int duelOfferOpponentItemStack[]; + private int messageHistoryTimeout[]; + private boolean optionCameraModeAuto; + private int objectX[]; + private int objectY[]; + private int objectId[]; + private int objectDirection[]; + private int characterTopBottomColours[] = { + 0xff0000, 0xff8000, 0xffe000, 0xa0e000, 57344, 32768, 41088, 45311, 33023, 12528, + 0xe000e0, 0x303030, 0x604000, 0x805000, 0xffffff + }; + private int itemsAboveHeadCount; + private int showUiWildWarn; + private int selectedItemInventoryIndex; + private byte soundData[]; + private int statFatigue; + private int fatigueSleeping; + private boolean loadingArea; + private int tradeRecipientConfirmItemsCount; + private int tradeRecipientConfirmItems[]; + private int tradeRecipientConfirmItemCount[]; + private int tradeRecipientItemsCount; + private int tradeRecipientItems[]; + private int tradeRecipientItemCount[]; + private boolean showDialogServermessage; + private int menuItemID[]; + private boolean questComplete[]; + private GameModel wallObjectModel[]; + private int menuX; + private int menuY; + private int menuWidth; + private int menuHeight; + private int menuItemsCount; + private int actionBubbleX[]; + private int actionBubbleY[]; + private Panel panelQuestList; + private int cameraZoom; + private Panel panelMagic; + private int showUiTab; + private int tradeItemsCount; + private int tradeItems[]; + private int tradeItemCount[]; + private int planeWidth; + private int planeHeight; + private int planeMultiplier; + private int lastHeightOffset; + //private int anInt917;// unused + private boolean duelSettingsRetreat; + private boolean duelSettingsMagic; + private boolean duelSettingsPrayer; + private boolean duelSettingsWeapons; + private boolean showDialogBank; + private int playerQuestPoints; + private String loginUserDesc; + private String loginUserDisp; + private int characterHairColours[] = { + 0xffc030, 0xffa040, 0x805030, 0x604020, 0x303030, 0xff6020, 0xff4000, 0xffffff, 65280, 65535 + }; + private int bankActivePage; + private int welcomeLastLoggedInDays; + private String equipmentStatNames[] = { + "Armour", "WeaponAim", "WeaponPower", "Magic", "Prayer" + }; + private boolean optionMouseButtonOne; + private int inventoryItemsCount; + private int inventoryItemId[]; + private int inventoryItemStackCount[]; + private int inventoryEquipped[]; + private String skillNameShort[] = { + "Attack", "Defense", "Strength", "Hits", "Ranged", "Prayer", "Magic", "Cooking", "Woodcut", "Fletching", + "Fishing", "Firemaking", "Crafting", "Smithing", "Mining", "Herblaw", "Agility", "Thieving" + }; + private GameCharacter knownPlayers[]; + private String messageHistory[]; + private long duelOpponentNameHash; + private Panel panelAppearance; + private int minimapRandom_1; + private int minimapRandom_2; + private Panel panelLoginExistinguser; + private boolean reportAbuseMute; + private int objectCount; + private int duelOfferItemCount; + private int duelOfferItemId[]; + private int duelOfferItemStack[]; + private int cameraAutoRotatePlayerX; + private int cameraAutoRotatePlayerY; + private int actionBubbleScale[]; + private int actionBubbleItem[]; + private boolean sleepWordDelay; + private boolean showAppearanceChange; + private int shopSelectedItemIndex; + private int shopSelectedItemType; + private int projectileMaxRange; + private String sleepingStatusText; + private int npcCombatModelArray1[] = { + 0, 1, 2, 1, 0, 0, 0, 0 + }; + private GameCharacter npcs[]; + private int experienceArray[]; + private int healthBarX[]; + private int healthBarY[]; + private int healthBarMissing[]; + private String skillNameLong[] = { + "Attack", "Defense", "Strength", "Hits", "Ranged", "Prayer", "Magic", "Cooking", "Woodcutting", "Fletching", + "Fishing", "Firemaking", "Crafting", "Smithing", "Mining", "Herblaw", "Agility", "Thieving" + }; + private GameCharacter playerServer[]; + private int playerCount; + private int knownPlayerCount; + private int spriteCount; + private int walkPathX[]; + private int walkPathY[]; + private String welcomeLastLoggedInHost; + private int wallObjectCount; + private int wallObjectX[]; + private int wallObjectY[]; + private int welcomeRecoverySetDays; + private int localLowerX; + private int localLowerY; + private int localUpperX; + private int localUpperY; + private int welcomeLastLoggedInIP; + private String menuItemText2[]; + private GameCharacter npcsServer[]; + private int sleepWordDelayTimer; + private int playerStatEquipment[]; + private World world; + private GameModel objectModel[]; + + public mudclient() { + menuIndices = new int[menuMaxSize]; + cameraAutoAngleDebug = false; + wallObjectDirection = new int[wallObjectsMax]; + wallObjectId = new int[wallObjectsMax]; + cameraRotationXIncrement = 2; + inventoryMaxItemCount = 30; + bankItemsMax = 48; + optionMenuEntry = new String[5]; + newBankItems = new int[256]; + newBankItemsCount = new int[256]; + teleportBubbleTime = new int[50]; + showDialogTradeConfirm = false; + tradeConfirmAccepted = false; + receivedMessageX = new int[50]; + receivedMessageY = new int[50]; + receivedMessageMidPoint = new int[50]; + receivedMessageHeight = new int[50]; + localPlayer = new GameCharacter(); + localPlayerServerIndex = -1; + menuItemX = new int[menuMaxSize]; + menuItemY = new int[menuMaxSize]; + showDialogTrade = false; + bankItems = new int[256]; + bankItemsCount = new int[256]; + appearanceBodyGender = 1; + appearance2Colour = 2; + appearanceHairColour = 2; + appearanceTopColour = 8; + appearanceBottomColour = 14; + appearanceHeadGender = 1; + loginUser = ""; + loginPass = ""; + cameraAngle = 1; + members = false; + optionSoundDisabled = false; + showRightClickMenu = false; + cameraRotationYIncrement = 2; + objectAlreadyInMenu = new boolean[objectsMax]; + menuItemText1 = new String[menuMaxSize]; + duelOpponentName = ""; + lastObjectAnimationNumberFireLightningSpell = -1; + lastObjectAnimationNumberTorch = -1; + lastOjectAnimationNumberClaw = -1; + planeIndex = -1; + //aString744 = "";// unused + welcomScreenAlreadyShown = false; + isSleeping = false; + cameraRotation = 128; + teleportBubbleX = new int[50]; + errorLoadingData = false; + playerExperience = new int[playerStatCount]; + tradeRecipientAccepted = false; + tradeAccepted = false; + mouseClickXHistory = new int[8192]; + mouseClickYHistory = new int[8192]; + showDialogWelcome = false; + playerServerIndexes = new int[playersMax]; + teleportBubbleY = new int[50]; + receivedMessages = new String[50]; + showDialogDuelConfirm = false; + duelAccepted = false; + players = new GameCharacter[playersMax]; + prayerOn = new boolean[50]; + //aString793 = "";// unused + menuSourceType = new int[menuMaxSize]; + menuSourceIndex = new int[menuMaxSize]; + menuTargetIndex = new int[menuMaxSize]; + wallObjectAlreadyInMenu = new boolean[wallObjectsMax]; + magicLoc = 128; + errorLoadingMemory = false; + fogOfWar = false; + gameWidth = appletWidth; // 512 + gameHeight = appletHeight - 10; // 334 + const_9 = 9; + tradeConfirmItems = new int[14]; + tradeConfirmItemCount = new int[14]; + tradeRecipientName = ""; + selectedSpell = -1; + showOptionMenu = false; + playerStatCurrent = new int[playerStatCount]; + teleportBubbleType = new int[50]; + errorLoadingCodebase = false; + showDialogShop = false; + shopItem = new int[256]; + shopItemCount = new int[256]; + shopItemPrice = new int[256]; + duelOfferOpponentAccepted = false; + duelOfferAccepted = false; + gameModels = new GameModel[1000]; + showDialogDuel = false; + serverMessage = ""; + serverMessageBoxTop = false; + duelOpponentItems = new int[8]; + duelOpponentItemCount = new int[8]; + duelItems = new int[8]; + duelItemCount = new int[8]; + playerStatBase = new int[playerStatCount]; + npcsCache = new GameCharacter[npcsMax]; + appletMode = true; + groundItemX = new int[groundItemsMax]; + groundItemY = new int[groundItemsMax]; + groundItemId = new int[groundItemsMax]; + groundItemZ = new int[groundItemsMax]; + bankSelectedItemSlot = -1; + bankSelectedItem = -2; + duelOfferOpponentItemId = new int[8]; + duelOfferOpponentItemStack = new int[8]; + messageHistoryTimeout = new int[5]; + optionCameraModeAuto = true; + objectX = new int[objectsMax]; + objectY = new int[objectsMax]; + objectId = new int[objectsMax]; + objectDirection = new int[objectsMax]; + selectedItemInventoryIndex = -1; + selectedItemName = ""; + loadingArea = false; + tradeRecipientConfirmItems = new int[14]; + tradeRecipientConfirmItemCount = new int[14]; + tradeRecipientItems = new int[14]; + tradeRecipientItemCount = new int[14]; + showDialogServermessage = false; + menuItemID = new int[menuMaxSize]; + questComplete = new boolean[questCount]; + wallObjectModel = new GameModel[wallObjectsMax]; + actionBubbleX = new int[50]; + actionBubbleY = new int[50]; + cameraZoom = 550; + tradeItems = new int[14]; + tradeItemCount = new int[14]; + lastHeightOffset = -1; + //anInt917 = 12345678;// unused + duelSettingsRetreat = false; + duelSettingsMagic = false; + duelSettingsPrayer = false; + duelSettingsWeapons = false; + showDialogBank = false; + loginUserDesc = ""; + loginUserDisp = ""; + optionMouseButtonOne = false; + inventoryItemId = new int[35]; + inventoryItemStackCount = new int[35]; + inventoryEquipped = new int[35]; + knownPlayers = new GameCharacter[playersMax]; + messageHistory = new String[5]; + reportAbuseMute = false; + duelOfferItemId = new int[8]; + duelOfferItemStack = new int[8]; + actionBubbleScale = new int[50]; + actionBubbleItem = new int[50]; + sleepWordDelay = true; + showAppearanceChange = false; + shopSelectedItemIndex = -1; + shopSelectedItemType = -2; + projectileMaxRange = 40; + npcs = new GameCharacter[npcsMax]; + experienceArray = new int[99]; + healthBarX = new int[50]; + healthBarY = new int[50]; + healthBarMissing = new int[50]; + playerServer = new GameCharacter[playersServerMax]; + walkPathX = new int[pathStepsMax]; + walkPathY = new int[pathStepsMax]; + wallObjectX = new int[wallObjectsMax]; + wallObjectY = new int[wallObjectsMax]; + menuItemText2 = new String[menuMaxSize]; + npcsServer = new GameCharacter[npcsServerMax]; + playerStatEquipment = new int[playerStatEquipmentCount]; + objectModel = new GameModel[objectsMax]; + } + + public static void main(String args[]) { + mudclient mc = new mudclient(); + mc.appletMode = false; + if (args.length > 0 && args[0].equals("members")) + mc.members = true; + if (args.length > 1) + mc.server = args[1]; + if (args.length > 2) + mc.port = Integer.parseInt(args[2]); + if (args.length > 3) + Version.CLIENT = Integer.parseInt(args[3]); + mc.startApplication(mc.gameWidth, mc.gameHeight + 11, "Runescape by Andrew Gower", false); + mc.threadSleep = 10; + } + + private static String formatNumber(int i) // wonder why this wasn't in the utility class + { + String s = String.valueOf(i); + for (int j = s.length() - 3; j > 0; j -= 3) + s = s.substring(0, j) + "," + s.substring(j); + + if (s.length() > 8) + s = "@gre@" + s.substring(0, s.length() - 8) + " million @whi@(" + s + ")"; + else if (s.length() > 4) + s = "@cya@" + s.substring(0, s.length() - 4) + "K @whi@(" + s + ")"; + return s; + } + + private void playSoundFile(String s) { + if (audioPlayer == null) + return; + if (!optionSoundDisabled) + audioPlayer.writeStream(soundData, Utility.getDataFileOffset(s + ".pcm", soundData), Utility.getDataFileLength(s + ".pcm", soundData)); + } + + private void drawDialogReportAbuse() { + reportAbuseOffence = 0; + int y = 135; + for (int i = 0; i < 12; i++) { + if (super.mouseX > 66 && super.mouseX < 446 && super.mouseY >= y - 12 && super.mouseY < y + 3) + reportAbuseOffence = i + 1; + y += 14; + } + + if (mouseButtonClick != 0 && reportAbuseOffence != 0) { + mouseButtonClick = 0; + showDialogReportAbuseStep = 2; + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + return; + } + y += 15; + if (mouseButtonClick != 0) { + mouseButtonClick = 0; + if (super.mouseX < 56 || super.mouseY < 35 || super.mouseX > 456 || super.mouseY > 325) { + showDialogReportAbuseStep = 0; + return; + } + if (super.mouseX > 66 && super.mouseX < 446 && super.mouseY >= y - 15 && super.mouseY < y + 5) { + showDialogReportAbuseStep = 0; + return; + } + } + surface.drawBox(56, 35, 400, 290, 0); + surface.drawBoxEdge(56, 35, 400, 290, 0xffffff); + y = 50; + surface.drawStringCenter("This form is for reporting players who are breaking our rules", 256, y, 1, 0xffffff); + y += 15; + surface.drawStringCenter("Using it sends a snapshot of the last 60 secs of activity to us", 256, y, 1, 0xffffff); + y += 15; + surface.drawStringCenter("If you misuse this form, you will be banned.", 256, y, 1, 0xff8000); + y += 15; + y += 10; + surface.drawStringCenter("First indicate which of our 12 rules is being broken. For a detailed", 256, y, 1, 0xffff00); + y += 15; + surface.drawStringCenter("explanation of each rule please read the manual on our website.", 256, y, 1, 0xffff00); + y += 15; + int textColour; + if (reportAbuseOffence == 1) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("1: Offensive language", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 2) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("2: Item scamming", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 3) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("3: Password scamming", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 4) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("4: Bug abuse", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 5) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("5: Jagex Staff impersonation", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 6) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("6: Account sharing/trading", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 7) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("7: Macroing", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 8) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("8: Mutiple logging in", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 9) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("9: Encouraging others to break rules", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 10) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("10: Misuse of customer support", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 11) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("11: Advertising / website", 256, y, 1, textColour); + y += 14; + if (reportAbuseOffence == 12) { + surface.drawBoxEdge(66, y - 12, 380, 15, 0xffffff); + textColour = 0xff8000; + } else { + textColour = 0xffffff; + } + surface.drawStringCenter("12: Real world item trading", 256, y, 1, textColour); + y += 14; + y += 15; + textColour = 0xffffff; + if (super.mouseX > 196 && super.mouseX < 316 && super.mouseY > y - 15 && super.mouseY < y + 5) + textColour = 0xffff00; + surface.drawStringCenter("Click here to cancel", 256, y, 1, textColour); + } + + private boolean walkToActionSource(int startX, int startY, int x1, int y1, int x2, int y2, boolean checkObjects, boolean walkToAction) { + int steps = world.route(startX, startY, x1, y1, x2, y2, walkPathX, walkPathY, checkObjects); + if (steps == -1) + if (walkToAction) { + steps = 1; + walkPathX[0] = x1; + walkPathY[0] = y1; + } else { + return false; + } + steps--; + startX = walkPathX[steps]; + startY = walkPathY[steps]; + steps--; + if (walkToAction) + super.clientStream.newPacket((Command.CL_WALK_ACTION)); + else + super.clientStream.newPacket((Command.CL_WALK)); + super.clientStream.putShort(startX + regionX); + super.clientStream.putShort(startY + regionY); + if (walkToAction && steps == -1 && (startX + regionX) % 5 == 0) + steps = 0; + for (int l1 = steps; l1 >= 0 && l1 > steps - 25; l1--) { + super.clientStream.putByte(walkPathX[l1] - startX); + super.clientStream.putByte(walkPathY[l1] - startY); + } + + super.clientStream.sendPacket(); + mouseClickXStep = -24; + mouseClickXX = super.mouseX; + mouseClickXY = super.mouseY; + return true; + } + + private boolean walkTo(int startX, int startY, int x1, int y1, int x2, int y2, boolean checkObjects, + boolean walkToAction) { + int steps = world.route(startX, startY, x1, y1, x2, y2, walkPathX, walkPathY, checkObjects); + if (steps == -1) + return false; + steps--; + startX = walkPathX[steps]; + startY = walkPathY[steps]; + steps--; + if (walkToAction) + super.clientStream.newPacket((Command.CL_WALK_ACTION)); + else + super.clientStream.newPacket((Command.CL_WALK)); + super.clientStream.putShort(startX + regionX); + super.clientStream.putShort(startY + regionY); + if (walkToAction && steps == -1 && (startX + regionX) % 5 == 0) + steps = 0; + for (int l1 = steps; l1 >= 0 && l1 > steps - 25; l1--) { + super.clientStream.putByte(walkPathX[l1] - startX); + super.clientStream.putByte(walkPathY[l1] - startY); + } + + super.clientStream.sendPacket(); + mouseClickXStep = -24; + mouseClickXX = super.mouseX; + mouseClickXY = super.mouseY; + return true; + } + + /* + public String getParameter(String s) { + return super.getParameter(s); + }*/ + + private void drawMinimapEntity(int x, int y, int c) { + surface.setPixel(x, y, c); + surface.setPixel(x - 1, y, c); + surface.setPixel(x + 1, y, c); + surface.setPixel(x, y - 1, c); + surface.setPixel(x, y + 1, c); + } + + private void updateBankItems() { + bankItemCount = newBankItemCount; + for (int i = 0; i < newBankItemCount; i++) { + bankItems[i] = newBankItems[i]; + bankItemsCount[i] = newBankItemsCount[i]; + } + + for (int invidx = 0; invidx < inventoryItemsCount; invidx++) { + if (bankItemCount >= bankItemsMax) + break; + int invid = inventoryItemId[invidx]; + boolean hasitemininv = false; + for (int bankidx = 0; bankidx < bankItemCount; bankidx++) { + if (bankItems[bankidx] != invid) + continue; + hasitemininv = true; + break; + } + + if (!hasitemininv) { + bankItems[bankItemCount] = invid; + bankItemsCount[bankItemCount] = 0; + bankItemCount++; + } + } + + } + + private void drawDialogWildWarn() { + int y = 97; + surface.drawBox(86, 77, 340, 180, 0); + surface.drawBoxEdge(86, 77, 340, 180, 0xffffff); + surface.drawStringCenter("Warning! Proceed with caution", 256, y, 4, 0xff0000); + y += 26; + surface.drawStringCenter("If you go much further north you will enter the", 256, y, 1, 0xffffff); + y += 13; + surface.drawStringCenter("wilderness. This a very dangerous area where", 256, y, 1, 0xffffff); + y += 13; + surface.drawStringCenter("other players can attack you!", 256, y, 1, 0xffffff); + y += 22; + surface.drawStringCenter("The further north you go the more dangerous it", 256, y, 1, 0xffffff); + y += 13; + surface.drawStringCenter("becomes, but the more treasure you will find.", 256, y, 1, 0xffffff); + y += 22; + surface.drawStringCenter("In the wilderness an indicator at the bottom-right", 256, y, 1, 0xffffff); + y += 13; + surface.drawStringCenter("of the screen will show the current level of danger", 256, y, 1, 0xffffff); + y += 22; + int j = 0xffffff; + if (super.mouseY > y - 12 && super.mouseY <= y && super.mouseX > 181 && super.mouseX < 331) + j = 0xff0000; + surface.drawStringCenter("Click here to close window", 256, y, 1, j); + if (mouseButtonClick != 0) { + if (super.mouseY > y - 12 && super.mouseY <= y && super.mouseX > 181 && super.mouseX < 331) + showUiWildWarn = 2; + if (super.mouseX < 86 || super.mouseX > 426 || super.mouseY < 77 || super.mouseY > 257) + showUiWildWarn = 2; + mouseButtonClick = 0; + } + } + + private void drawAboveHeadStuff() { + for (int msgidx = 0; msgidx < receivedMessagesCount; msgidx++) { + int txtheight = surface.textHeight(1); + int x = receivedMessageX[msgidx]; + int y = receivedMessageY[msgidx]; + int mid = receivedMessageMidPoint[msgidx]; + int msgheight = receivedMessageHeight[msgidx]; + boolean flag = true; + while (flag) { + flag = false; + for (int i4 = 0; i4 < msgidx; i4++) + if (y + msgheight > receivedMessageY[i4] - txtheight && y - txtheight < receivedMessageY[i4] + receivedMessageHeight[i4] && x - mid < receivedMessageX[i4] + receivedMessageMidPoint[i4] && x + mid > receivedMessageX[i4] - receivedMessageMidPoint[i4] && receivedMessageY[i4] - txtheight - msgheight < y) { + y = receivedMessageY[i4] - txtheight - msgheight; + flag = true; + } + + } + receivedMessageY[msgidx] = y; + surface.centrepara(receivedMessages[msgidx], x, y, 1, 0xffff00, 300); + } + + for (int itemidx = 0; itemidx < itemsAboveHeadCount; itemidx++) { + int x = actionBubbleX[itemidx]; + int y = actionBubbleY[itemidx]; + int scale = actionBubbleScale[itemidx]; + int id = actionBubbleItem[itemidx]; + int scaleX = (39 * scale) / 100; + int scaleY = (27 * scale) / 100; + surface.drawActionBubble(x - scaleX / 2, y - scaleY, scaleX, scaleY, spriteMedia + 9, 85); + int scaleXClip = (36 * scale) / 100; + int scaleYClip = (24 * scale) / 100; + surface.spriteClipping(x - scaleXClip / 2, (y - scaleY + scaleY / 2) - scaleYClip / 2, scaleXClip, scaleYClip, GameData.itemPicture[id] + spriteItem, GameData.itemMask[id], 0, 0, false); + } + + for (int j1 = 0; j1 < healthBarCount; j1++) { + int i2 = healthBarX[j1]; + int l2 = healthBarY[j1]; + int k3 = healthBarMissing[j1]; + surface.drawBoxAlpha(i2 - 15, l2 - 3, k3, 5, 65280, 192); + surface.drawBoxAlpha((i2 - 15) + k3, l2 - 3, 30 - k3, 5, 0xff0000, 192); + } + + } + + protected Socket createSocket(String addr, int port) throws IOException { + Socket socket1; + /*if (getStartedAsApplet()) + socket1 = new Socket(InetAddress.getByName(getCodeBase().getHost()), port); + else*/ + socket1 = new Socket(InetAddress.getByName(addr), port); + socket1.setSoTimeout(30000); + socket1.setTcpNoDelay(true); + return socket1; + } + + private void walkToActionSource(int sx, int sy, int dx, int dy, boolean action) { + walkToActionSource(sx, sy, dx, dy, dx, dy, false, action); + } + + private void createMessageTabPanel() { + panelMessageTabs = new Panel(surface, 10); + controlTextListChat = panelMessageTabs.addTextList(5, 269, 502, 56, 1, 20, true); + controlTextListAll = panelMessageTabs.addTextListInput(7, 324, 498, 14, 1, 80, false, true); + controlTextListQuest = panelMessageTabs.addTextList(5, 269, 502, 56, 1, 20, true); + controlTextListPrivate = panelMessageTabs.addTextList(5, 269, 502, 56, 1, 20, true); + panelMessageTabs.setFocus(controlTextListAll); + } + + private void disposeAndCollect() { + try { + if (surface != null) { + surface.clear(); + surface.pixels = null; + surface = null; + } + if (scene != null) { + scene.dispose(); + scene = null; + } + gameModels = null; + objectModel = null; + wallObjectModel = null; + playerServer = null; + players = null; + npcsServer = null; + npcs = null; + localPlayer = null; + if (world != null) { + world.terrainModels = null; + world.wallModels = null; + world.roofModels = null; + world.parentModel = null; + world = null; + } + System.gc(); + return; + } catch (Exception Ex) { + return; + } + } + + private void drawUi() { + if (logoutTimeout != 0) + drawDialogLogout(); + else if (showDialogWelcome) + drawDialogWelcome(); + else if (showDialogServermessage) + drawDialogServermessage(); + else if (showUiWildWarn == 1) + drawDialogWildWarn(); + else if (showDialogBank && combatTimeout == 0) + drawDialogBank(); + else if (showDialogShop && combatTimeout == 0) + drawDialogShop(); + else if (showDialogTradeConfirm) + drawDialogTradeConfirm(); + else if (showDialogTrade) + drawDialogTrade(); + else if (showDialogDuelConfirm) + drawDialogDuelConfirm(); + else if (showDialogDuel) + drawDialogDuel(); + else if (showDialogReportAbuseStep == 1) + drawDialogReportAbuse(); + else if (showDialogReportAbuseStep == 2) + drawDialogReportAbuseInput(); + else if (showDialogSocialInput != 0) { + drawDialogSocialInput(); + } else { + if (showOptionMenu) + drawOptionMenu(); + if (localPlayer.animationCurrent == 8 || localPlayer.animationCurrent == 9) + drawDialogCombatStyle(); + setActiveUiTab(); + boolean nomenus = !showOptionMenu && !showRightClickMenu; + if (nomenus) + menuItemsCount = 0; + if (showUiTab == 0 && nomenus) + createRightClickMenu(); + if (showUiTab == 1) + drawUiTabInventory(nomenus); + if (showUiTab == 2) + drawUiTabMinimap(nomenus); + if (showUiTab == 3) + drawUiTabPlayerInfo(nomenus); + if (showUiTab == 4) + drawUiTabMagic(nomenus); + if (showUiTab == 5) + drawUiTabSocial(nomenus); + if (showUiTab == 6) + drawUiTabOptions(nomenus); + if (!showRightClickMenu && !showOptionMenu) + createTopMouseMenu(); + if (showRightClickMenu && !showOptionMenu) + drawRightClickMenu(); + } + mouseButtonClick = 0; + } + + private void drawDialogTrade() { + if (mouseButtonClick != 0 && mouseButtonItemCountIncrement == 0) + mouseButtonItemCountIncrement = 1; + if (mouseButtonItemCountIncrement > 0) { + int mouseX = super.mouseX - 22; + int mouseY = super.mouseY - 36; + if (mouseX >= 0 && mouseY >= 0 && mouseX < 468 && mouseY < 262) { + if (mouseX > 216 && mouseY > 30 && mouseX < 462 && mouseY < 235) { + int slot = (mouseX - 217) / 49 + ((mouseY - 31) / 34) * 5; + if (slot >= 0 && slot < inventoryItemsCount) { + boolean sendUpdate = false; + int itemCountAdd = 0; + int itemType = inventoryItemId[slot]; + for (int itemIndex = 0; itemIndex < tradeItemsCount; itemIndex++) + if (tradeItems[itemIndex] == itemType) + if (GameData.itemStackable[itemType] == 0) { + for (int i4 = 0; i4 < mouseButtonItemCountIncrement; i4++) { + if (tradeItemCount[itemIndex] < inventoryItemStackCount[slot]) + tradeItemCount[itemIndex]++; + sendUpdate = true; + } + + } else { + itemCountAdd++; + } + + if (getInventoryCount(itemType) <= itemCountAdd) + sendUpdate = true; + if (GameData.itemSpecial[itemType] == 1) { // quest items? or just tagged as 'special' + showMessage("This object cannot be traded with other players", 3); + sendUpdate = true; + } + if (!sendUpdate && tradeItemsCount < 12) { + tradeItems[tradeItemsCount] = itemType; + tradeItemCount[tradeItemsCount] = 1; + tradeItemsCount++; + sendUpdate = true; + } + if (sendUpdate) { + super.clientStream.newPacket((Command.CL_TRADE_ITEM_UPDATE)); + super.clientStream.putByte(tradeItemsCount); + for (int j4 = 0; j4 < tradeItemsCount; j4++) { + super.clientStream.putShort(tradeItems[j4]); + super.clientStream.putInt(tradeItemCount[j4]); + } + + super.clientStream.sendPacket(); + tradeRecipientAccepted = false; + tradeAccepted = false; + } + } + } + if (mouseX > 8 && mouseY > 30 && mouseX < 205 && mouseY < 133) { + int itemIndex = (mouseX - 9) / 49 + ((mouseY - 31) / 34) * 4; + if (itemIndex >= 0 && itemIndex < tradeItemsCount) { + int itemType = tradeItems[itemIndex]; + for (int i2 = 0; i2 < mouseButtonItemCountIncrement; i2++) { + if (GameData.itemStackable[itemType] == 0 && tradeItemCount[itemIndex] > 1) { + tradeItemCount[itemIndex]--; + continue; + } + tradeItemsCount--; + mouseButtonDownTime = 0; + for (int l2 = itemIndex; l2 < tradeItemsCount; l2++) { + tradeItems[l2] = tradeItems[l2 + 1]; + tradeItemCount[l2] = tradeItemCount[l2 + 1]; + } + + break; + } + + super.clientStream.newPacket((Command.CL_TRADE_ITEM_UPDATE)); + super.clientStream.putByte(tradeItemsCount); + for (int i3 = 0; i3 < tradeItemsCount; i3++) { + super.clientStream.putShort(tradeItems[i3]); + super.clientStream.putInt(tradeItemCount[i3]); + } + + super.clientStream.sendPacket(); + tradeRecipientAccepted = false; + tradeAccepted = false; + } + } + if (mouseX >= 217 && mouseY >= 238 && mouseX <= 286 && mouseY <= 259) { + tradeAccepted = true; + super.clientStream.newPacket((Command.CL_TRADE_ACCEPT)); + super.clientStream.sendPacket(); + } + if (mouseX >= 394 && mouseY >= 238 && mouseX < 463 && mouseY < 259) { + showDialogTrade = false; + super.clientStream.newPacket((Command.CL_TRADE_DECLINE)); + super.clientStream.sendPacket(); + } + } else if (mouseButtonClick != 0) { + showDialogTrade = false; + super.clientStream.newPacket((Command.CL_TRADE_DECLINE)); + super.clientStream.sendPacket(); + } + mouseButtonClick = 0; + mouseButtonItemCountIncrement = 0; + } + if (!showDialogTrade) + return; + byte dialogX = 22; + byte dialogY = 36; + surface.drawBox(dialogX, dialogY, 468, 12, 192); + surface.drawBoxAlpha(dialogX, dialogY + 12, 468, 18, 0x989898, 160); + surface.drawBoxAlpha(dialogX, dialogY + 30, 8, 248, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 205, dialogY + 30, 11, 248, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 462, dialogY + 30, 6, 248, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 133, 197, 22, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 258, 197, 20, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 216, dialogY + 235, 246, 43, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 30, 197, 103, 0xd0d0d0, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 155, 197, 103, 0xd0d0d0, 160); + surface.drawBoxAlpha(dialogX + 216, dialogY + 30, 246, 205, 0xd0d0d0, 160); + for (int j2 = 0; j2 < 4; j2++) + surface.drawLineHoriz(dialogX + 8, dialogY + 30 + j2 * 34, 197, 0); + + for (int j3 = 0; j3 < 4; j3++) + surface.drawLineHoriz(dialogX + 8, dialogY + 155 + j3 * 34, 197, 0); + + for (int l3 = 0; l3 < 7; l3++) + surface.drawLineHoriz(dialogX + 216, dialogY + 30 + l3 * 34, 246, 0); + + for (int k4 = 0; k4 < 6; k4++) { + if (k4 < 5) + surface.drawLineVert(dialogX + 8 + k4 * 49, dialogY + 30, 103, 0); + if (k4 < 5) + surface.drawLineVert(dialogX + 8 + k4 * 49, dialogY + 155, 103, 0); + surface.drawLineVert(dialogX + 216 + k4 * 49, dialogY + 30, 205, 0); + } + + surface.drawstring("Trading with: " + tradeRecipientName, dialogX + 1, dialogY + 10, 1, 0xffffff); + surface.drawstring("Your Offer", dialogX + 9, dialogY + 27, 4, 0xffffff); + surface.drawstring("Opponent's Offer", dialogX + 9, dialogY + 152, 4, 0xffffff); + surface.drawstring("Your Inventory", dialogX + 216, dialogY + 27, 4, 0xffffff); + if (!tradeAccepted) + surface.drawSprite(dialogX + 217, dialogY + 238, spriteMedia + 25); + surface.drawSprite(dialogX + 394, dialogY + 238, spriteMedia + 26); + if (tradeRecipientAccepted) { + surface.drawStringCenter("Other player", dialogX + 341, dialogY + 246, 1, 0xffffff); + surface.drawStringCenter("has accepted", dialogX + 341, dialogY + 256, 1, 0xffffff); + } + if (tradeAccepted) { + surface.drawStringCenter("Waiting for", dialogX + 217 + 35, dialogY + 246, 1, 0xffffff); + surface.drawStringCenter("other player", dialogX + 217 + 35, dialogY + 256, 1, 0xffffff); + } + for (int itemIndex = 0; itemIndex < inventoryItemsCount; itemIndex++) { + int slotX = 217 + dialogX + (itemIndex % 5) * 49; + int slotY = 31 + dialogY + (itemIndex / 5) * 34; + surface.spriteClipping(slotX, slotY, 48, 32, spriteItem + GameData.itemPicture[inventoryItemId[itemIndex]], GameData.itemMask[inventoryItemId[itemIndex]], 0, 0, false); + if (GameData.itemStackable[inventoryItemId[itemIndex]] == 0) + surface.drawstring(String.valueOf(inventoryItemStackCount[itemIndex]), slotX + 1, slotY + 10, 1, 0xffff00); + } + + for (int itemIndex = 0; itemIndex < tradeItemsCount; itemIndex++) { + int slotX = 9 + dialogX + (itemIndex % 4) * 49; + int slotY = 31 + dialogY + (itemIndex / 4) * 34; + surface.spriteClipping(slotX, slotY, 48, 32, spriteItem + GameData.itemPicture[tradeItems[itemIndex]], GameData.itemMask[tradeItems[itemIndex]], 0, 0, false); + if (GameData.itemStackable[tradeItems[itemIndex]] == 0) + surface.drawstring(String.valueOf(tradeItemCount[itemIndex]), slotX + 1, slotY + 10, 1, 0xffff00); + if (super.mouseX > slotX && super.mouseX < slotX + 48 && super.mouseY > slotY && super.mouseY < slotY + 32) + surface.drawstring(GameData.itemName[tradeItems[itemIndex]] + ": @whi@" + GameData.itemDescription[tradeItems[itemIndex]], dialogX + 8, dialogY + 273, 1, 0xffff00); + } + + for (int itemIndex = 0; itemIndex < tradeRecipientItemsCount; itemIndex++) { + int slotX = 9 + dialogX + (itemIndex % 4) * 49; + int slotY = 156 + dialogY + (itemIndex / 4) * 34; + surface.spriteClipping(slotX, slotY, 48, 32, spriteItem + GameData.itemPicture[tradeRecipientItems[itemIndex]], GameData.itemMask[tradeRecipientItems[itemIndex]], 0, 0, false); + if (GameData.itemStackable[tradeRecipientItems[itemIndex]] == 0) + surface.drawstring(String.valueOf(tradeRecipientItemCount[itemIndex]), slotX + 1, slotY + 10, 1, 0xffff00); + if (super.mouseX > slotX && super.mouseX < slotX + 48 && super.mouseY > slotY && super.mouseY < slotY + 32) + surface.drawstring(GameData.itemName[tradeRecipientItems[itemIndex]] + ": @whi@" + GameData.itemDescription[tradeRecipientItems[itemIndex]], dialogX + 8, dialogY + 273, 1, 0xffff00); + } + + } + + protected void resetGame() { + systemUpdate = 0; + combatStyle = 0; + logoutTimeout = 0; + loginScreen = 0; + loggedIn = 1; + resetPMText(); + surface.blackScreen(); + surface.draw(0, 0); + for (int i = 0; i < objectCount; i++) { + scene.removeModel(objectModel[i]); + world.removeObject(objectX[i], objectY[i], objectId[i]); + } + + for (int j = 0; j < wallObjectCount; j++) { + scene.removeModel(wallObjectModel[j]); + world.removeWallObject(wallObjectX[j], wallObjectY[j], wallObjectDirection[j], wallObjectId[j]); + } + + objectCount = 0; + wallObjectCount = 0; + groundItemCount = 0; + playerCount = 0; + for (int k = 0; k < playersServerMax; k++) + playerServer[k] = null; + + for (int l = 0; l < playersMax; l++) + players[l] = null; + + npcCount = 0; + for (int i1 = 0; i1 < npcsServerMax; i1++) + npcsServer[i1] = null; + + for (int j1 = 0; j1 < npcsMax; j1++) + npcs[j1] = null; + + for (int k1 = 0; k1 < 50; k1++) + prayerOn[k1] = false; + + mouseButtonClick = 0; + super.lastMouseButtonDown = 0; + super.mouseButtonDown = 0; + showDialogShop = false; + showDialogBank = false; + isSleeping = false; + super.friendListCount = 0; + } + + private void drawUiTabSocial(boolean nomenus) { + int uiX = surface.width2 - 199; + int uiY = 36; + surface.drawSprite(uiX - 49, 3, spriteMedia + 5); + int uiWidth = 196;//'\304'; + int uiHeight = 182;//'\266'; + int l; + int k = l = Surface.rgb2long(160, 160, 160); + if (uiTabSocialSubTab == 0) + k = Surface.rgb2long(220, 220, 220); + else + l = Surface.rgb2long(220, 220, 220); + surface.drawBoxAlpha(uiX, uiY, uiWidth / 2, 24, k, 128); + surface.drawBoxAlpha(uiX + uiWidth / 2, uiY, uiWidth / 2, 24, l, 128); + surface.drawBoxAlpha(uiX, uiY + 24, uiWidth, uiHeight - 24, Surface.rgb2long(220, 220, 220), 128); + surface.drawLineHoriz(uiX, uiY + 24, uiWidth, 0); + surface.drawLineVert(uiX + uiWidth / 2, uiY, 24, 0); + surface.drawLineHoriz(uiX, (uiY + uiHeight) - 16, uiWidth, 0); + surface.drawStringCenter("Friends", uiX + uiWidth / 4, uiY + 16, 4, 0); + surface.drawStringCenter("Ignore", uiX + uiWidth / 4 + uiWidth / 2, uiY + 16, 4, 0); + panelSocialList.clearList(controlListSocialPlayers); + if (uiTabSocialSubTab == 0) { + for (int i1 = 0; i1 < super.friendListCount; i1++) { + String s; + if (super.friendListOnline[i1] == 255) + s = "@gre@"; + else if (super.friendListOnline[i1] > 0) + s = "@yel@"; + else + s = "@red@"; + panelSocialList.addListEntry(controlListSocialPlayers, i1, s + Utility.hash2username(super.friendListHashes[i1]) + "~439~@whi@Remove WWWWWWWWWW"); + } + + } + if (uiTabSocialSubTab == 1) { + for (int j1 = 0; j1 < super.ignoreListCount; j1++) + panelSocialList.addListEntry(controlListSocialPlayers, j1, "@yel@" + Utility.hash2username(super.ignoreList[j1]) + "~439~@whi@Remove WWWWWWWWWW"); + + } + panelSocialList.drawPanel(); + if (uiTabSocialSubTab == 0) { + int k1 = panelSocialList.getListEntryIndex(controlListSocialPlayers); + if (k1 >= 0 && super.mouseX < 489) { + if (super.mouseX > 429) + surface.drawStringCenter("Click to remove " + Utility.hash2username(super.friendListHashes[k1]), uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + else if (super.friendListOnline[k1] == 255) + surface.drawStringCenter("Click to message " + Utility.hash2username(super.friendListHashes[k1]), uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + else if (super.friendListOnline[k1] > 0) { + if (super.friendListOnline[k1] < 200) + surface.drawStringCenter(Utility.hash2username(super.friendListHashes[k1]) + " is on world " + (super.friendListOnline[k1] - 9), uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + else + surface.drawStringCenter(Utility.hash2username(super.friendListHashes[k1]) + " is on classic " + (super.friendListOnline[k1] - 219), uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + } else { + surface.drawStringCenter(Utility.hash2username(super.friendListHashes[k1]) + " is offline", uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + } + } else { + surface.drawStringCenter("Click a name to send a message", uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + } + int colour; + if (super.mouseX > uiX && super.mouseX < uiX + uiWidth && super.mouseY > (uiY + uiHeight) - 16 && super.mouseY < uiY + uiHeight) + colour = 0xffff00; + else + colour = 0xffffff; + surface.drawStringCenter("Click here to add a friend", uiX + uiWidth / 2, (uiY + uiHeight) - 3, 1, colour); + } + if (uiTabSocialSubTab == 1) { + int l1 = panelSocialList.getListEntryIndex(controlListSocialPlayers); + if (l1 >= 0 && super.mouseX < 489 && super.mouseX > 429) { + if (super.mouseX > 429) + surface.drawStringCenter("Click to remove " + Utility.hash2username(super.ignoreList[l1]), uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + } else { + surface.drawStringCenter("Blocking messages from:", uiX + uiWidth / 2, uiY + 35, 1, 0xffffff); + } + int l2; + if (super.mouseX > uiX && super.mouseX < uiX + uiWidth && super.mouseY > (uiY + uiHeight) - 16 && super.mouseY < uiY + uiHeight) + l2 = 0xffff00; + else + l2 = 0xffffff; + surface.drawStringCenter("Click here to add a name", uiX + uiWidth / 2, (uiY + uiHeight) - 3, 1, l2); + } + if (!nomenus) + return; + uiX = super.mouseX - (surface.width2 - 199); + uiY = super.mouseY - 36; + if (uiX >= 0 && uiY >= 0 && uiX < 196 && uiY < 182) { + panelSocialList.handleMouse(uiX + (surface.width2 - 199), uiY + 36, super.lastMouseButtonDown, super.mouseButtonDown); + if (uiY <= 24 && mouseButtonClick == 1) + if (uiX < 98 && uiTabSocialSubTab == 1) { + uiTabSocialSubTab = 0; + panelSocialList.resetListProps(controlListSocialPlayers); + } else if (uiX > 98 && uiTabSocialSubTab == 0) { + uiTabSocialSubTab = 1; + panelSocialList.resetListProps(controlListSocialPlayers); + } + if (mouseButtonClick == 1 && uiTabSocialSubTab == 0) { + int i2 = panelSocialList.getListEntryIndex(controlListSocialPlayers); + if (i2 >= 0 && super.mouseX < 489) + if (super.mouseX > 429) + friendRemove(super.friendListHashes[i2]); + else if (super.friendListOnline[i2] != 0) { + showDialogSocialInput = 2; + privateMessageTarget = super.friendListHashes[i2]; + super.inputPmCurrent = ""; + super.inputPmFinal = ""; + } + } + if (mouseButtonClick == 1 && uiTabSocialSubTab == 1) { + int j2 = panelSocialList.getListEntryIndex(controlListSocialPlayers); + if (j2 >= 0 && super.mouseX < 489 && super.mouseX > 429) + ignoreRemove(super.ignoreList[j2]); + } + if (uiY > 166 && mouseButtonClick == 1 && uiTabSocialSubTab == 0) { + showDialogSocialInput = 1; + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + } + if (uiY > 166 && mouseButtonClick == 1 && uiTabSocialSubTab == 1) { + showDialogSocialInput = 3; + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + } + mouseButtonClick = 0; + } + } + + protected void handleKeyPress(int i) { + if (loggedIn == 0) { + if (loginScreen == 0 && panelLoginWelcome != null) + panelLoginWelcome.keyPress(i); + if (loginScreen == 1 && panelLoginNewuser != null) + panelLoginNewuser.keyPress(i); + if (loginScreen == 2 && panelLoginExistinguser != null) + panelLoginExistinguser.keyPress(i); + } + if (loggedIn == 1) { + if (showAppearanceChange && panelAppearance != null) { + panelAppearance.keyPress(i); + return; + } + if (showDialogSocialInput == 0 && showDialogReportAbuseStep == 0 && !isSleeping && panelMessageTabs != null) + panelMessageTabs.keyPress(i); + } + } + + private void sendLogout() { + if (loggedIn == 0) + return; + if (combatTimeout > 450) { + showMessage("@cya@You can't logout during combat!", 3); + return; + } + if (combatTimeout > 0) { + showMessage("@cya@You can't logout for 10 seconds after combat", 3); + return; + } else { + super.clientStream.newPacket((Command.CL_LOGOUT)); + super.clientStream.sendPacket(); + logoutTimeout = 1000; + return; + } + } + + private GameCharacter createPlayer(int serverIndex, int x, int y, int anim) { + if (playerServer[serverIndex] == null) { + playerServer[serverIndex] = new GameCharacter(); + playerServer[serverIndex].serverIndex = serverIndex; + playerServer[serverIndex].serverId = 0; + } + GameCharacter character = playerServer[serverIndex]; + boolean flag = false; + for (int i1 = 0; i1 < knownPlayerCount; i1++) { + if (knownPlayers[i1].serverIndex != serverIndex) + continue; + flag = true; + break; + } + + if (flag) { + character.animationNext = anim; + int j1 = character.waypointCurrent; + if (x != character.waypointsX[j1] || y != character.waypointsY[j1]) { + character.waypointCurrent = j1 = (j1 + 1) % 10; + character.waypointsX[j1] = x; + character.waypointsY[j1] = y; + } + } else { + character.serverIndex = serverIndex; + character.movingStep = 0; + character.waypointCurrent = 0; + character.waypointsX[0] = character.currentX = x; + character.waypointsY[0] = character.currentY = y; + character.animationNext = character.animationCurrent = anim; + character.stepCount = 0; + } + players[playerCount++] = character; + return character; + } + + private void drawDialogSocialInput() { + if (mouseButtonClick != 0) { + mouseButtonClick = 0; + if (showDialogSocialInput == 1 && (super.mouseX < 106 || super.mouseY < 145 || super.mouseX > 406 || super.mouseY > 215)) { + showDialogSocialInput = 0; + return; + } + if (showDialogSocialInput == 2 && (super.mouseX < 6 || super.mouseY < 145 || super.mouseX > 506 || super.mouseY > 215)) { + showDialogSocialInput = 0; + return; + } + if (showDialogSocialInput == 3 && (super.mouseX < 106 || super.mouseY < 145 || super.mouseX > 406 || super.mouseY > 215)) { + showDialogSocialInput = 0; + return; + } + if (super.mouseX > 236 && super.mouseX < 276 && super.mouseY > 193 && super.mouseY < 213) { + showDialogSocialInput = 0; + return; + } + } + int i = 145; + if (showDialogSocialInput == 1) { + surface.drawBox(106, i, 300, 70, 0); + surface.drawBoxEdge(106, i, 300, 70, 0xffffff); + i += 20; + surface.drawStringCenter("Enter name to add to friends list", 256, i, 4, 0xffffff); + i += 20; + surface.drawStringCenter(super.inputTextCurrent + "*", 256, i, 4, 0xffffff); + if (super.inputTextFinal.length() > 0) { + String s = super.inputTextFinal.trim(); + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + showDialogSocialInput = 0; + if (s.length() > 0 && Utility.username2hash(s) != localPlayer.hash) + friendAdd(s); + } + } + if (showDialogSocialInput == 2) { + surface.drawBox(6, i, 500, 70, 0); + surface.drawBoxEdge(6, i, 500, 70, 0xffffff); + i += 20; + surface.drawStringCenter("Enter message to send to " + Utility.hash2username(privateMessageTarget), 256, i, 4, 0xffffff); + i += 20; + surface.drawStringCenter(super.inputPmCurrent + "*", 256, i, 4, 0xffffff); + if (super.inputPmFinal.length() > 0) { + String s1 = super.inputPmFinal; + super.inputPmCurrent = ""; + super.inputPmFinal = ""; + showDialogSocialInput = 0; + int k = ChatMessage.scramble(s1); + sendPrivateMessage(privateMessageTarget, ChatMessage.scrambledbytes, k); + s1 = ChatMessage.descramble(ChatMessage.scrambledbytes, 0, k); + s1 = WordFilter.filter(s1); + showServerMessage("@pri@You tell " + Utility.hash2username(privateMessageTarget) + ": " + s1); + } + } + if (showDialogSocialInput == 3) { + surface.drawBox(106, i, 300, 70, 0); + surface.drawBoxEdge(106, i, 300, 70, 0xffffff); + i += 20; + surface.drawStringCenter("Enter name to add to ignore list", 256, i, 4, 0xffffff); + i += 20; + surface.drawStringCenter(super.inputTextCurrent + "*", 256, i, 4, 0xffffff); + if (super.inputTextFinal.length() > 0) { + String s2 = super.inputTextFinal.trim(); + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + showDialogSocialInput = 0; + if (s2.length() > 0 && Utility.username2hash(s2) != localPlayer.hash) + ignoreAdd(s2); + } + } + int j = 0xffffff; + if (super.mouseX > 236 && super.mouseX < 276 && super.mouseY > 193 && super.mouseY < 213) + j = 0xffff00; + surface.drawStringCenter("Cancel", 256, 208, 1, j); + } + + private void createAppearancePanel() { + panelAppearance = new Panel(surface, 100); + panelAppearance.addText(256, 10, "Please design Your Character", 4, true); + int x = 140; + int y = 34; + x += 116; + y -= 10; + panelAppearance.addText(x - 55, y + 110, "Front", 3, true); + panelAppearance.addText(x, y + 110, "Side", 3, true); + panelAppearance.addText(x + 55, y + 110, "Back", 3, true); + byte xoff = 54; + y += 145; + panelAppearance.addBoxRounded(x - xoff, y, 53, 41); + panelAppearance.addText(x - xoff, y - 8, "Head", 1, true); + panelAppearance.addText(x - xoff, y + 8, "Type", 1, true); + panelAppearance.addSprite(x - xoff - 40, y, Panel.baseSpriteStart + 7); + controlButtonAppearanceHead1 = panelAppearance.addButton(x - xoff - 40, y, 20, 20); + panelAppearance.addSprite((x - xoff) + 40, y, Panel.baseSpriteStart + 6); + controlButtonAppearanceHead2 = panelAppearance.addButton((x - xoff) + 40, y, 20, 20); + panelAppearance.addBoxRounded(x + xoff, y, 53, 41); + panelAppearance.addText(x + xoff, y - 8, "Hair", 1, true); + panelAppearance.addText(x + xoff, y + 8, "Color", 1, true); + panelAppearance.addSprite((x + xoff) - 40, y, Panel.baseSpriteStart + 7); + controlButtonAppearanceHair1 = panelAppearance.addButton((x + xoff) - 40, y, 20, 20); + panelAppearance.addSprite(x + xoff + 40, y, Panel.baseSpriteStart + 6); + controlButtonAppearanceHair2 = panelAppearance.addButton(x + xoff + 40, y, 20, 20); + y += 50; + panelAppearance.addBoxRounded(x - xoff, y, 53, 41); + panelAppearance.addText(x - xoff, y, "Gender", 1, true); + panelAppearance.addSprite(x - xoff - 40, y, Panel.baseSpriteStart + 7); + controlButtonAppearanceGender1 = panelAppearance.addButton(x - xoff - 40, y, 20, 20); + panelAppearance.addSprite((x - xoff) + 40, y, Panel.baseSpriteStart + 6); + controlButtonAppearanceGender2 = panelAppearance.addButton((x - xoff) + 40, y, 20, 20); + panelAppearance.addBoxRounded(x + xoff, y, 53, 41); + panelAppearance.addText(x + xoff, y - 8, "Top", 1, true); + panelAppearance.addText(x + xoff, y + 8, "Color", 1, true); + panelAppearance.addSprite((x + xoff) - 40, y, Panel.baseSpriteStart + 7); + controlButtonAppearanceTop1 = panelAppearance.addButton((x + xoff) - 40, y, 20, 20); + panelAppearance.addSprite(x + xoff + 40, y, Panel.baseSpriteStart + 6); + controlButtonAppearanceTop2 = panelAppearance.addButton(x + xoff + 40, y, 20, 20); + y += 50; + panelAppearance.addBoxRounded(x - xoff, y, 53, 41); + panelAppearance.addText(x - xoff, y - 8, "Skin", 1, true); + panelAppearance.addText(x - xoff, y + 8, "Color", 1, true); + panelAppearance.addSprite(x - xoff - 40, y, Panel.baseSpriteStart + 7); + controlButtonAppearanceSkin1 = panelAppearance.addButton(x - xoff - 40, y, 20, 20); + panelAppearance.addSprite((x - xoff) + 40, y, Panel.baseSpriteStart + 6); + controlButtonAppearanceSkin2 = panelAppearance.addButton((x - xoff) + 40, y, 20, 20); + panelAppearance.addBoxRounded(x + xoff, y, 53, 41); + panelAppearance.addText(x + xoff, y - 8, "Bottom", 1, true); + panelAppearance.addText(x + xoff, y + 8, "Color", 1, true); + panelAppearance.addSprite((x + xoff) - 40, y, Panel.baseSpriteStart + 7); + controlButtonAppearanceBottom1 = panelAppearance.addButton((x + xoff) - 40, y, 20, 20); + panelAppearance.addSprite(x + xoff + 40, y, Panel.baseSpriteStart + 6); + controlButtonAppearanceBottom2 = panelAppearance.addButton(x + xoff + 40, y, 20, 20); + y += 82; + y -= 35; + panelAppearance.addButtonBackground(x, y, 200, 30); + panelAppearance.addText(x, y, "Accept", 4, false); + controlButtonAppearanceAccept = panelAppearance.addButton(x, y, 200, 30); + } + + private void resetPMText() { + super.inputPmCurrent = ""; + super.inputPmFinal = ""; + } + + private void drawDialogWelcome() { + int i = 65; + if (welcomeRecoverySetDays != 201) + i += 60; + if (welcomeUnreadMessages > 0) + i += 60; + if (welcomeLastLoggedInIP != 0) + i += 45; + int y = 167 - i / 2; + surface.drawBox(56, 167 - i / 2, 400, i, 0); + surface.drawBoxEdge(56, 167 - i / 2, 400, i, 0xffffff); + y += 20; + surface.drawStringCenter("Welcome to RuneScape " + loginUser, 256, y, 4, 0xffff00); + y += 30; + String s; + if (welcomeLastLoggedInDays == 0) + s = "earlier today"; + else if (welcomeLastLoggedInDays == 1) + s = "yesterday"; + else + s = welcomeLastLoggedInDays + " days ago"; + if (welcomeLastLoggedInIP != 0) { + surface.drawStringCenter("You last logged in " + s, 256, y, 1, 0xffffff); + y += 15; + if (welcomeLastLoggedInHost == null) + welcomeLastLoggedInHost = getHostnameIP(welcomeLastLoggedInIP); + surface.drawStringCenter("from: " + welcomeLastLoggedInHost, 256, y, 1, 0xffffff); + y += 15; + y += 15; + } + if (welcomeUnreadMessages > 0) { + int k = 0xffffff; + surface.drawStringCenter("Jagex staff will NEVER email you. We use the", 256, y, 1, k); + y += 15; + surface.drawStringCenter("message-centre on this website instead.", 256, y, 1, k); + y += 15; + if (welcomeUnreadMessages == 1) + surface.drawStringCenter("You have @yel@0@whi@ unread messages in your message-centre", 256, y, 1, 0xffffff); + else + surface.drawStringCenter("You have @gre@" + (welcomeUnreadMessages - 1) + " unread messages @whi@in your message-centre", 256, y, 1, 0xffffff); + y += 15; + y += 15; + } + if (welcomeRecoverySetDays != 201) // this is an odd way of storing recovery day settings + { + if (welcomeRecoverySetDays == 200) // and this + { + surface.drawStringCenter("You have not yet set any password recovery questions.", 256, y, 1, 0xff8000); + y += 15; + surface.drawStringCenter("We strongly recommend you do so now to secure your account.", 256, y, 1, 0xff8000); + y += 15; + surface.drawStringCenter("Do this from the 'account management' area on our front webpage", 256, y, 1, 0xff8000); + y += 15; + } else { + String s1; + if (welcomeRecoverySetDays == 0) + s1 = "Earlier today"; + else if (welcomeRecoverySetDays == 1) + s1 = "Yesterday"; + else + s1 = welcomeRecoverySetDays + " days ago"; + surface.drawStringCenter(s1 + " you changed your recovery questions", 256, y, 1, 0xff8000); + y += 15; + surface.drawStringCenter("If you do not remember making this change then cancel it immediately", 256, y, 1, 0xff8000); + y += 15; + surface.drawStringCenter("Do this from the 'account management' area on our front webpage", 256, y, 1, 0xff8000); + y += 15; + } + y += 15; + } + int l = 0xffffff; + if (super.mouseY > y - 12 && super.mouseY <= y && super.mouseX > 106 && super.mouseX < 406) + l = 0xff0000; + surface.drawStringCenter("Click here to close window", 256, y, 1, l); + if (mouseButtonClick == 1) { + if (l == 0xff0000) + showDialogWelcome = false; + if ((super.mouseX < 86 || super.mouseX > 426) && (super.mouseY < 167 - i / 2 || super.mouseY > 167 + i / 2)) + showDialogWelcome = false; + } + mouseButtonClick = 0; + } + + private void drawAppearancePanelCharacterSprites() { + surface.interlace = false; + surface.blackScreen(); + panelAppearance.drawPanel(); + int i = 140; + int j = 50; + i += 116; + j -= 25; + surface.spriteClipping(i - 32 - 55, j, 64, 102, GameData.animationNumber[appearance2Colour], characterTopBottomColours[appearanceBottomColour]); + surface.spriteClipping(i - 32 - 55, j, 64, 102, GameData.animationNumber[appearanceBodyGender], characterTopBottomColours[appearanceTopColour], characterSkinColours[appearanceSkinColour], 0, false); + surface.spriteClipping(i - 32 - 55, j, 64, 102, GameData.animationNumber[appearanceHeadType], characterHairColours[appearanceHairColour], characterSkinColours[appearanceSkinColour], 0, false); + surface.spriteClipping(i - 32, j, 64, 102, GameData.animationNumber[appearance2Colour] + 6, characterTopBottomColours[appearanceBottomColour]); + surface.spriteClipping(i - 32, j, 64, 102, GameData.animationNumber[appearanceBodyGender] + 6, characterTopBottomColours[appearanceTopColour], characterSkinColours[appearanceSkinColour], 0, false); + surface.spriteClipping(i - 32, j, 64, 102, GameData.animationNumber[appearanceHeadType] + 6, characterHairColours[appearanceHairColour], characterSkinColours[appearanceSkinColour], 0, false); + surface.spriteClipping((i - 32) + 55, j, 64, 102, GameData.animationNumber[appearance2Colour] + 12, characterTopBottomColours[appearanceBottomColour]); + surface.spriteClipping((i - 32) + 55, j, 64, 102, GameData.animationNumber[appearanceBodyGender] + 12, characterTopBottomColours[appearanceTopColour], characterSkinColours[appearanceSkinColour], 0, false); + surface.spriteClipping((i - 32) + 55, j, 64, 102, GameData.animationNumber[appearanceHeadType] + 12, characterHairColours[appearanceHairColour], characterSkinColours[appearanceSkinColour], 0, false); + surface.drawSprite(0, gameHeight, spriteMedia + 22); + surface.draw(0, 0); + } + + /* + public URL getDocumentBase() { + return super.getDocumentBase(); + }*/ + + /* + public Graphics getGraphics() { + if (gameFrame != null) + return gameFrame.getGraphics(); + else + return super.getGraphics(); + }*/ + + /* + public URL getCodeBase() { + return super.getCodeBase(); + }*/ + + void drawItem(int x, int y, int w, int h, int id, int tx, int ty) { + int picture = GameData.itemPicture[id] + spriteItem; + int mask = GameData.itemMask[id]; + surface.spriteClipping(x, y, w, h, picture, mask, 0, 0, false); + } + + private void handleGameInput() { + if (systemUpdate > 1) + systemUpdate--; + checkConnection(); + if (logoutTimeout > 0) + logoutTimeout--; + if (super.mouseActionTimeout > 4500 && combatTimeout == 0 && logoutTimeout == 0) { + super.mouseActionTimeout -= 500; + sendLogout(); + return; + } + if (localPlayer.animationCurrent == 8 || localPlayer.animationCurrent == 9) + combatTimeout = 500; + if (combatTimeout > 0) + combatTimeout--; + if (showAppearanceChange) { + handleAppearancePanelControls(); + return; + } + for (int i = 0; i < playerCount; i++) { + GameCharacter character = players[i]; + int k = (character.waypointCurrent + 1) % 10; + if (character.movingStep != k) { + int i1 = -1; + int l2 = character.movingStep; + int j4; + if (l2 < k) + j4 = k - l2; + else + j4 = (10 + k) - l2; + int j5 = 4; + if (j4 > 2) + j5 = (j4 - 1) * 4; + if (character.waypointsX[l2] - character.currentX > magicLoc * 3 || character.waypointsY[l2] - character.currentY > magicLoc * 3 || character.waypointsX[l2] - character.currentX < -magicLoc * 3 || character.waypointsY[l2] - character.currentY < -magicLoc * 3 || j4 > 8) { + character.currentX = character.waypointsX[l2]; + character.currentY = character.waypointsY[l2]; + } else { + if (character.currentX < character.waypointsX[l2]) { + character.currentX += j5; + character.stepCount++; + i1 = 2; + } else if (character.currentX > character.waypointsX[l2]) { + character.currentX -= j5; + character.stepCount++; + i1 = 6; + } + if (character.currentX - character.waypointsX[l2] < j5 && character.currentX - character.waypointsX[l2] > -j5) + character.currentX = character.waypointsX[l2]; + if (character.currentY < character.waypointsY[l2]) { + character.currentY += j5; + character.stepCount++; + if (i1 == -1) + i1 = 4; + else if (i1 == 2) + i1 = 3; + else + i1 = 5; + } else if (character.currentY > character.waypointsY[l2]) { + character.currentY -= j5; + character.stepCount++; + if (i1 == -1) + i1 = 0; + else if (i1 == 2) + i1 = 1; + else + i1 = 7; + } + if (character.currentY - character.waypointsY[l2] < j5 && character.currentY - character.waypointsY[l2] > -j5) + character.currentY = character.waypointsY[l2]; + } + if (i1 != -1) + character.animationCurrent = i1; + if (character.currentX == character.waypointsX[l2] && character.currentY == character.waypointsY[l2]) + character.movingStep = (l2 + 1) % 10; + } else { + character.animationCurrent = character.animationNext; + } + if (character.messageTimeout > 0) + character.messageTimeout--; + if (character.bubbleTimeout > 0) + character.bubbleTimeout--; + if (character.combatTimer > 0) + character.combatTimer--; + if (deathScreenTimeout > 0) { + deathScreenTimeout--; + if (deathScreenTimeout == 0) + showMessage("You have been granted another life. Be more careful this time!", 3); + if (deathScreenTimeout == 0) + showMessage("You retain your skills. Your objects land where you died", 3); + } + } + + for (int j = 0; j < npcCount; j++) { + GameCharacter character_1 = npcs[j]; + int j1 = (character_1.waypointCurrent + 1) % 10; + if (character_1.movingStep != j1) { + int i3 = -1; + int k4 = character_1.movingStep; + int k5; + if (k4 < j1) + k5 = j1 - k4; + else + k5 = (10 + j1) - k4; + int l5 = 4; + if (k5 > 2) + l5 = (k5 - 1) * 4; + if (character_1.waypointsX[k4] - character_1.currentX > magicLoc * 3 || character_1.waypointsY[k4] - character_1.currentY > magicLoc * 3 || character_1.waypointsX[k4] - character_1.currentX < -magicLoc * 3 || character_1.waypointsY[k4] - character_1.currentY < -magicLoc * 3 || k5 > 8) { + character_1.currentX = character_1.waypointsX[k4]; + character_1.currentY = character_1.waypointsY[k4]; + } else { + if (character_1.currentX < character_1.waypointsX[k4]) { + character_1.currentX += l5; + character_1.stepCount++; + i3 = 2; + } else if (character_1.currentX > character_1.waypointsX[k4]) { + character_1.currentX -= l5; + character_1.stepCount++; + i3 = 6; + } + if (character_1.currentX - character_1.waypointsX[k4] < l5 && character_1.currentX - character_1.waypointsX[k4] > -l5) + character_1.currentX = character_1.waypointsX[k4]; + if (character_1.currentY < character_1.waypointsY[k4]) { + character_1.currentY += l5; + character_1.stepCount++; + if (i3 == -1) + i3 = 4; + else if (i3 == 2) + i3 = 3; + else + i3 = 5; + } else if (character_1.currentY > character_1.waypointsY[k4]) { + character_1.currentY -= l5; + character_1.stepCount++; + if (i3 == -1) + i3 = 0; + else if (i3 == 2) + i3 = 1; + else + i3 = 7; + } + if (character_1.currentY - character_1.waypointsY[k4] < l5 && character_1.currentY - character_1.waypointsY[k4] > -l5) + character_1.currentY = character_1.waypointsY[k4]; + } + if (i3 != -1) + character_1.animationCurrent = i3; + if (character_1.currentX == character_1.waypointsX[k4] && character_1.currentY == character_1.waypointsY[k4]) + character_1.movingStep = (k4 + 1) % 10; + } else { + character_1.animationCurrent = character_1.animationNext; + if (character_1.npcId == 43) + character_1.stepCount++; + } + if (character_1.messageTimeout > 0) + character_1.messageTimeout--; + if (character_1.bubbleTimeout > 0) + character_1.bubbleTimeout--; + if (character_1.combatTimer > 0) + character_1.combatTimer--; + } + + if (showUiTab != 2) { + if (Surface.anInt346 > 0) + sleepWordDelayTimer++; + if (Surface.anInt347 > 0) + sleepWordDelayTimer = 0; + Surface.anInt346 = 0; + Surface.anInt347 = 0; + } + for (int l = 0; l < playerCount; l++) { + GameCharacter character = players[l]; + if (character.projectileRange > 0) + character.projectileRange--; + } + + if (cameraAutoAngleDebug) { + if (cameraAutoRotatePlayerX - localPlayer.currentX < -500 || cameraAutoRotatePlayerX - localPlayer.currentX > 500 || cameraAutoRotatePlayerY - localPlayer.currentY < -500 || cameraAutoRotatePlayerY - localPlayer.currentY > 500) { + cameraAutoRotatePlayerX = localPlayer.currentX; + cameraAutoRotatePlayerY = localPlayer.currentY; + } + } else { + if (cameraAutoRotatePlayerX - localPlayer.currentX < -500 || cameraAutoRotatePlayerX - localPlayer.currentX > 500 || cameraAutoRotatePlayerY - localPlayer.currentY < -500 || cameraAutoRotatePlayerY - localPlayer.currentY > 500) { + cameraAutoRotatePlayerX = localPlayer.currentX; + cameraAutoRotatePlayerY = localPlayer.currentY; + } + if (cameraAutoRotatePlayerX != localPlayer.currentX) + cameraAutoRotatePlayerX += (localPlayer.currentX - cameraAutoRotatePlayerX) / (16 + (cameraZoom - 500) / 15); + if (cameraAutoRotatePlayerY != localPlayer.currentY) + cameraAutoRotatePlayerY += (localPlayer.currentY - cameraAutoRotatePlayerY) / (16 + (cameraZoom - 500) / 15); + if (optionCameraModeAuto) { + int k1 = cameraAngle * 32; + int j3 = k1 - cameraRotation; + byte byte0 = 1; + if (j3 != 0) { + anInt707++; + if (j3 > 128) { + byte0 = -1; + j3 = 256 - j3; + } else if (j3 > 0) + byte0 = 1; + else if (j3 < -128) { + byte0 = 1; + j3 = 256 + j3; + } else if (j3 < 0) { + byte0 = -1; + j3 = -j3; + } + cameraRotation += ((anInt707 * j3 + 255) / 256) * byte0; + cameraRotation &= 255;// 0xff; + } else { + anInt707 = 0; + } + } + } + if (sleepWordDelayTimer > 20) { + sleepWordDelay = false; + sleepWordDelayTimer = 0; + } + if (isSleeping) { + if (super.inputTextFinal.length() > 0) + if (super.inputTextFinal.equalsIgnoreCase("::lostcon") && !appletMode) + super.clientStream.closeStream(); + else if (super.inputTextFinal.equalsIgnoreCase("::closecon") && !appletMode) { + closeConnection(); + } else { + super.clientStream.newPacket((Command.CL_SLEEP_WORD)); + super.clientStream.putString(super.inputTextFinal); + if (!sleepWordDelay) { + super.clientStream.putByte(0); + sleepWordDelay = true; + } + super.clientStream.sendPacket(); + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + sleepingStatusText = "Please wait..."; + } + if (super.lastMouseButtonDown == 1 && super.mouseY > 275 && super.mouseY < 310 && super.mouseX > 56 && super.mouseX < 456) { + super.clientStream.newPacket((Command.CL_SLEEP_WORD)); + super.clientStream.putString("-null-"); + if (!sleepWordDelay) { + super.clientStream.putByte(0); + sleepWordDelay = true; + } + super.clientStream.sendPacket(); + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + sleepingStatusText = "Please wait..."; + } + super.lastMouseButtonDown = 0; + return; + } + if (super.mouseY > gameHeight - 4) { + if (super.mouseX > 15 && super.mouseX < 96 && super.lastMouseButtonDown == 1) + messageTabSelected = 0; + if (super.mouseX > 110 && super.mouseX < 194 && super.lastMouseButtonDown == 1) { + messageTabSelected = 1; + panelMessageTabs.controlFlashText[controlTextListChat] = 999999;//0xf423f; + } + if (super.mouseX > 215 && super.mouseX < 295 && super.lastMouseButtonDown == 1) { + messageTabSelected = 2; + panelMessageTabs.controlFlashText[controlTextListQuest] = 999999;//0xf423f; + } + if (super.mouseX > 315 && super.mouseX < 395 && super.lastMouseButtonDown == 1) { + messageTabSelected = 3; + panelMessageTabs.controlFlashText[controlTextListPrivate] = 999999;//0xf423f; + } + if (super.mouseX > 417 && super.mouseX < 497 && super.lastMouseButtonDown == 1) { + showDialogReportAbuseStep = 1; + reportAbuseOffence = 0; + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + } + super.lastMouseButtonDown = 0; + super.mouseButtonDown = 0; + } + panelMessageTabs.handleMouse(super.mouseX, super.mouseY, super.lastMouseButtonDown, super.mouseButtonDown); + if (messageTabSelected > 0 && super.mouseX >= 494 && super.mouseY >= gameHeight - 66) + super.lastMouseButtonDown = 0; + if (panelMessageTabs.isClicked(controlTextListAll)) { + String s = panelMessageTabs.getText(controlTextListAll); + panelMessageTabs.updateText(controlTextListAll, ""); + if (s.startsWith("::")) { + if (s.equalsIgnoreCase("::closecon") && !appletMode) + super.clientStream.closeStream(); + else if (s.equalsIgnoreCase("::logout") && !appletMode) + closeConnection(); + else if (s.equalsIgnoreCase("::lostcon") && !appletMode) + lostConnection(); + else + sendCommandString(s.substring(2)); + } else { + int k3 = ChatMessage.scramble(s); + sendChatMessage(ChatMessage.scrambledbytes, k3); + s = ChatMessage.descramble(ChatMessage.scrambledbytes, 0, k3); + s = WordFilter.filter(s); + localPlayer.messageTimeout = 150; + localPlayer.message = s; + showMessage(localPlayer.name + ": " + s, 2); + } + } + if (messageTabSelected == 0) { + for (int l1 = 0; l1 < 5; l1++) + if (messageHistoryTimeout[l1] > 0) + messageHistoryTimeout[l1]--; + + } + if (deathScreenTimeout != 0) + super.lastMouseButtonDown = 0; + if (showDialogTrade || showDialogDuel) { + if (super.mouseButtonDown != 0) + mouseButtonDownTime++; + else + mouseButtonDownTime = 0; + if (mouseButtonDownTime > 600) + mouseButtonItemCountIncrement += 5000; + else if (mouseButtonDownTime > 450) + mouseButtonItemCountIncrement += 500; + else if (mouseButtonDownTime > 300) + mouseButtonItemCountIncrement += 50; + else if (mouseButtonDownTime > 150) + mouseButtonItemCountIncrement += 5; + else if (mouseButtonDownTime > 50) + mouseButtonItemCountIncrement++; + else if (mouseButtonDownTime > 20 && (mouseButtonDownTime & 5) == 0) + mouseButtonItemCountIncrement++; + } else { + mouseButtonDownTime = 0; + mouseButtonItemCountIncrement = 0; + } + if (super.lastMouseButtonDown == 1) + mouseButtonClick = 1; + else if (super.lastMouseButtonDown == 2) + mouseButtonClick = 2; + scene.setMouseLoc(super.mouseX, super.mouseY); + super.lastMouseButtonDown = 0; + if (optionCameraModeAuto) { + if (anInt707 == 0 || cameraAutoAngleDebug) { + if (super.keyLeft) { + cameraAngle = cameraAngle + 1 & 7; + super.keyLeft = false; + if (!fogOfWar) { + if ((cameraAngle & 1) == 0) + cameraAngle = cameraAngle + 1 & 7; + for (int i2 = 0; i2 < 8; i2++) { + if (isValidCameraAngle(cameraAngle)) + break; + cameraAngle = cameraAngle + 1 & 7; + } + + } + } + if (super.keyRight) { + cameraAngle = cameraAngle + 7 & 7; + super.keyRight = false; + if (!fogOfWar) { + if ((cameraAngle & 1) == 0) + cameraAngle = cameraAngle + 7 & 7; + for (int j2 = 0; j2 < 8; j2++) { + if (isValidCameraAngle(cameraAngle)) + break; + cameraAngle = cameraAngle + 7 & 7; + } + + } + } + } + } else if (super.keyLeft) + cameraRotation = cameraRotation + 2 & 255;// 0xff; + else if (super.keyRight) + cameraRotation = cameraRotation - 2 & 255;// 0xff; + if (fogOfWar && cameraZoom > 550) + cameraZoom -= 4; + else if (!fogOfWar && cameraZoom < 750) + cameraZoom += 4; + if (mouseClickXStep > 0) + mouseClickXStep--; + else if (mouseClickXStep < 0) + mouseClickXStep++; + scene.doSOemthingWithTheFuckinFountainFuck(17);// 17 is fountain + objectAnimationCount++; + if (objectAnimationCount > 5) { + objectAnimationCount = 0; + objectAnimationNumberFireLightningSpell = (objectAnimationNumberFireLightningSpell + 1) % 3; + objectAnimationNumberTorch = (objectAnimationNumberTorch + 1) % 4; + objectAnimationNumberClaw = (objectAnimationNumberClaw + 1) % 5; + } + for (int k2 = 0; k2 < objectCount; k2++) { + int l3 = objectX[k2]; + int l4 = objectY[k2]; + if (l3 >= 0 && l4 >= 0 && l3 < 96 && l4 < 96 && objectId[k2] == 74) + objectModel[k2].rotate(1, 0, 0); + } + + for (int i4 = 0; i4 < teleportBubbleCount; i4++) { + teleportBubbleTime[i4]++; + if (teleportBubbleTime[i4] > 50) { + teleportBubbleCount--; + for (int i5 = i4; i5 < teleportBubbleCount; i5++) { + teleportBubbleX[i5] = teleportBubbleX[i5 + 1]; + teleportBubbleY[i5] = teleportBubbleY[i5 + 1]; + teleportBubbleTime[i5] = teleportBubbleTime[i5 + 1]; + teleportBubbleType[i5] = teleportBubbleType[i5 + 1]; + } + + } + } + + } + + private void renderLoginScreenViewports() { + int rh = 0; + byte rx = 50;//49; + byte ry = 50;//47; + world.loadSection(rx * 48 + 23, ry * 48 + 23, rh); + world.addModels(gameModels); + int x = 9728;// '\u2600' + int y = 6400;// '\u1900' + int zoom = 1100;// '\u044C' + int rotation = 888;// '\u0378' + scene.clipFar3d = 4100; + scene.clipFar2d = 4100; + scene.fogZFalloff = 1; + scene.fogZDistance = 4000; + surface.blackScreen(); + scene.setCamera(x, -world.getElevation(x, y), y, 912, rotation, 0, zoom * 2); + scene.render(); + surface.fade2black(); + surface.fade2black(); + surface.drawBox(0, 0, gameWidth, 6, 0); + for (int j = 6; j >= 1; j--) + surface.drawLineAlpha(0, j, 0, j, gameWidth, 8); + + surface.drawBox(0, 194, 512, 20, 0); + for (int k = 6; k >= 1; k--) + surface.drawLineAlpha(0, k, 0, 194 - k, gameWidth, 8); + + surface.drawSprite(gameWidth / 2 - surface.spriteWidth[spriteMedia + 10] / 2, 15, spriteMedia + 10); // runescape logo + surface.drawSprite(spriteLogo, 0, 0, gameWidth, 200); + surface.drawWorld(spriteLogo); + x = 9216;// '\u2400'; + y = 9216;// '\u2400'; + zoom = 1100;// '\u044C'; + rotation = 888;// '\u0378'; + scene.clipFar3d = 4100; + scene.clipFar2d = 4100; + scene.fogZFalloff = 1; + scene.fogZDistance = 4000; + surface.blackScreen(); + scene.setCamera(x, -world.getElevation(x, y), y, 912, rotation, 0, zoom * 2); + scene.render(); + surface.fade2black(); + surface.fade2black(); + surface.drawBox(0, 0, gameWidth, 6, 0); + for (int l = 6; l >= 1; l--) + surface.drawLineAlpha(0, l, 0, l, gameWidth, 8); + + surface.drawBox(0, 194, gameWidth, 20, 0); + for (int i1 = 6; i1 >= 1; i1--) + surface.drawLineAlpha(0, i1, 0, 194 - i1, gameWidth, 8); + + surface.drawSprite(gameWidth / 2 - surface.spriteWidth[spriteMedia + 10] / 2, 15, spriteMedia + 10); + surface.drawSprite(spriteLogo + 1, 0, 0, gameWidth, 200); // h was 200 + surface.drawWorld(spriteLogo + 1); + + for (int j1 = 0; j1 < 64; j1++) { + scene.removeModel(world.roofModels[0][j1]); + scene.removeModel(world.wallModels[1][j1]); + scene.removeModel(world.roofModels[1][j1]); + scene.removeModel(world.wallModels[2][j1]); + scene.removeModel(world.roofModels[2][j1]); + } + + x = 11136;// '\u2B80'; + y = 10368;// '\u2880'; + zoom = 500;// '\u01F4'; + rotation = 376;// '\u0178'; + scene.clipFar3d = 4100; + scene.clipFar2d = 4100; + scene.fogZFalloff = 1; + scene.fogZDistance = 4000; + surface.blackScreen(); + scene.setCamera(x, -world.getElevation(x, y), y, 912, rotation, 0, zoom * 2); + scene.render(); + surface.fade2black(); + surface.fade2black(); + surface.drawBox(0, 0, gameWidth, 6, 0); + for (int k1 = 6; k1 >= 1; k1--) + surface.drawLineAlpha(0, k1, 0, k1, gameWidth, 8); + + surface.drawBox(0, 194, gameWidth, 20, 0); + for (int l1 = 6; l1 >= 1; l1--) + surface.drawLineAlpha(0, l1, 0, 194, gameWidth, 8); + + surface.drawSprite(gameWidth / 2 - surface.spriteWidth[spriteMedia + 10] / 2, 15, spriteMedia + 10); + surface.drawSprite(spriteMedia + 10, 0, 0, gameWidth, 200); + surface.drawWorld(spriteMedia + 10); + } + + private void createLoginPanels() { + panelLoginWelcome = new Panel(surface, 50); + int y = 40; + int x = gameWidth / 2; + if (!members) { + panelLoginWelcome.addText(x, 200 + y, "Click on an option", 5, true); + panelLoginWelcome.addButtonBackground(x - 100, 240 + y, 120, 35); + panelLoginWelcome.addButtonBackground(x + 100, 240 + y, 120, 35); + panelLoginWelcome.addText(x - 100, 240 + y, "New User", 5, false); + panelLoginWelcome.addText(x + 100, 240 + y, "Existing User", 5, false); + controlWelcomeNewuser = panelLoginWelcome.addButton(x - 100, 240 + y, 120, 35); + controlWelcomeExistinguser = panelLoginWelcome.addButton(x + 100, 240 + y, 120, 35); + } else { + panelLoginWelcome.addText(x, 200 + y, "Welcome to RuneScape", 4, true); + panelLoginWelcome.addText(x, 215 + y, "You need a member account to use this server", 4, true); + panelLoginWelcome.addButtonBackground(x, 250 + y, 200, 35); + panelLoginWelcome.addText(x, 250 + y, "Click here to login", 5, false); + controlWelcomeExistinguser = panelLoginWelcome.addButton(x, 250 + y, 200, 35); + } + panelLoginNewuser = new Panel(surface, 50); + y = 230; + if (referid == 0) { + panelLoginNewuser.addText(x, y + 8, "To create an account please go back to the", 4, true); + y += 20; + panelLoginNewuser.addText(x, y + 8, "www.runescape.com front page, and choose 'create account'", 4, true); + } else if (referid == 1) { + panelLoginNewuser.addText(x, y + 8, "To create an account please click on the", 4, true); + y += 20; + panelLoginNewuser.addText(x, y + 8, "'create account' link below the game window", 4, true); + } else { + panelLoginNewuser.addText(x, y + 8, "To create an account please go back to the", 4, true); + y += 20; + panelLoginNewuser.addText(x, y + 8, "runescape front webpage and choose 'create account'", 4, true); + } + y += 30; + panelLoginNewuser.addButtonBackground(x, y + 17, 150, 34); + panelLoginNewuser.addText(x, y + 17, "Ok", 5, false); + controlLoginNewOk = panelLoginNewuser.addButton(x, y + 17, 150, 34); + panelLoginExistinguser = new Panel(surface, 50); + y = 230; + controlLoginStatus = panelLoginExistinguser.addText(x, y - 10, "Please enter your username and password", 4, true); + y += 28; + panelLoginExistinguser.addButtonBackground(x - 116, y, 200, 40); + panelLoginExistinguser.addText(x - 116, y - 10, "Username:", 4, false); + controlLoginUser = panelLoginExistinguser.addTextInput(x - 116, y + 10, 200, 40, 4, 12, false, false); + y += 47; + panelLoginExistinguser.addButtonBackground(x - 66, y, 200, 40); + panelLoginExistinguser.addText(x - 66, y - 10, "Password:", 4, false); + controlLoginPass = panelLoginExistinguser.addTextInput(x - 66, y + 10, 200, 40, 4, 20, true, false); + y -= 55; + panelLoginExistinguser.addButtonBackground(x + 154, y, 120, 25); + panelLoginExistinguser.addText(x + 154, y, "Ok", 4, false); + controlLoginOk = panelLoginExistinguser.addButton(x + 154, y, 120, 25); + y += 30; + panelLoginExistinguser.addButtonBackground(x + 154, y, 120, 25); + panelLoginExistinguser.addText(x + 154, y, "Cancel", 4, false); + controlLoginCancel = panelLoginExistinguser.addButton(x + 154, y, 120, 25); + y += 30; + panelLoginExistinguser.setFocus(controlLoginUser); + } + + private void drawUiTabInventory(boolean nomenus) { + int uiX = surface.width2 - 248; + surface.drawSprite(uiX, 3, spriteMedia + 1); + for (int itemIndex = 0; itemIndex < inventoryMaxItemCount; itemIndex++) { + int slotX = uiX + (itemIndex % 5) * 49; + int slotY = 36 + (itemIndex / 5) * 34; + if (itemIndex < inventoryItemsCount && inventoryEquipped[itemIndex] == 1) + surface.drawBoxAlpha(slotX, slotY, 49, 34, 0xff0000, 128); + else + surface.drawBoxAlpha(slotX, slotY, 49, 34, Surface.rgb2long(181, 181, 181), 128); + if (itemIndex < inventoryItemsCount) { + surface.spriteClipping(slotX, slotY, 48, 32, spriteItem + GameData.itemPicture[inventoryItemId[itemIndex]], GameData.itemMask[inventoryItemId[itemIndex]], 0, 0, false); + if (GameData.itemStackable[inventoryItemId[itemIndex]] == 0) + surface.drawstring(String.valueOf(inventoryItemStackCount[itemIndex]), slotX + 1, slotY + 10, 1, 0xffff00); + } + } + + for (int rows = 1; rows <= 4; rows++) + surface.drawLineVert(uiX + rows * 49, 36, (inventoryMaxItemCount / 5) * 34, 0); + + for (int cols = 1; cols <= inventoryMaxItemCount / 5 - 1; cols++) + surface.drawLineHoriz(uiX, 36 + cols * 34, 245, 0); + + if (!nomenus) + return; + int mouseX = super.mouseX - (surface.width2 - 248); + int mouseY = super.mouseY - 36; + if (mouseX >= 0 && mouseY >= 0 && mouseX < 248 && mouseY < (inventoryMaxItemCount / 5) * 34) { + int itemIndex = mouseX / 49 + (mouseY / 34) * 5; + if (itemIndex < inventoryItemsCount) { + int i2 = inventoryItemId[itemIndex]; + if (selectedSpell >= 0) { + if (GameData.spellType[selectedSpell] == 3) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 600; + menuSourceType[menuItemsCount] = itemIndex; + menuSourceIndex[menuItemsCount] = selectedSpell; + menuItemsCount++; + return; + } + } else { + if (selectedItemInventoryIndex >= 0) { + menuItemText1[menuItemsCount] = "Use " + selectedItemName + " with"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 610; + menuSourceType[menuItemsCount] = itemIndex; + menuSourceIndex[menuItemsCount] = selectedItemInventoryIndex; + menuItemsCount++; + return; + } + if (inventoryEquipped[itemIndex] == 1) { + menuItemText1[menuItemsCount] = "Remove"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 620; + menuSourceType[menuItemsCount] = itemIndex; + menuItemsCount++; + } else if (GameData.itemWearable[i2] != 0) { + if ((GameData.itemWearable[i2] & 24) != 0)// 0x18 + menuItemText1[menuItemsCount] = "Wield"; + else + menuItemText1[menuItemsCount] = "Wear"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 630; + menuSourceType[menuItemsCount] = itemIndex; + menuItemsCount++; + } + if (!GameData.itemCommand[i2].equals("")) { + menuItemText1[menuItemsCount] = GameData.itemCommand[i2]; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 640; + menuSourceType[menuItemsCount] = itemIndex; + menuItemsCount++; + } + menuItemText1[menuItemsCount] = "Use"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 650; + menuSourceType[menuItemsCount] = itemIndex; + menuItemsCount++; + menuItemText1[menuItemsCount] = "Drop"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 660; + menuSourceType[menuItemsCount] = itemIndex; + menuItemsCount++; + menuItemText1[menuItemsCount] = "Examine"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[i2]; + menuItemID[menuItemsCount] = 3600; + menuSourceType[menuItemsCount] = i2; + menuItemsCount++; + } + } + } + } + + private void autorotateCamera() { + if ((cameraAngle & 1) == 1 && isValidCameraAngle(cameraAngle)) + return; + if ((cameraAngle & 1) == 0 && isValidCameraAngle(cameraAngle)) { + if (isValidCameraAngle(cameraAngle + 1 & 7)) { + cameraAngle = cameraAngle + 1 & 7; + return; + } + if (isValidCameraAngle(cameraAngle + 7 & 7)) + cameraAngle = cameraAngle + 7 & 7; + return; + } + int ai[] = { + 1, -1, 2, -2, 3, -3, 4 + }; + for (int i = 0; i < 7; i++) { + if (!isValidCameraAngle(cameraAngle + ai[i] + 8 & 7)) + continue; + cameraAngle = cameraAngle + ai[i] + 8 & 7; + break; + } + + if ((cameraAngle & 1) == 0 && isValidCameraAngle(cameraAngle)) { + if (isValidCameraAngle(cameraAngle + 1 & 7)) { + cameraAngle = cameraAngle + 1 & 7; + return; + } + if (isValidCameraAngle(cameraAngle + 7 & 7)) + cameraAngle = cameraAngle + 7 & 7; + } + } + + private void drawRightClickMenu() { + if (mouseButtonClick != 0) { + for (int i = 0; i < menuItemsCount; i++) { + int k = menuX + 2; + int i1 = menuY + 27 + i * 15; + if (super.mouseX <= k - 2 || super.mouseY <= i1 - 12 || super.mouseY >= i1 + 4 || super.mouseX >= (k - 3) + menuWidth) + continue; + menuItemClick(menuIndices[i]); + break; + } + + mouseButtonClick = 0; + showRightClickMenu = false; + return; + } + if (super.mouseX < menuX - 10 || super.mouseY < menuY - 10 || super.mouseX > menuX + menuWidth + 10 || super.mouseY > menuY + menuHeight + 10) { + showRightClickMenu = false; + return; + } + surface.drawBoxAlpha(menuX, menuY, menuWidth, menuHeight, 0xd0d0d0, 160); + surface.drawstring("Choose option", menuX + 2, menuY + 12, 1, 65535); + for (int j = 0; j < menuItemsCount; j++) { + int l = menuX + 2; + int j1 = menuY + 27 + j * 15; + int k1 = 0xffffff; + if (super.mouseX > l - 2 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && super.mouseX < (l - 3) + menuWidth) + k1 = 0xffff00; + surface.drawstring(menuItemText1[menuIndices[j]] + " " + menuItemText2[menuIndices[j]], l, j1, 1, k1); + } + + } + + private void drawUiTabMinimap(boolean nomenus) { + int uiX = surface.width2 - 199; + int uiWidth = 156;// '\234'; + int uiHeight = 152;// '\230'; + surface.drawSprite(uiX - 49, 3, spriteMedia + 2); + uiX += 40; + surface.drawBox(uiX, 36, uiWidth, uiHeight, 0); + surface.setBounds(uiX, 36, uiX + uiWidth, 36 + uiHeight); + int k = 192 + minimapRandom_2; + int i1 = cameraRotation + minimapRandom_1 & 255;//0xff; + int k1 = ((localPlayer.currentX - 6040) * 3 * k) / 2048; + int i3 = ((localPlayer.currentY - 6040) * 3 * k) / 2048; + int k4 = Scene.sin2048Cache[1024 - i1 * 4 & 0x3ff]; + int i5 = Scene.sin2048Cache[(1024 - i1 * 4 & 0x3ff) + 1024]; + int k5 = i3 * k4 + k1 * i5 >> 18; + i3 = i3 * i5 - k1 * k4 >> 18; + k1 = k5; + surface.drawMinimapSprite((uiX + uiWidth / 2) - k1, 36 + uiHeight / 2 + i3, spriteMedia - 1, i1 + 64 & 255, k);// landscape + for (int i = 0; i < objectCount; i++) { + int l1 = (((objectX[i] * magicLoc + 64) - localPlayer.currentX) * 3 * k) / 2048; + int j3 = (((objectY[i] * magicLoc + 64) - localPlayer.currentY) * 3 * k) / 2048; + int l5 = j3 * k4 + l1 * i5 >> 18; + j3 = j3 * i5 - l1 * k4 >> 18; + l1 = l5; + drawMinimapEntity(uiX + uiWidth / 2 + l1, (36 + uiHeight / 2) - j3, 65535); + } + + for (int j7 = 0; j7 < groundItemCount; j7++) { + int i2 = (((groundItemX[j7] * magicLoc + 64) - localPlayer.currentX) * 3 * k) / 2048; + int k3 = (((groundItemY[j7] * magicLoc + 64) - localPlayer.currentY) * 3 * k) / 2048; + int i6 = k3 * k4 + i2 * i5 >> 18; + k3 = k3 * i5 - i2 * k4 >> 18; + i2 = i6; + drawMinimapEntity(uiX + uiWidth / 2 + i2, (36 + uiHeight / 2) - k3, 0xff0000); + } + + for (int k7 = 0; k7 < npcCount; k7++) { + GameCharacter character = npcs[k7]; + int j2 = ((character.currentX - localPlayer.currentX) * 3 * k) / 2048; + int l3 = ((character.currentY - localPlayer.currentY) * 3 * k) / 2048; + int j6 = l3 * k4 + j2 * i5 >> 18; + l3 = l3 * i5 - j2 * k4 >> 18; + j2 = j6; + drawMinimapEntity(uiX + uiWidth / 2 + j2, (36 + uiHeight / 2) - l3, 0xffff00); + } + + for (int l7 = 0; l7 < playerCount; l7++) { + GameCharacter character_1 = players[l7]; + int k2 = ((character_1.currentX - localPlayer.currentX) * 3 * k) / 2048; + int i4 = ((character_1.currentY - localPlayer.currentY) * 3 * k) / 2048; + int k6 = i4 * k4 + k2 * i5 >> 18; + i4 = i4 * i5 - k2 * k4 >> 18; + k2 = k6; + int j8 = 0xffffff; + for (int k8 = 0; k8 < super.friendListCount; k8++) { + if (character_1.hash != super.friendListHashes[k8] || super.friendListOnline[k8] != 255) + continue; + j8 = 65280; + break; + } + + drawMinimapEntity(uiX + uiWidth / 2 + k2, (36 + uiHeight / 2) - i4, j8); + } + + surface.drawCircle(uiX + uiWidth / 2, 36 + uiHeight / 2, 2, 0xffffff, 255); + surface.drawMinimapSprite(uiX + 19, 55, spriteMedia + 24, cameraRotation + 128 & 255, 128);// compass + surface.setBounds(0, 0, gameWidth, gameHeight + 12); + if (!nomenus) + return; + int mouseX = super.mouseX - (surface.width2 - 199); + int mouseY = super.mouseY - 36; + if (mouseX >= 40 && mouseY >= 0 && mouseX < 196 && mouseY < 152) { + int c1 = 156;// '\234'; + int c3 = 152;// '\230'; + int l = 192 + minimapRandom_2; + int j1 = cameraRotation + minimapRandom_1 & 255;// 0xff + int j = surface.width2 - 199; + j += 40; + int dx = ((super.mouseX - (j + c1 / 2)) * 16384) / (3 * l); + int dy = ((super.mouseY - (36 + c3 / 2)) * 16384) / (3 * l); + int l4 = Scene.sin2048Cache[1024 - j1 * 4 & 1023];// 0x3ff + int j5 = Scene.sin2048Cache[(1024 - j1 * 4 & 1023) + 1024];// 0x3ff + int l6 = dy * l4 + dx * j5 >> 15; + dy = dy * j5 - dx * l4 >> 15; + dx = l6; + dx += localPlayer.currentX; + dy = localPlayer.currentY - dy; + if (mouseButtonClick == 1) + walkToActionSource(localRegionX, localRegionY, dx / 128, dy / 128, false); + mouseButtonClick = 0; + } + } + + private void drawDialogTradeConfirm() { + byte dialogX = 22; + byte dialogY = 36; + surface.drawBox(dialogX, dialogY, 468, 16, 192); + surface.drawBoxAlpha(dialogX, dialogY + 16, 468, 246, 0x989898, 160); + surface.drawStringCenter("Please confirm your trade with @yel@" + Utility.hash2username(tradeRecipientConfirmHash), dialogX + 234, dialogY + 12, 1, 0xffffff); + surface.drawStringCenter("You are about to give:", dialogX + 117, dialogY + 30, 1, 0xffff00); + for (int j = 0; j < tradeConfirmItemsCount; j++) { + String s = GameData.itemName[tradeConfirmItems[j]]; + if (GameData.itemStackable[tradeConfirmItems[j]] == 0) + s = s + " x " + formatNumber(tradeConfirmItemCount[j]); + surface.drawStringCenter(s, dialogX + 117, dialogY + 42 + j * 12, 1, 0xffffff); + } + + if (tradeConfirmItemsCount == 0) + surface.drawStringCenter("Nothing!", dialogX + 117, dialogY + 42, 1, 0xffffff); + surface.drawStringCenter("In return you will receive:", dialogX + 351, dialogY + 30, 1, 0xffff00); + for (int k = 0; k < tradeRecipientConfirmItemsCount; k++) { + String s1 = GameData.itemName[tradeRecipientConfirmItems[k]]; + if (GameData.itemStackable[tradeRecipientConfirmItems[k]] == 0) + s1 = s1 + " x " + formatNumber(tradeRecipientConfirmItemCount[k]); + surface.drawStringCenter(s1, dialogX + 351, dialogY + 42 + k * 12, 1, 0xffffff); + } + + if (tradeRecipientConfirmItemsCount == 0) + surface.drawStringCenter("Nothing!", dialogX + 351, dialogY + 42, 1, 0xffffff); + surface.drawStringCenter("Are you sure you want to do this?", dialogX + 234, dialogY + 200, 4, 65535); + surface.drawStringCenter("There is NO WAY to reverse a trade if you change your mind.", dialogX + 234, dialogY + 215, 1, 0xffffff); + surface.drawStringCenter("Remember that not all players are trustworthy", dialogX + 234, dialogY + 230, 1, 0xffffff); + if (!tradeConfirmAccepted) { + surface.drawSprite((dialogX + 118) - 35, dialogY + 238, spriteMedia + 25); + surface.drawSprite((dialogX + 352) - 35, dialogY + 238, spriteMedia + 26); + } else { + surface.drawStringCenter("Waiting for other player...", dialogX + 234, dialogY + 250, 1, 0xffff00); + } + if (mouseButtonClick == 1) { + if (super.mouseX < dialogX || super.mouseY < dialogY || super.mouseX > dialogX + 468 || super.mouseY > dialogY + 262) { + showDialogTradeConfirm = false; + super.clientStream.newPacket((Command.CL_TRADE_DECLINE)); + super.clientStream.sendPacket(); + } + if (super.mouseX >= (dialogX + 118) - 35 && super.mouseX <= dialogX + 118 + 70 && super.mouseY >= dialogY + 238 && super.mouseY <= dialogY + 238 + 21) { + tradeConfirmAccepted = true; + super.clientStream.newPacket((Command.CL_TRADE_CONFIRM_ACCEPT)); + super.clientStream.sendPacket(); + } + if (super.mouseX >= (dialogX + 352) - 35 && super.mouseX <= dialogX + 353 + 70 && super.mouseY >= dialogY + 238 && super.mouseY <= dialogY + 238 + 21) { + showDialogTradeConfirm = false; + super.clientStream.newPacket((Command.CL_TRADE_DECLINE)); + super.clientStream.sendPacket(); + } + mouseButtonClick = 0; + } + } + + private void setActiveUiTab() { + if (showUiTab == 0 && super.mouseX >= surface.width2 - 35 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 && super.mouseY < 35) + showUiTab = 1; + if (showUiTab == 0 && super.mouseX >= surface.width2 - 35 - 33 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 33 && super.mouseY < 35) { + showUiTab = 2; + minimapRandom_1 = (int) (Math.random() * 13D) - 6; + minimapRandom_2 = (int) (Math.random() * 23D) - 11; + } + if (showUiTab == 0 && super.mouseX >= surface.width2 - 35 - 66 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 66 && super.mouseY < 35) + showUiTab = 3; + if (showUiTab == 0 && super.mouseX >= surface.width2 - 35 - 99 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 99 && super.mouseY < 35) + showUiTab = 4; + if (showUiTab == 0 && super.mouseX >= surface.width2 - 35 - 132 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 132 && super.mouseY < 35) + showUiTab = 5; + if (showUiTab == 0 && super.mouseX >= surface.width2 - 35 - 165 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 165 && super.mouseY < 35) + showUiTab = 6; + if (showUiTab != 0 && super.mouseX >= surface.width2 - 35 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 && super.mouseY < 26) + showUiTab = 1; + if (showUiTab != 0 && showUiTab != 2 && super.mouseX >= surface.width2 - 35 - 33 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 33 && super.mouseY < 26) { + showUiTab = 2; + minimapRandom_1 = (int) (Math.random() * 13D) - 6; + minimapRandom_2 = (int) (Math.random() * 23D) - 11; + } + if (showUiTab != 0 && super.mouseX >= surface.width2 - 35 - 66 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 66 && super.mouseY < 26) + showUiTab = 3; + if (showUiTab != 0 && super.mouseX >= surface.width2 - 35 - 99 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 99 && super.mouseY < 26) + showUiTab = 4; + if (showUiTab != 0 && super.mouseX >= surface.width2 - 35 - 132 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 132 && super.mouseY < 26) + showUiTab = 5; + if (showUiTab != 0 && super.mouseX >= surface.width2 - 35 - 165 && super.mouseY >= 3 && super.mouseX < surface.width2 - 3 - 165 && super.mouseY < 26) + showUiTab = 6; + if (showUiTab == 1 && (super.mouseX < surface.width2 - 248 || super.mouseY > 36 + (inventoryMaxItemCount / 5) * 34)) + showUiTab = 0; + if (showUiTab == 3 && (super.mouseX < surface.width2 - 199 || super.mouseY > 316)) + showUiTab = 0; + if ((showUiTab == 2 || showUiTab == 4 || showUiTab == 5) && (super.mouseX < surface.width2 - 199 || super.mouseY > 240)) + showUiTab = 0; + if (showUiTab == 6 && (super.mouseX < surface.width2 - 199 || super.mouseY > 311)) + showUiTab = 0; + } + + private void drawOptionMenu() { + if (mouseButtonClick != 0) { + for (int i = 0; i < optionMenuCount; i++) { + if (super.mouseX >= surface.textWidth(optionMenuEntry[i], 1) || super.mouseY <= i * 12 || super.mouseY >= 12 + i * 12) + continue; + super.clientStream.newPacket((Command.CL_CHOOSE_OPTION)); + super.clientStream.putByte(i); + super.clientStream.sendPacket(); + break; + } + + mouseButtonClick = 0; + showOptionMenu = false; + return; + } + for (int j = 0; j < optionMenuCount; j++) { + int k = 65535; + if (super.mouseX < surface.textWidth(optionMenuEntry[j], 1) && super.mouseY > j * 12 && super.mouseY < 12 + j * 12) + k = 0xff0000; + surface.drawstring(optionMenuEntry[j], 6, 12 + j * 12, 1, k); + } + + } + + void drawNpc(int x, int y, int w, int h, int id, int tx, int ty) { + GameCharacter character = npcs[id]; + int l1 = character.animationCurrent + (cameraRotation + 16) / 32 & 7; + boolean flag = false; + int i2 = l1; + if (i2 == 5) { + i2 = 3; + flag = true; + } else if (i2 == 6) { + i2 = 2; + flag = true; + } else if (i2 == 7) { + i2 = 1; + flag = true; + } + int j2 = i2 * 3 + npcWalkModel[(character.stepCount / GameData.npcWalkModel[character.npcId]) % 4]; + if (character.animationCurrent == 8) { + i2 = 5; + l1 = 2; + flag = false; + x -= (GameData.npcCombatAnimation[character.npcId] * ty) / 100; + j2 = i2 * 3 + npcCombatModelArray1[(loginTimer / (GameData.npcCombatModel[character.npcId] - 1)) % 8]; + } else if (character.animationCurrent == 9) { + i2 = 5; + l1 = 2; + flag = true; + x += (GameData.npcCombatAnimation[character.npcId] * ty) / 100; + j2 = i2 * 3 + npcCombatModelArray2[(loginTimer / GameData.npcCombatModel[character.npcId]) % 8]; + } + for (int k2 = 0; k2 < 12; k2++) { + int l2 = npcAnimationArray[l1][k2]; + int k3 = GameData.npcSprite[character.npcId][l2]; + if (k3 >= 0) { + int i4 = 0; + int j4 = 0; + int k4 = j2; + if (flag && i2 >= 1 && i2 <= 3 && GameData.animationHasF[k3] == 1) + k4 += 15; + if (i2 != 5 || GameData.animationHasA[k3] == 1) { + int l4 = k4 + GameData.animationNumber[k3]; + i4 = (i4 * w) / surface.spriteWidthFull[l4]; + j4 = (j4 * h) / surface.spriteHeightFull[l4]; + int i5 = (w * surface.spriteWidthFull[l4]) / surface.spriteWidthFull[GameData.animationNumber[k3]]; + i4 -= (i5 - w) / 2; + int col = GameData.animationCharacterColour[k3]; + int skincol = 0; + if (col == 1) { + col = GameData.npcColourHair[character.npcId]; + skincol = GameData.npcColourSkin[character.npcId]; + } else if (col == 2) { + col = GameData.npcColourTop[character.npcId]; + skincol = GameData.npcColourSkin[character.npcId]; + } else if (col == 3) { + col = GameData.npcColorBottom[character.npcId]; + skincol = GameData.npcColourSkin[character.npcId]; + } + surface.spriteClipping(x + i4, y + j4, i5, h, l4, col, skincol, tx, flag); + } + } + } + + if (character.messageTimeout > 0) { + receivedMessageMidPoint[receivedMessagesCount] = surface.textWidth(character.message, 1) / 2; + if (receivedMessageMidPoint[receivedMessagesCount] > 150) + receivedMessageMidPoint[receivedMessagesCount] = 150; + receivedMessageHeight[receivedMessagesCount] = (surface.textWidth(character.message, 1) / 300) * surface.textHeight(1); + receivedMessageX[receivedMessagesCount] = x + w / 2; + receivedMessageY[receivedMessagesCount] = y; + receivedMessages[receivedMessagesCount++] = character.message; + } + if (character.animationCurrent == 8 || character.animationCurrent == 9 || character.combatTimer != 0) { + if (character.combatTimer > 0) { + int i3 = x; + if (character.animationCurrent == 8) + i3 -= (20 * ty) / 100; + else if (character.animationCurrent == 9) + i3 += (20 * ty) / 100; + int l3 = (character.healthCurrent * 30) / character.healthMax; + healthBarX[healthBarCount] = i3 + w / 2; + healthBarY[healthBarCount] = y; + healthBarMissing[healthBarCount++] = l3; + } + if (character.combatTimer > 150) { + int j3 = x; + if (character.animationCurrent == 8) + j3 -= (10 * ty) / 100; + else if (character.animationCurrent == 9) + j3 += (10 * ty) / 100; + surface.drawSprite((j3 + w / 2) - 12, (y + h / 2) - 12, spriteMedia + 12); + surface.drawStringCenter(String.valueOf(character.damageTaken), (j3 + w / 2) - 1, y + h / 2 + 5, 3, 0xffffff); + } + } + } + + /*public Image createImage(int i, int j) { + if (gameFrame != null) + return gameFrame.createImage(i, j); + + return super.createImage(i, j); + }*/ + + private void walkToWallObject(int i, int j, int k) { + if (k == 0) { + walkToActionSource(localRegionX, localRegionY, i, j - 1, i, j, false, true); + return; + } + if (k == 1) { + walkToActionSource(localRegionX, localRegionY, i - 1, j, i, j, false, true); + return; + } else { + walkToActionSource(localRegionX, localRegionY, i, j, i, j, true, true); + return; + } + } + + private void loadGameConfig() { + byte buff[] = readDataFile("config" + Version.CONFIG + ".jag", "Configuration", 10); + + if (buff == null) { + errorLoadingData = true; + return; + } + + GameData.loadData(buff, members); + + byte abyte1[] = readDataFile("filter" + Version.FILTER + ".jag", "Chat system", 15); + + if (abyte1 == null) { + errorLoadingData = true; + return; + } else { + byte buffragments[] = Utility.loadData("fragmentsenc.txt", 0, abyte1); + byte buffbandenc[] = Utility.loadData("badenc.txt", 0, abyte1); + byte buffhostenc[] = Utility.loadData("hostenc.txt", 0, abyte1); + byte bufftldlist[] = Utility.loadData("tldlist.txt", 0, abyte1); + WordFilter.loadFilters(new Buffer(buffragments), new Buffer(buffbandenc), new Buffer(buffhostenc), new Buffer(bufftldlist)); + return; + } + } + + private GameCharacter addNpc(int serverIndex, int x, int y, int sprite, int type) { + if (npcsServer[serverIndex] == null) { + npcsServer[serverIndex] = new GameCharacter(); + npcsServer[serverIndex].serverIndex = serverIndex; + } + GameCharacter character = npcsServer[serverIndex]; + boolean foundNpc = false; + for (int i = 0; i < npcCacheCount; i++) { + if (npcsCache[i].serverIndex != serverIndex) + continue; + foundNpc = true; + break; + } + + if (foundNpc) { + character.npcId = type; + character.animationNext = sprite; + int waypointIdx = character.waypointCurrent; + if (x != character.waypointsX[waypointIdx] || y != character.waypointsY[waypointIdx]) { + character.waypointCurrent = waypointIdx = (waypointIdx + 1) % 10; + character.waypointsX[waypointIdx] = x; + character.waypointsY[waypointIdx] = y; + } + } else { + character.serverIndex = serverIndex; + character.movingStep = 0; + character.waypointCurrent = 0; + character.waypointsX[0] = character.currentX = x; + character.waypointsY[0] = character.currentY = y; + character.npcId = type; + character.animationNext = character.animationCurrent = sprite; + character.stepCount = 0; + } + npcs[npcCount++] = character; + return character; + } + + protected void resetLoginVars() { + systemUpdate = 0; + loginScreen = 0; + loggedIn = 0; + logoutTimeout = 0; + } + + private void drawDialogBank() { + int dialogWidth = 408;// '\u0198'; + int dialogHeight = 334;// '\u014E'; + if (bankActivePage > 0 && bankItemCount <= 48) + bankActivePage = 0; + if (bankActivePage > 1 && bankItemCount <= 96) + bankActivePage = 1; + if (bankActivePage > 2 && bankItemCount <= 144) + bankActivePage = 2; + if (bankSelectedItemSlot >= bankItemCount || bankSelectedItemSlot < 0) + bankSelectedItemSlot = -1; + if (bankSelectedItemSlot != -1 && bankItems[bankSelectedItemSlot] != bankSelectedItem) { + bankSelectedItemSlot = -1; + bankSelectedItem = -2; + } + if (mouseButtonClick != 0) { + mouseButtonClick = 0; + int mouseX = super.mouseX - (gameWidth / 2 - dialogWidth / 2); + int mouseY = super.mouseY - (gameHeight / 2 - dialogHeight / 2); + //int mouseX = super.mouseX - (256 - dialogWidth / 2); + //int mouseY = super.mouseY - (170 - dialogHeight / 2); + if (mouseX >= 0 && mouseY >= 12 && mouseX < 408 && mouseY < 280) { + int i1 = bankActivePage * 48; + for (int l1 = 0; l1 < 6; l1++) { + for (int j2 = 0; j2 < 8; j2++) { + int l6 = 7 + j2 * 49; + int j7 = 28 + l1 * 34; + if (mouseX > l6 && mouseX < l6 + 49 && mouseY > j7 && mouseY < j7 + 34 && i1 < bankItemCount && bankItems[i1] != -1) { + bankSelectedItem = bankItems[i1]; + bankSelectedItemSlot = i1; + } + i1++; + } + + } + + mouseX = 256 - dialogWidth / 2; + mouseY = 170 - dialogHeight / 2; + int slot; + if (bankSelectedItemSlot < 0) + slot = -1; + else + slot = bankItems[bankSelectedItemSlot]; + if (slot != -1) { + int j1 = bankItemsCount[bankSelectedItemSlot]; + if (GameData.itemStackable[slot] == 1 && j1 > 1) + j1 = 1; + if (j1 >= 1 && super.mouseX >= mouseX + 220 && super.mouseY >= mouseY + 238 && super.mouseX < mouseX + 250 && super.mouseY <= mouseY + 249) { + super.clientStream.newPacket((Command.CL_BANK_WITHDRAW)); + super.clientStream.putShort(slot); + super.clientStream.putShort(1); + super.clientStream.putInt(0x12345678); + super.clientStream.sendPacket(); + } + if (j1 >= 5 && super.mouseX >= mouseX + 250 && super.mouseY >= mouseY + 238 && super.mouseX < mouseX + 280 && super.mouseY <= mouseY + 249) { + super.clientStream.newPacket((Command.CL_BANK_WITHDRAW)); + super.clientStream.putShort(slot); + super.clientStream.putShort(5); + super.clientStream.putInt(0x12345678); + super.clientStream.sendPacket(); + } + if (j1 >= 25 && super.mouseX >= mouseX + 280 && super.mouseY >= mouseY + 238 && super.mouseX < mouseX + 305 && super.mouseY <= mouseY + 249) { + super.clientStream.newPacket((Command.CL_BANK_WITHDRAW)); + super.clientStream.putShort(slot); + super.clientStream.putShort(25); + super.clientStream.putInt(0x12345678); + super.clientStream.sendPacket(); + } + if (j1 >= 100 && super.mouseX >= mouseX + 305 && super.mouseY >= mouseY + 238 && super.mouseX < mouseX + 335 && super.mouseY <= mouseY + 249) { + super.clientStream.newPacket((Command.CL_BANK_WITHDRAW)); + super.clientStream.putShort(slot); + super.clientStream.putShort(100); + super.clientStream.putInt(0x12345678); + super.clientStream.sendPacket(); + } + if (j1 >= 500 && super.mouseX >= mouseX + 335 && super.mouseY >= mouseY + 238 && super.mouseX < mouseX + 368 && super.mouseY <= mouseY + 249) { + super.clientStream.newPacket((Command.CL_BANK_WITHDRAW)); + super.clientStream.putShort(slot); + super.clientStream.putShort(500); + super.clientStream.putInt(0x12345678); + super.clientStream.sendPacket(); + } + if (j1 >= 2500 && super.mouseX >= mouseX + 370 && super.mouseY >= mouseY + 238 && super.mouseX < mouseX + 400 && super.mouseY <= mouseY + 249) { + super.clientStream.newPacket((Command.CL_BANK_WITHDRAW)); + super.clientStream.putShort(slot); + super.clientStream.putShort(2500); + super.clientStream.putInt(0x12345678); + super.clientStream.sendPacket(); + } + if (getInventoryCount(slot) >= 1 && super.mouseX >= mouseX + 220 && super.mouseY >= mouseY + 263 && super.mouseX < mouseX + 250 && super.mouseY <= mouseY + 274) { + super.clientStream.newPacket((Command.CL_BANK_DEPOSIT)); + super.clientStream.putShort(slot); + super.clientStream.putShort(1); + super.clientStream.putInt(0x87654321); + super.clientStream.sendPacket(); + } + if (getInventoryCount(slot) >= 5 && super.mouseX >= mouseX + 250 && super.mouseY >= mouseY + 263 && super.mouseX < mouseX + 280 && super.mouseY <= mouseY + 274) { + super.clientStream.newPacket((Command.CL_BANK_DEPOSIT)); + super.clientStream.putShort(slot); + super.clientStream.putShort(5); + super.clientStream.putInt(0x87654321); + super.clientStream.sendPacket(); + } + if (getInventoryCount(slot) >= 25 && super.mouseX >= mouseX + 280 && super.mouseY >= mouseY + 263 && super.mouseX < mouseX + 305 && super.mouseY <= mouseY + 274) { + super.clientStream.newPacket((Command.CL_BANK_DEPOSIT)); + super.clientStream.putShort(slot); + super.clientStream.putShort(25); + super.clientStream.putInt(0x87654321); + super.clientStream.sendPacket(); + } + if (getInventoryCount(slot) >= 100 && super.mouseX >= mouseX + 305 && super.mouseY >= mouseY + 263 && super.mouseX < mouseX + 335 && super.mouseY <= mouseY + 274) { + super.clientStream.newPacket((Command.CL_BANK_DEPOSIT)); + super.clientStream.putShort(slot); + super.clientStream.putShort(100); + super.clientStream.putInt(0x87654321); + super.clientStream.sendPacket(); + } + if (getInventoryCount(slot) >= 500 && super.mouseX >= mouseX + 335 && super.mouseY >= mouseY + 263 && super.mouseX < mouseX + 368 && super.mouseY <= mouseY + 274) { + super.clientStream.newPacket((Command.CL_BANK_DEPOSIT)); + super.clientStream.putShort(slot); + super.clientStream.putShort(500); + super.clientStream.putInt(0x87654321); + super.clientStream.sendPacket(); + } + if (getInventoryCount(slot) >= 2500 && super.mouseX >= mouseX + 370 && super.mouseY >= mouseY + 263 && super.mouseX < mouseX + 400 && super.mouseY <= mouseY + 274) { + super.clientStream.newPacket((Command.CL_BANK_DEPOSIT)); + super.clientStream.putShort(slot); + super.clientStream.putShort(2500); + super.clientStream.putInt(0x87654321); + super.clientStream.sendPacket(); + } + } + } else if (bankItemCount > 48 && mouseX >= 50 && mouseX <= 115 && mouseY <= 12) + bankActivePage = 0; + else if (bankItemCount > 48 && mouseX >= 115 && mouseX <= 180 && mouseY <= 12) + bankActivePage = 1; + else if (bankItemCount > 96 && mouseX >= 180 && mouseX <= 245 && mouseY <= 12) + bankActivePage = 2; + else if (bankItemCount > 144 && mouseX >= 245 && mouseX <= 310 && mouseY <= 12) { + bankActivePage = 3; + } else { + super.clientStream.newPacket((Command.CL_BANK_CLOSE)); + super.clientStream.sendPacket(); + showDialogBank = false; + return; + } + } + int x = gameWidth / 2 - dialogWidth / 2; + int y = gameHeight / 2 - dialogHeight / 2; + //int x = 256 - dialogWidth / 2; + //int y = 170 - dialogHeight / 2; + surface.drawBox(x, y, 408, 12, 192); + surface.drawBoxAlpha(x, y + 12, 408, 17, 0x989898, 160); + surface.drawBoxAlpha(x, y + 29, 8, 204, 0x989898, 160); + surface.drawBoxAlpha(x + 399, y + 29, 9, 204, 0x989898, 160); + surface.drawBoxAlpha(x, y + 233, 408, 47, 0x989898, 160); + surface.drawstring("Bank", x + 1, y + 10, 1, 0xffffff); + int xOff = 50; + if (bankItemCount > 48) { + int l2 = 0xffffff; + if (bankActivePage == 0) + l2 = 0xff0000; + else if (super.mouseX > x + xOff && super.mouseY >= y && super.mouseX < x + xOff + 65 && super.mouseY < y + 12) + l2 = 0xffff00; + surface.drawstring("", x + xOff, y + 10, 1, l2); + xOff += 65; + l2 = 0xffffff; + if (bankActivePage == 1) + l2 = 0xff0000; + else if (super.mouseX > x + xOff && super.mouseY >= y && super.mouseX < x + xOff + 65 && super.mouseY < y + 12) + l2 = 0xffff00; + surface.drawstring("", x + xOff, y + 10, 1, l2); + xOff += 65; + } + if (bankItemCount > 96) { + int i3 = 0xffffff; + if (bankActivePage == 2) + i3 = 0xff0000; + else if (super.mouseX > x + xOff && super.mouseY >= y && super.mouseX < x + xOff + 65 && super.mouseY < y + 12) + i3 = 0xffff00; + surface.drawstring("", x + xOff, y + 10, 1, i3); + xOff += 65; + } + if (bankItemCount > 144) { + int j3 = 0xffffff; + if (bankActivePage == 3) + j3 = 0xff0000; + else if (super.mouseX > x + xOff && super.mouseY >= y && super.mouseX < x + xOff + 65 && super.mouseY < y + 12) + j3 = 0xffff00; + surface.drawstring("", x + xOff, y + 10, 1, j3); + xOff += 65; + } + int colour = 0xffffff; + if (super.mouseX > x + 320 && super.mouseY >= y && super.mouseX < x + 408 && super.mouseY < y + 12) + colour = 0xff0000; + surface.drawstringRight("Close window", x + 406, y + 10, 1, colour); + surface.drawstring("Number in bank in green", x + 7, y + 24, 1, 65280); + surface.drawstring("Number held in blue", x + 289, y + 24, 1, 65535); + int k7 = bankActivePage * 48; + for (int i8 = 0; i8 < 6; i8++) { + for (int j8 = 0; j8 < 8; j8++) { + int l8 = x + 7 + j8 * 49; + int i9 = y + 28 + i8 * 34; + if (bankSelectedItemSlot == k7) + surface.drawBoxAlpha(l8, i9, 49, 34, 0xff0000, 160); + else + surface.drawBoxAlpha(l8, i9, 49, 34, 0xd0d0d0, 160); + surface.drawBoxEdge(l8, i9, 50, 35, 0); + if (k7 < bankItemCount && bankItems[k7] != -1) { + surface.spriteClipping(l8, i9, 48, 32, spriteItem + GameData.itemPicture[bankItems[k7]], GameData.itemMask[bankItems[k7]], 0, 0, false); + surface.drawstring(String.valueOf(bankItemsCount[k7]), l8 + 1, i9 + 10, 1, 65280); + surface.drawstringRight(String.valueOf(getInventoryCount(bankItems[k7])), l8 + 47, i9 + 29, 1, 65535); + } + k7++; + } + + } + + surface.drawLineHoriz(x + 5, y + 256, 398, 0); + if (bankSelectedItemSlot == -1) { + surface.drawStringCenter("Select an object to withdraw or deposit", x + 204, y + 248, 3, 0xffff00); + return; + } + int itemType; + if (bankSelectedItemSlot < 0) + itemType = -1; + else + itemType = bankItems[bankSelectedItemSlot]; + if (itemType != -1) { + int itemCount = bankItemsCount[bankSelectedItemSlot]; + if (GameData.itemStackable[itemType] == 1 && itemCount > 1) + itemCount = 1; + if (itemCount > 0) { + surface.drawstring("Withdraw " + GameData.itemName[itemType], x + 2, y + 248, 1, 0xffffff); + colour = 0xffffff; + if (super.mouseX >= x + 220 && super.mouseY >= y + 238 && super.mouseX < x + 250 && super.mouseY <= y + 249) + colour = 0xff0000; + surface.drawstring("One", x + 222, y + 248, 1, colour); + if (itemCount >= 5) { + colour = 0xffffff; + if (super.mouseX >= x + 250 && super.mouseY >= y + 238 && super.mouseX < x + 280 && super.mouseY <= y + 249) + colour = 0xff0000; + surface.drawstring("Five", x + 252, y + 248, 1, colour); + } + if (itemCount >= 25) { + colour = 0xffffff; + if (super.mouseX >= x + 280 && super.mouseY >= y + 238 && super.mouseX < x + 305 && super.mouseY <= y + 249) + colour = 0xff0000; + surface.drawstring("25", x + 282, y + 248, 1, colour); + } + if (itemCount >= 100) { + colour = 0xffffff; + if (super.mouseX >= x + 305 && super.mouseY >= y + 238 && super.mouseX < x + 335 && super.mouseY <= y + 249) + colour = 0xff0000; + surface.drawstring("100", x + 307, y + 248, 1, colour); + } + if (itemCount >= 500) { + colour = 0xffffff; + if (super.mouseX >= x + 335 && super.mouseY >= y + 238 && super.mouseX < x + 368 && super.mouseY <= y + 249) + colour = 0xff0000; + surface.drawstring("500", x + 337, y + 248, 1, colour); + } + if (itemCount >= 2500) { + colour = 0xffffff; + if (super.mouseX >= x + 370 && super.mouseY >= y + 238 && super.mouseX < x + 400 && super.mouseY <= y + 249) + colour = 0xff0000; + surface.drawstring("2500", x + 370, y + 248, 1, colour); + } + } + if (getInventoryCount(itemType) > 0) { + surface.drawstring("Deposit " + GameData.itemName[itemType], x + 2, y + 273, 1, 0xffffff); + colour = 0xffffff; + if (super.mouseX >= x + 220 && super.mouseY >= y + 263 && super.mouseX < x + 250 && super.mouseY <= y + 274) + colour = 0xff0000; + surface.drawstring("One", x + 222, y + 273, 1, colour); + if (getInventoryCount(itemType) >= 5) { + colour = 0xffffff; + if (super.mouseX >= x + 250 && super.mouseY >= y + 263 && super.mouseX < x + 280 && super.mouseY <= y + 274) + colour = 0xff0000; + surface.drawstring("Five", x + 252, y + 273, 1, colour); + } + if (getInventoryCount(itemType) >= 25) { + colour = 0xffffff; + if (super.mouseX >= x + 280 && super.mouseY >= y + 263 && super.mouseX < x + 305 && super.mouseY <= y + 274) + colour = 0xff0000; + surface.drawstring("25", x + 282, y + 273, 1, colour); + } + if (getInventoryCount(itemType) >= 100) { + colour = 0xffffff; + if (super.mouseX >= x + 305 && super.mouseY >= y + 263 && super.mouseX < x + 335 && super.mouseY <= y + 274) + colour = 0xff0000; + surface.drawstring("100", x + 307, y + 273, 1, colour); + } + if (getInventoryCount(itemType) >= 500) { + colour = 0xffffff; + if (super.mouseX >= x + 335 && super.mouseY >= y + 263 && super.mouseX < x + 368 && super.mouseY <= y + 274) + colour = 0xff0000; + surface.drawstring("500", x + 337, y + 273, 1, colour); + } + if (getInventoryCount(itemType) >= 2500) { + colour = 0xffffff; + if (super.mouseX >= x + 370 && super.mouseY >= y + 263 && super.mouseX < x + 400 && super.mouseY <= y + 274) + colour = 0xff0000; + surface.drawstring("2500", x + 370, y + 273, 1, colour); + } + } + } + } + + private void drawDialogDuel() { + if (mouseButtonClick != 0 && mouseButtonItemCountIncrement == 0) + mouseButtonItemCountIncrement = 1; + if (mouseButtonItemCountIncrement > 0) { + int mouseX = super.mouseX - (gameWidth / 2 - 468 / 2); + int mouseY = super.mouseY - (gameHeight / 2 - 262 / 2); + //int mouseX = super.mouseX - 22; + //int mouseY = super.mouseY - 36; + if (mouseX >= 0 && mouseY >= 0 && mouseX < 468 && mouseY < 262) { + if (mouseX > 216 && mouseY > 30 && mouseX < 462 && mouseY < 235) { + int slot = (mouseX - 217) / 49 + ((mouseY - 31) / 34) * 5; + if (slot >= 0 && slot < inventoryItemsCount) { + boolean sendUpdate = false; + int l1 = 0; + int item = inventoryItemId[slot]; + for (int k3 = 0; k3 < duelOfferItemCount; k3++) + if (duelOfferItemId[k3] == item) + if (GameData.itemStackable[item] == 0) { + for (int i4 = 0; i4 < mouseButtonItemCountIncrement; i4++) { + if (duelOfferItemStack[k3] < inventoryItemStackCount[slot]) + duelOfferItemStack[k3]++; + sendUpdate = true; + } + + } else { + l1++; + } + + if (getInventoryCount(item) <= l1) + sendUpdate = true; + if (GameData.itemSpecial[item] == 1) { + showMessage("This object cannot be added to a duel offer", 3); + sendUpdate = true; + } + if (!sendUpdate && duelOfferItemCount < 8) { + duelOfferItemId[duelOfferItemCount] = item; + duelOfferItemStack[duelOfferItemCount] = 1; + duelOfferItemCount++; + sendUpdate = true; + } + if (sendUpdate) { + super.clientStream.newPacket((Command.CL_DUEL_ITEM_UPDATE)); + super.clientStream.putByte(duelOfferItemCount); + for (int j4 = 0; j4 < duelOfferItemCount; j4++) { + super.clientStream.putShort(duelOfferItemId[j4]); + super.clientStream.putInt(duelOfferItemStack[j4]); + } + + super.clientStream.sendPacket(); + duelOfferOpponentAccepted = false; + duelOfferAccepted = false; + } + } + } + if (mouseX > 8 && mouseY > 30 && mouseX < 205 && mouseY < 129) { + int slot = (mouseX - 9) / 49 + ((mouseY - 31) / 34) * 4; + if (slot >= 0 && slot < duelOfferItemCount) { + int j1 = duelOfferItemId[slot]; + for (int i2 = 0; i2 < mouseButtonItemCountIncrement; i2++) { + if (GameData.itemStackable[j1] == 0 && duelOfferItemStack[slot] > 1) { + duelOfferItemStack[slot]--; + continue; + } + duelOfferItemCount--; + mouseButtonDownTime = 0; + for (int l2 = slot; l2 < duelOfferItemCount; l2++) { + duelOfferItemId[l2] = duelOfferItemId[l2 + 1]; + duelOfferItemStack[l2] = duelOfferItemStack[l2 + 1]; + } + + break; + } + + super.clientStream.newPacket((Command.CL_DUEL_ITEM_UPDATE)); + super.clientStream.putByte(duelOfferItemCount); + for (int i3 = 0; i3 < duelOfferItemCount; i3++) { + super.clientStream.putShort(duelOfferItemId[i3]); + super.clientStream.putInt(duelOfferItemStack[i3]); + } + + super.clientStream.sendPacket(); + duelOfferOpponentAccepted = false; + duelOfferAccepted = false; + } + } + boolean flag = false; + if (mouseX >= 93 && mouseY >= 221 && mouseX <= 104 && mouseY <= 232) { + duelSettingsRetreat = !duelSettingsRetreat; + flag = true; + } + if (mouseX >= 93 && mouseY >= 240 && mouseX <= 104 && mouseY <= 251) { + duelSettingsMagic = !duelSettingsMagic; + flag = true; + } + if (mouseX >= 191 && mouseY >= 221 && mouseX <= 202 && mouseY <= 232) { + duelSettingsPrayer = !duelSettingsPrayer; + flag = true; + } + if (mouseX >= 191 && mouseY >= 240 && mouseX <= 202 && mouseY <= 251) { + duelSettingsWeapons = !duelSettingsWeapons; + flag = true; + } + if (flag) { + super.clientStream.newPacket((Command.CL_DUEL_SETTINGS)); + super.clientStream.putByte(duelSettingsRetreat ? 1 : 0); + super.clientStream.putByte(duelSettingsMagic ? 1 : 0); + super.clientStream.putByte(duelSettingsPrayer ? 1 : 0); + super.clientStream.putByte(duelSettingsWeapons ? 1 : 0); + super.clientStream.sendPacket(); + duelOfferOpponentAccepted = false; + duelOfferAccepted = false; + } + if (mouseX >= 217 && mouseY >= 238 && mouseX <= 286 && mouseY <= 259) { + duelOfferAccepted = true; + super.clientStream.newPacket((Command.CL_DUEL_ACCEPT)); + super.clientStream.sendPacket(); + } + if (mouseX >= 394 && mouseY >= 238 && mouseX < 463 && mouseY < 259) { + showDialogDuel = false; + super.clientStream.newPacket((Command.CL_DUEL_DECLINE)); + super.clientStream.sendPacket(); + } + } else if (mouseButtonClick != 0) { + showDialogDuel = false; + super.clientStream.newPacket((Command.CL_DUEL_DECLINE)); + super.clientStream.sendPacket(); + } + mouseButtonClick = 0; + mouseButtonItemCountIncrement = 0; + } + if (!showDialogDuel) + return; + int dialogX = gameWidth / 2 - 468 / 2 + 22; + int dialogY = gameHeight / 2 - 262 / 2 + 22; + //int dialogX = 22; + //int dialogY = 36; + surface.drawBox(dialogX, dialogY, 468, 12, 0xc90b1d); + surface.drawBoxAlpha(dialogX, dialogY + 12, 468, 18, 0x989898, 160); + surface.drawBoxAlpha(dialogX, dialogY + 30, 8, 248, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 205, dialogY + 30, 11, 248, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 462, dialogY + 30, 6, 248, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 99, 197, 24, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 192, 197, 23, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 258, 197, 20, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 216, dialogY + 235, 246, 43, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 30, 197, 69, 0xd0d0d0, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 123, 197, 69, 0xd0d0d0, 160); + surface.drawBoxAlpha(dialogX + 8, dialogY + 215, 197, 43, 0xd0d0d0, 160); + surface.drawBoxAlpha(dialogX + 216, dialogY + 30, 246, 205, 0xd0d0d0, 160); + for (int j2 = 0; j2 < 3; j2++) + surface.drawLineHoriz(dialogX + 8, dialogY + 30 + j2 * 34, 197, 0); + + for (int j3 = 0; j3 < 3; j3++) + surface.drawLineHoriz(dialogX + 8, dialogY + 123 + j3 * 34, 197, 0); + + for (int l3 = 0; l3 < 7; l3++) + surface.drawLineHoriz(dialogX + 216, dialogY + 30 + l3 * 34, 246, 0); + + for (int k4 = 0; k4 < 6; k4++) { + if (k4 < 5) + surface.drawLineVert(dialogX + 8 + k4 * 49, dialogY + 30, 69, 0); + if (k4 < 5) + surface.drawLineVert(dialogX + 8 + k4 * 49, dialogY + 123, 69, 0); + surface.drawLineVert(dialogX + 216 + k4 * 49, dialogY + 30, 205, 0); + } + + surface.drawLineHoriz(dialogX + 8, dialogY + 215, 197, 0); + surface.drawLineHoriz(dialogX + 8, dialogY + 257, 197, 0); + surface.drawLineVert(dialogX + 8, dialogY + 215, 43, 0); + surface.drawLineVert(dialogX + 204, dialogY + 215, 43, 0); + surface.drawstring("Preparing to duel with: " + duelOpponentName, dialogX + 1, dialogY + 10, 1, 0xffffff); + surface.drawstring("Your Stake", dialogX + 9, dialogY + 27, 4, 0xffffff); + surface.drawstring("Opponent's Stake", dialogX + 9, dialogY + 120, 4, 0xffffff); + surface.drawstring("Duel Options", dialogX + 9, dialogY + 212, 4, 0xffffff); + surface.drawstring("Your Inventory", dialogX + 216, dialogY + 27, 4, 0xffffff); + surface.drawstring("No retreating", dialogX + 8 + 1, dialogY + 215 + 16, 3, 0xffff00); + surface.drawstring("No magic", dialogX + 8 + 1, dialogY + 215 + 35, 3, 0xffff00); + surface.drawstring("No prayer", dialogX + 8 + 102, dialogY + 215 + 16, 3, 0xffff00); + surface.drawstring("No weapons", dialogX + 8 + 102, dialogY + 215 + 35, 3, 0xffff00); + surface.drawBoxEdge(dialogX + 93, dialogY + 215 + 6, 11, 11, 0xffff00); + if (duelSettingsRetreat) + surface.drawBox(dialogX + 95, dialogY + 215 + 8, 7, 7, 0xffff00); + surface.drawBoxEdge(dialogX + 93, dialogY + 215 + 25, 11, 11, 0xffff00); + if (duelSettingsMagic) + surface.drawBox(dialogX + 95, dialogY + 215 + 27, 7, 7, 0xffff00); + surface.drawBoxEdge(dialogX + 191, dialogY + 215 + 6, 11, 11, 0xffff00); + if (duelSettingsPrayer) + surface.drawBox(dialogX + 193, dialogY + 215 + 8, 7, 7, 0xffff00); + surface.drawBoxEdge(dialogX + 191, dialogY + 215 + 25, 11, 11, 0xffff00); + if (duelSettingsWeapons) + surface.drawBox(dialogX + 193, dialogY + 215 + 27, 7, 7, 0xffff00); + if (!duelOfferAccepted) + surface.drawSprite(dialogX + 217, dialogY + 238, spriteMedia + 25); + surface.drawSprite(dialogX + 394, dialogY + 238, spriteMedia + 26); + if (duelOfferOpponentAccepted) { + surface.drawStringCenter("Other player", dialogX + 341, dialogY + 246, 1, 0xffffff); + surface.drawStringCenter("has accepted", dialogX + 341, dialogY + 256, 1, 0xffffff); + } + if (duelOfferAccepted) { + surface.drawStringCenter("Waiting for", dialogX + 217 + 35, dialogY + 246, 1, 0xffffff); + surface.drawStringCenter("other player", dialogX + 217 + 35, dialogY + 256, 1, 0xffffff); + } + for (int i = 0; i < inventoryItemsCount; i++) { + int x = 217 + dialogX + (i % 5) * 49; + int y = 31 + dialogY + (i / 5) * 34; + surface.spriteClipping(x, y, 48, 32, spriteItem + GameData.itemPicture[inventoryItemId[i]], GameData.itemMask[inventoryItemId[i]], 0, 0, false); + if (GameData.itemStackable[inventoryItemId[i]] == 0) + surface.drawstring(String.valueOf(inventoryItemStackCount[i]), x + 1, y + 10, 1, 0xffff00); + } + + for (int i = 0; i < duelOfferItemCount; i++) { + int x = 9 + dialogX + (i % 4) * 49; + int y = 31 + dialogY + (i / 4) * 34; + surface.spriteClipping(x, y, 48, 32, spriteItem + GameData.itemPicture[duelOfferItemId[i]], GameData.itemMask[duelOfferItemId[i]], 0, 0, false); + if (GameData.itemStackable[duelOfferItemId[i]] == 0) + surface.drawstring(String.valueOf(duelOfferItemStack[i]), x + 1, y + 10, 1, 0xffff00); + if (super.mouseX > x && super.mouseX < x + 48 && super.mouseY > y && super.mouseY < y + 32) + surface.drawstring(GameData.itemName[duelOfferItemId[i]] + ": @whi@" + GameData.itemDescription[duelOfferItemId[i]], dialogX + 8, dialogY + 273, 1, 0xffff00); + } + + for (int i = 0; i < duelOfferOpponentItemCount; i++) { + int x = 9 + dialogX + (i % 4) * 49; + int y = 124 + dialogY + (i / 4) * 34; + surface.spriteClipping(x, y, 48, 32, spriteItem + GameData.itemPicture[duelOfferOpponentItemId[i]], GameData.itemMask[duelOfferOpponentItemId[i]], 0, 0, false); + if (GameData.itemStackable[duelOfferOpponentItemId[i]] == 0) + surface.drawstring(String.valueOf(duelOfferOpponentItemStack[i]), x + 1, y + 10, 1, 0xffff00); + if (super.mouseX > x && super.mouseX < x + 48 && super.mouseY > y && super.mouseY < y + 32) + surface.drawstring(GameData.itemName[duelOfferOpponentItemId[i]] + ": @whi@" + GameData.itemDescription[duelOfferOpponentItemId[i]], dialogX + 8, dialogY + 273, 1, 0xffff00); + } + + } + + private boolean loadNextRegion(int lx, int ly) { + if (deathScreenTimeout != 0) { + world.playerAlive = false; + return false; + } + loadingArea = false; + lx += planeWidth; + ly += planeHeight; + if (lastHeightOffset == planeIndex && lx > localLowerX && lx < localUpperX && ly > localLowerY && ly < localUpperY) { + world.playerAlive = true; + return false; + } + surface.drawStringCenter("Loading... Please wait", 256, 192, 1, 0xffffff); + drawChatMessageTabs(); + surface.draw(0, 0); + int ax = regionX; + int ay = regionY; + int sectionX = (lx + 24) / 48; + int sectionY = (ly + 24) / 48; + lastHeightOffset = planeIndex; + regionX = sectionX * 48 - 48; + regionY = sectionY * 48 - 48; + localLowerX = sectionX * 48 - 32; + localLowerY = sectionY * 48 - 32; + localUpperX = sectionX * 48 + 32; + localUpperY = sectionY * 48 + 32; + world.loadSection(lx, ly, lastHeightOffset); + regionX -= planeWidth; + regionY -= planeHeight; + int offsetx = regionX - ax; + int offsety = regionY - ay; + for (int objidx = 0; objidx < objectCount; objidx++) { + objectX[objidx] -= offsetx; + objectY[objidx] -= offsety; + int objx = objectX[objidx]; + int objy = objectY[objidx]; + int objid = objectId[objidx]; + GameModel gameModel = objectModel[objidx]; + try { + int objtype = objectDirection[objidx]; + int objw; + int objh; + if (objtype == 0 || objtype == 4) { + objw = GameData.objectWidth[objid]; + objh = GameData.objectHeight[objid]; + } else { + objh = GameData.objectWidth[objid]; + objw = GameData.objectHeight[objid]; + } + int j6 = ((objx + objx + objw) * magicLoc) / 2; + int k6 = ((objy + objy + objh) * magicLoc) / 2; + if (objx >= 0 && objy >= 0 && objx < 96 && objy < 96) { + scene.addModel(gameModel); + gameModel.place(j6, -world.getElevation(j6, k6), k6); + world.removeObject2(objx, objy, objid); + if (objid == 74) + gameModel.translate(0, -480, 0); + } + } catch (RuntimeException runtimeexception) { + System.out.println("Loc Error: " + runtimeexception.getMessage()); + System.out.println("i:" + objidx + " obj:" + gameModel); + runtimeexception.printStackTrace(); + } + } + + for (int k2 = 0; k2 < wallObjectCount; k2++) { + wallObjectX[k2] -= offsetx; + wallObjectY[k2] -= offsety; + int i3 = wallObjectX[k2]; + int l3 = wallObjectY[k2]; + int j4 = wallObjectId[k2]; + int i5 = wallObjectDirection[k2]; + try { + world.setObjectAdjacency(i3, l3, i5, j4); + GameModel gameModel_1 = createModel(i3, l3, i5, j4, k2); + wallObjectModel[k2] = gameModel_1; + } catch (RuntimeException runtimeexception1) { + System.out.println("Bound Error: " + runtimeexception1.getMessage()); + runtimeexception1.printStackTrace(); + } + } + + for (int j3 = 0; j3 < groundItemCount; j3++) { + groundItemX[j3] -= offsetx; + groundItemY[j3] -= offsety; + } + + for (int i4 = 0; i4 < playerCount; i4++) { + GameCharacter character = players[i4]; + character.currentX -= offsetx * magicLoc; + character.currentY -= offsety * magicLoc; + for (int j5 = 0; j5 <= character.waypointCurrent; j5++) { + character.waypointsX[j5] -= offsetx * magicLoc; + character.waypointsY[j5] -= offsety * magicLoc; + } + + } + + for (int k4 = 0; k4 < npcCount; k4++) { + GameCharacter character_1 = npcs[k4]; + character_1.currentX -= offsetx * magicLoc; + character_1.currentY -= offsety * magicLoc; + for (int l5 = 0; l5 <= character_1.waypointCurrent; l5++) { + character_1.waypointsX[l5] -= offsetx * magicLoc; + character_1.waypointsY[l5] -= offsety * magicLoc; + } + + } + + world.playerAlive = true; + return true; + } + + void drawPlayer(int x, int y, int w, int h, int id, int tx, int ty) { + GameCharacter character = players[id]; + if (character.colourBottom == 255) // this means the character is invisible! MOD!!! + return; + int l1 = character.animationCurrent + (cameraRotation + 16) / 32 & 7; + boolean flag = false; + int i2 = l1; + if (i2 == 5) { + i2 = 3; + flag = true; + } else if (i2 == 6) { + i2 = 2; + flag = true; + } else if (i2 == 7) { + i2 = 1; + flag = true; + } + int j2 = i2 * 3 + npcWalkModel[(character.stepCount / 6) % 4]; + if (character.animationCurrent == 8) { + i2 = 5; + l1 = 2; + flag = false; + x -= (5 * ty) / 100; + j2 = i2 * 3 + npcCombatModelArray1[(loginTimer / 5) % 8]; + } else if (character.animationCurrent == 9) { + i2 = 5; + l1 = 2; + flag = true; + x += (5 * ty) / 100; + j2 = i2 * 3 + npcCombatModelArray2[(loginTimer / 6) % 8]; + } + for (int k2 = 0; k2 < 12; k2++) { + int l2 = npcAnimationArray[l1][k2]; + int l3 = character.equippedItem[l2] - 1; + if (l3 >= 0) { + int k4 = 0; + int i5 = 0; + int j5 = j2; + if (flag && i2 >= 1 && i2 <= 3) + if (GameData.animationHasF[l3] == 1) + j5 += 15; + else if (l2 == 4 && i2 == 1) { + k4 = -22; + i5 = -3; + j5 = i2 * 3 + npcWalkModel[(2 + character.stepCount / 6) % 4]; + } else if (l2 == 4 && i2 == 2) { + k4 = 0; + i5 = -8; + j5 = i2 * 3 + npcWalkModel[(2 + character.stepCount / 6) % 4]; + } else if (l2 == 4 && i2 == 3) { + k4 = 26; + i5 = -5; + j5 = i2 * 3 + npcWalkModel[(2 + character.stepCount / 6) % 4]; + } else if (l2 == 3 && i2 == 1) { + k4 = 22; + i5 = 3; + j5 = i2 * 3 + npcWalkModel[(2 + character.stepCount / 6) % 4]; + } else if (l2 == 3 && i2 == 2) { + k4 = 0; + i5 = 8; + j5 = i2 * 3 + npcWalkModel[(2 + character.stepCount / 6) % 4]; + } else if (l2 == 3 && i2 == 3) { + k4 = -26; + i5 = 5; + j5 = i2 * 3 + npcWalkModel[(2 + character.stepCount / 6) % 4]; + } + if (i2 != 5 || GameData.animationHasA[l3] == 1) { + int k5 = j5 + GameData.animationNumber[l3]; + k4 = (k4 * w) / surface.spriteWidthFull[k5]; + i5 = (i5 * h) / surface.spriteHeightFull[k5]; + int l5 = (w * surface.spriteWidthFull[k5]) / surface.spriteWidthFull[GameData.animationNumber[l3]]; + k4 -= (l5 - w) / 2; + int i6 = GameData.animationCharacterColour[l3]; + int j6 = characterSkinColours[character.colourSkin]; + if (i6 == 1) + i6 = characterHairColours[character.colourHair]; + else if (i6 == 2) + i6 = characterTopBottomColours[character.colourTop]; + else if (i6 == 3) + i6 = characterTopBottomColours[character.colourBottom]; + surface.spriteClipping(x + k4, y + i5, l5, h, k5, i6, j6, tx, flag); + } + } + } + + if (character.messageTimeout > 0) { + receivedMessageMidPoint[receivedMessagesCount] = surface.textWidth(character.message, 1) / 2; + if (receivedMessageMidPoint[receivedMessagesCount] > 150) + receivedMessageMidPoint[receivedMessagesCount] = 150; + receivedMessageHeight[receivedMessagesCount] = (surface.textWidth(character.message, 1) / 300) * surface.textHeight(1); + receivedMessageX[receivedMessagesCount] = x + w / 2; + receivedMessageY[receivedMessagesCount] = y; + receivedMessages[receivedMessagesCount++] = character.message; + } + if (character.bubbleTimeout > 0) { + actionBubbleX[itemsAboveHeadCount] = x + w / 2; + actionBubbleY[itemsAboveHeadCount] = y; + actionBubbleScale[itemsAboveHeadCount] = ty; + actionBubbleItem[itemsAboveHeadCount++] = character.bubbleItem; + } + if (character.animationCurrent == 8 || character.animationCurrent == 9 || character.combatTimer != 0) { + if (character.combatTimer > 0) { + int i3 = x; + if (character.animationCurrent == 8) + i3 -= (20 * ty) / 100; + else if (character.animationCurrent == 9) + i3 += (20 * ty) / 100; + int i4 = (character.healthCurrent * 30) / character.healthMax; + healthBarX[healthBarCount] = i3 + w / 2; + healthBarY[healthBarCount] = y; + healthBarMissing[healthBarCount++] = i4; + } + if (character.combatTimer > 150) { + int j3 = x; + if (character.animationCurrent == 8) + j3 -= (10 * ty) / 100; + else if (character.animationCurrent == 9) + j3 += (10 * ty) / 100; + surface.drawSprite((j3 + w / 2) - 12, (y + h / 2) - 12, spriteMedia + 11); + surface.drawStringCenter(String.valueOf(character.damageTaken), (j3 + w / 2) - 1, y + h / 2 + 5, 3, 0xffffff); + } + } + if (character.skullVisible == 1 && character.bubbleTimeout == 0) { + int k3 = tx + x + w / 2; + if (character.animationCurrent == 8) + k3 -= (20 * ty) / 100; + else if (character.animationCurrent == 9) + k3 += (20 * ty) / 100; + int j4 = (16 * ty) / 100; + int l4 = (16 * ty) / 100; + surface.spriteClipping(k3 - j4 / 2, y - l4 / 2 - (10 * ty) / 100, j4, l4, spriteMedia + 13); + } + } + + private void loadMedia() { + byte media[] = readDataFile("media" + Version.MEDIA + ".jag", "2d graphics", 20); + if (media == null) { + errorLoadingData = true; + return; + } + byte buff[] = Utility.loadData("index.dat", 0, media); + surface.parseSprite(spriteMedia, Utility.loadData("inv1.dat", 0, media), buff, 1); + surface.parseSprite(spriteMedia + 1, Utility.loadData("inv2.dat", 0, media), buff, 6); + surface.parseSprite(spriteMedia + 9, Utility.loadData("bubble.dat", 0, media), buff, 1); + surface.parseSprite(spriteMedia + 10, Utility.loadData("runescape.dat", 0, media), buff, 1); + surface.parseSprite(spriteMedia + 11, Utility.loadData("splat.dat", 0, media), buff, 3); + surface.parseSprite(spriteMedia + 14, Utility.loadData("icon.dat", 0, media), buff, 8); + surface.parseSprite(spriteMedia + 22, Utility.loadData("hbar.dat", 0, media), buff, 1); + surface.parseSprite(spriteMedia + 23, Utility.loadData("hbar2.dat", 0, media), buff, 1); + surface.parseSprite(spriteMedia + 24, Utility.loadData("compass.dat", 0, media), buff, 1); + surface.parseSprite(spriteMedia + 25, Utility.loadData("buttons.dat", 0, media), buff, 2); + surface.parseSprite(spriteUtil, Utility.loadData("scrollbar.dat", 0, media), buff, 2); + surface.parseSprite(spriteUtil + 2, Utility.loadData("corners.dat", 0, media), buff, 4); + surface.parseSprite(spriteUtil + 6, Utility.loadData("arrows.dat", 0, media), buff, 2); + surface.parseSprite(spriteProjectile, Utility.loadData("projectile.dat", 0, media), buff, GameData.projectileSprite); + int i = GameData.itemSpriteCount; + for (int j = 1; i > 0; j++) { + int k = i; + i -= 30; + if (k > 30) + k = 30; + surface.parseSprite(spriteItem + (j - 1) * 30, Utility.loadData("objects" + j + ".dat", 0, media), buff, k); + } + + surface.loadSprite(spriteMedia); + surface.loadSprite(spriteMedia + 9); + for (int l = 11; l <= 26; l++) + surface.loadSprite(spriteMedia + l); + + for (int i1 = 0; i1 < GameData.projectileSprite; i1++) + surface.loadSprite(spriteProjectile + i1); + + for (int j1 = 0; j1 < GameData.itemSpriteCount; j1++) + surface.loadSprite(spriteItem + j1); + + } + + private void drawChatMessageTabs() { + surface.drawSprite(0, gameHeight - 4, spriteMedia + 23); + int col = Surface.rgb2long(200, 200, 255); + if (messageTabSelected == 0) + col = Surface.rgb2long(255, 200, 50); + if (messageTabFlashAll % 30 > 15) + col = Surface.rgb2long(255, 50, 50); + surface.drawStringCenter("All messages", 54, gameHeight + 6, 0, col); + col = Surface.rgb2long(200, 200, 255); + if (messageTabSelected == 1) + col = Surface.rgb2long(255, 200, 50); + if (messageTabFlashHistory % 30 > 15) + col = Surface.rgb2long(255, 50, 50); + surface.drawStringCenter("Chat history", 155, gameHeight + 6, 0, col); + col = Surface.rgb2long(200, 200, 255); + if (messageTabSelected == 2) + col = Surface.rgb2long(255, 200, 50); + if (messtageTabFlashQuest % 30 > 15) + col = Surface.rgb2long(255, 50, 50); + surface.drawStringCenter("Quest history", 255, gameHeight + 6, 0, col); + col = Surface.rgb2long(200, 200, 255); + if (messageTabSelected == 3) + col = Surface.rgb2long(255, 200, 50); + if (messageTabFlashPrivate % 30 > 15) + col = Surface.rgb2long(255, 50, 50); + surface.drawStringCenter("Private history", 355, gameHeight + 6, 0, col); + surface.drawStringCenter("Report abuse", 457, gameHeight + 6, 0, 0xffffff); + } + + /*protected void startThread(Runnable runnable) { + Thread thread = new Thread(runnable); + thread.setDaemon(true); + thread.start(); + }*/ + + protected void startGame() { + int total_exp = 0; + for (int level = 0; level < 99; level++) { + int level_1 = level + 1; + int exp = (int) ((double) level_1 + 300D * Math.pow(2D, (double) level_1 / 7D)); + total_exp += exp; + experienceArray[level] = total_exp & 0xffffffc; + } + + if (appletMode) + super.port = 43594; + + maxReadTries = 1000; + clientVersion = Version.CLIENT; + loadGameConfig(); + if (errorLoadingData) + return; + spriteMedia = 2000; + spriteUtil = spriteMedia + 100; + spriteItem = spriteUtil + 50; + spriteLogo = spriteItem + 1000; + spriteProjectile = spriteLogo + 10; + spriteTexture = spriteProjectile + 50; + spriteTextureWorld = spriteTexture + 10; + //graphics = getGraphics(); + setTargetFps(50); + surface = new SurfaceSprite(gameWidth, gameHeight + 12, 4000, this); + surface.mudclientref = this; + surface.setBounds(0, 0, gameWidth, gameHeight + 12); + Panel.drawBackgroundArrow = false; + Panel.baseSpriteStart = spriteUtil; + panelMagic = new Panel(surface, 5); + int x = surface.width2 - 199; + byte y = 36; + controlListMagic = panelMagic.addTextListInteractive(x, y + 24, 196, 90, 1, 500, true); + panelSocialList = new Panel(surface, 5); + controlListSocialPlayers = panelSocialList.addTextListInteractive(x, y + 40, 196, 126, 1, 500, true); + panelQuestList = new Panel(surface, 5); + controlListQuest = panelQuestList.addTextListInteractive(x, y + 24, 196, 251, 1, 500, true); + loadMedia(); + if (errorLoadingData) + return; + loadEntities(); + if (errorLoadingData) + return; + scene = new Scene(surface, 15000, 15000, 1000); + scene.setBounds(gameWidth / 2, gameHeight / 2, gameWidth / 2, gameHeight / 2, gameWidth, const_9); + scene.clipFar3d = 2400; + scene.clipFar2d = 2400; + scene.fogZFalloff = 1; + scene.fogZDistance = 2300; + scene.setLight(-50, -10, -50); + world = new World(scene, surface); + world.baseMediaSprite = spriteMedia; + loadTextures(); + if (errorLoadingData) + return; + loadModels(); + if (errorLoadingData) + return; + loadMaps(); + if (errorLoadingData) + return; + if (members) + loadSounds(); + if (!errorLoadingData) { + showLoadingProgress(100, "Starting game..."); + createMessageTabPanel(); + createLoginPanels(); + createAppearancePanel(); + resetLoginScreenVariables(); + renderLoginScreenViewports(); + } + } + + private void drawUiTabMagic(boolean nomenus) { + int uiX = surface.width2 - 199; + int uiY = 36; + surface.drawSprite(uiX - 49, 3, spriteMedia + 4); + int uiWidth = 196;// '\304'; + int uiHeight = 182;// '\266'; + int l; + int k = l = Surface.rgb2long(160, 160, 160); + if (tabMagicPrayer == 0) + k = Surface.rgb2long(220, 220, 220); + else + l = Surface.rgb2long(220, 220, 220); + surface.drawBoxAlpha(uiX, uiY, uiWidth / 2, 24, k, 128); + surface.drawBoxAlpha(uiX + uiWidth / 2, uiY, uiWidth / 2, 24, l, 128); + surface.drawBoxAlpha(uiX, uiY + 24, uiWidth, 90, Surface.rgb2long(220, 220, 220), 128); + surface.drawBoxAlpha(uiX, uiY + 24 + 90, uiWidth, uiHeight - 90 - 24, Surface.rgb2long(160, 160, 160), 128); + surface.drawLineHoriz(uiX, uiY + 24, uiWidth, 0); + surface.drawLineVert(uiX + uiWidth / 2, uiY, 24, 0); + surface.drawLineHoriz(uiX, uiY + 113, uiWidth, 0); + surface.drawStringCenter("Magic", uiX + uiWidth / 4, uiY + 16, 4, 0); + surface.drawStringCenter("Prayers", uiX + uiWidth / 4 + uiWidth / 2, uiY + 16, 4, 0); + if (tabMagicPrayer == 0) { + panelMagic.clearList(controlListMagic); + int i1 = 0; + for (int spell = 0; spell < GameData.spellCount; spell++) { + String s = "@yel@"; + for (int rune = 0; rune < GameData.spellRunesRequired[spell]; rune++) { + int k4 = GameData.spellRunesId[spell][rune]; + if (hasInventoryItems(k4, GameData.spellRunesCount[spell][rune])) + continue; + s = "@whi@"; + break; + } + + int l4 = playerStatCurrent[6]; + if (GameData.spellLevel[spell] > l4) + s = "@bla@"; + panelMagic.addListEntry(controlListMagic, i1++, s + "Level " + GameData.spellLevel[spell] + ": " + GameData.spellName[spell]); + } + + panelMagic.drawPanel(); + int i3 = panelMagic.getListEntryIndex(controlListMagic); + if (i3 != -1) { + surface.drawstring("Level " + GameData.spellLevel[i3] + ": " + GameData.spellName[i3], uiX + 2, uiY + 124, 1, 0xffff00); + surface.drawstring(GameData.spellDescription[i3], uiX + 2, uiY + 136, 0, 0xffffff); + for (int i4 = 0; i4 < GameData.spellRunesRequired[i3]; i4++) { + int i5 = GameData.spellRunesId[i3][i4]; + surface.drawSprite(uiX + 2 + i4 * 44, uiY + 150, spriteItem + GameData.itemPicture[i5]); + int j5 = getInventoryCount(i5); + int k5 = GameData.spellRunesCount[i3][i4]; + String s2 = "@red@"; + if (hasInventoryItems(i5, k5)) + s2 = "@gre@"; + surface.drawstring(s2 + j5 + "/" + k5, uiX + 2 + i4 * 44, uiY + 150, 1, 0xffffff); + } + + } else { + surface.drawstring("Point at a spell for a description", uiX + 2, uiY + 124, 1, 0); + } + } + if (tabMagicPrayer == 1) { + panelMagic.clearList(controlListMagic); + int j1 = 0; + for (int j2 = 0; j2 < GameData.prayerCount; j2++) { + String s1 = "@whi@"; + if (GameData.prayerLevel[j2] > playerStatBase[5]) + s1 = "@bla@"; + if (prayerOn[j2]) + s1 = "@gre@"; + panelMagic.addListEntry(controlListMagic, j1++, s1 + "Level " + GameData.prayerLevel[j2] + ": " + GameData.prayerName[j2]); + } + + panelMagic.drawPanel(); + int j3 = panelMagic.getListEntryIndex(controlListMagic); + if (j3 != -1) { + surface.drawStringCenter("Level " + GameData.prayerLevel[j3] + ": " + GameData.prayerName[j3], uiX + uiWidth / 2, uiY + 130, 1, 0xffff00); + surface.drawStringCenter(GameData.prayerDescription[j3], uiX + uiWidth / 2, uiY + 145, 0, 0xffffff); + surface.drawStringCenter("Drain rate: " + GameData.prayerDrain[j3], uiX + uiWidth / 2, uiY + 160, 1, 0); + } else { + surface.drawstring("Point at a prayer for a description", uiX + 2, uiY + 124, 1, 0); + } + } + if (!nomenus) + return; + int mouseX = super.mouseX - (surface.width2 - 199); + int mouseY = super.mouseY - 36; + if (mouseX >= 0 && mouseY >= 0 && mouseX < 196 && mouseY < 182) { + panelMagic.handleMouse(mouseX + (surface.width2 - 199), mouseY + 36, super.lastMouseButtonDown, super.mouseButtonDown); + if (mouseY <= 24 && mouseButtonClick == 1) + if (mouseX < 98 && tabMagicPrayer == 1) { + tabMagicPrayer = 0; + panelMagic.resetListProps(controlListMagic); + } else if (mouseX > 98 && tabMagicPrayer == 0) { + tabMagicPrayer = 1; + panelMagic.resetListProps(controlListMagic); + } + if (mouseButtonClick == 1 && tabMagicPrayer == 0) { + int idx = panelMagic.getListEntryIndex(controlListMagic); + if (idx != -1) { + int k2 = playerStatCurrent[6]; + if (GameData.spellLevel[idx] > k2) { + showMessage("Your magic ability is not high enough for this spell", 3); + } else { + int k3; + for (k3 = 0; k3 < GameData.spellRunesRequired[idx]; k3++) { + int j4 = GameData.spellRunesId[idx][k3]; + if (hasInventoryItems(j4, GameData.spellRunesCount[idx][k3])) + continue; + showMessage("You don't have all the reagents you need for this spell", 3); + k3 = -1; + break; + } + + if (k3 == GameData.spellRunesRequired[idx]) { + selectedSpell = idx; + selectedItemInventoryIndex = -1; + } + } + } + } + if (mouseButtonClick == 1 && tabMagicPrayer == 1) { + int l1 = panelMagic.getListEntryIndex(controlListMagic); + if (l1 != -1) { + int l2 = playerStatBase[5]; + if (GameData.prayerLevel[l1] > l2) + showMessage("Your prayer ability is not high enough for this prayer", 3); + else if (playerStatCurrent[5] == 0) + showMessage("You have run out of prayer points. Return to a church to recharge", 3); + else if (prayerOn[l1]) { + super.clientStream.newPacket((Command.CL_PRAYER_OFF)); + super.clientStream.putByte(l1); + super.clientStream.sendPacket(); + prayerOn[l1] = false; + playSoundFile("prayeroff"); + } else { + super.clientStream.newPacket((Command.CL_PRAYER_ON)); + super.clientStream.putByte(l1); + super.clientStream.sendPacket(); + prayerOn[l1] = true; + playSoundFile("prayeron"); + } + } + } + mouseButtonClick = 0; + } + } + + private void drawDialogShop() { + if (mouseButtonClick != 0) { + mouseButtonClick = 0; + int mouseX = super.mouseX - 52; + int mouseY = super.mouseY - 44; + if (mouseX >= 0 && mouseY >= 12 && mouseX < 408 && mouseY < 246) { + int itemIndex = 0; + for (int row = 0; row < 5; row++) { + for (int col = 0; col < 8; col++) { + int slotX = 7 + col * 49; + int slotY = 28 + row * 34; + if (mouseX > slotX && mouseX < slotX + 49 && mouseY > slotY && mouseY < slotY + 34 && shopItem[itemIndex] != -1) { + shopSelectedItemIndex = itemIndex; + shopSelectedItemType = shopItem[itemIndex]; + } + itemIndex++; + } + + } + + if (shopSelectedItemIndex >= 0) { + int itemType = shopItem[shopSelectedItemIndex]; + if (itemType != -1) { + if (shopItemCount[shopSelectedItemIndex] > 0 && mouseX > 298 && mouseY >= 204 && mouseX < 408 && mouseY <= 215) { + int priceMod = shopBuyPriceMod + shopItemPrice[shopSelectedItemIndex]; + if (priceMod < 10) + priceMod = 10; + int itemPrice = (priceMod * GameData.itemBasePrice[itemType]) / 100; + super.clientStream.newPacket((Command.CL_SHOP_BUY)); + super.clientStream.putShort(shopItem[shopSelectedItemIndex]); + super.clientStream.putInt(itemPrice); + super.clientStream.sendPacket(); + } + if (getInventoryCount(itemType) > 0 && mouseX > 2 && mouseY >= 229 && mouseX < 112 && mouseY <= 240) { + int priceMod = shopSellPriceMod + shopItemPrice[shopSelectedItemIndex]; + if (priceMod < 10) + priceMod = 10; + int itemPrice = (priceMod * GameData.itemBasePrice[itemType]) / 100; + super.clientStream.newPacket((Command.CL_SHOP_SELL)); + super.clientStream.putShort(shopItem[shopSelectedItemIndex]); + super.clientStream.putInt(itemPrice); + super.clientStream.sendPacket(); + } + } + } + } else { + super.clientStream.newPacket((Command.CL_SHOP_CLOSE)); + super.clientStream.sendPacket(); + showDialogShop = false; + return; + } + } + byte dialogX = 52; + byte dialogY = 44; + surface.drawBox(dialogX, dialogY, 408, 12, 192); + surface.drawBoxAlpha(dialogX, dialogY + 12, 408, 17, 0x989898, 160); + surface.drawBoxAlpha(dialogX, dialogY + 29, 8, 170, 0x989898, 160); + surface.drawBoxAlpha(dialogX + 399, dialogY + 29, 9, 170, 0x989898, 160); + surface.drawBoxAlpha(dialogX, dialogY + 199, 408, 47, 0x989898, 160); + surface.drawstring("Buying and selling items", dialogX + 1, dialogY + 10, 1, 0xffffff); + int colour = 0xffffff; + if (super.mouseX > dialogX + 320 && super.mouseY >= dialogY && super.mouseX < dialogX + 408 && super.mouseY < dialogY + 12) + colour = 0xff0000; + surface.drawstringRight("Close window", dialogX + 406, dialogY + 10, 1, colour); + surface.drawstring("Shops stock in green", dialogX + 2, dialogY + 24, 1, 65280); + surface.drawstring("Number you own in blue", dialogX + 135, dialogY + 24, 1, 65535); + surface.drawstring("Your money: " + getInventoryCount(10) + "gp", dialogX + 280, dialogY + 24, 1, 0xffff00); + int itemIndex = 0; + for (int row = 0; row < 5; row++) { + for (int col = 0; col < 8; col++) { + int slotX = dialogX + 7 + col * 49; + int slotY = dialogY + 28 + row * 34; + if (shopSelectedItemIndex == itemIndex) + surface.drawBoxAlpha(slotX, slotY, 49, 34, 0xff0000, 160); + else + surface.drawBoxAlpha(slotX, slotY, 49, 34, 0xd0d0d0, 160); + surface.drawBoxEdge(slotX, slotY, 50, 35, 0); + if (shopItem[itemIndex] != -1) { + surface.spriteClipping(slotX, slotY, 48, 32, spriteItem + GameData.itemPicture[shopItem[itemIndex]], GameData.itemMask[shopItem[itemIndex]], 0, 0, false); + surface.drawstring(String.valueOf(shopItemCount[itemIndex]), slotX + 1, slotY + 10, 1, 65280); + surface.drawstringRight(String.valueOf(getInventoryCount(shopItem[itemIndex])), slotX + 47, slotY + 10, 1, 65535); + } + itemIndex++; + } + + } + + surface.drawLineHoriz(dialogX + 5, dialogY + 222, 398, 0); + if (shopSelectedItemIndex == -1) { + surface.drawStringCenter("Select an object to buy or sell", dialogX + 204, dialogY + 214, 3, 0xffff00); + return; + } + int selectedItemType = shopItem[shopSelectedItemIndex]; + if (selectedItemType != -1) { + if (shopItemCount[shopSelectedItemIndex] > 0) { + int priceMod = shopBuyPriceMod + shopItemPrice[shopSelectedItemIndex]; + if (priceMod < 10) + priceMod = 10; + int itemPrice = (priceMod * GameData.itemBasePrice[selectedItemType]) / 100; + surface.drawstring("Buy a new " + GameData.itemName[selectedItemType] + " for " + itemPrice + "gp", dialogX + 2, dialogY + 214, 1, 0xffff00); + colour = 0xffffff; + if (super.mouseX > dialogX + 298 && super.mouseY >= dialogY + 204 && super.mouseX < dialogX + 408 && super.mouseY <= dialogY + 215) + colour = 0xff0000; + surface.drawstringRight("Click here to buy", dialogX + 405, dialogY + 214, 3, colour); + } else { + surface.drawStringCenter("This item is not currently available to buy", dialogX + 204, dialogY + 214, 3, 0xffff00); + } + if (getInventoryCount(selectedItemType) > 0) { + int priceMod = shopSellPriceMod + shopItemPrice[shopSelectedItemIndex]; + if (priceMod < 10) + priceMod = 10; + int itemPrice = (priceMod * GameData.itemBasePrice[selectedItemType]) / 100; + surface.drawstringRight("Sell your " + GameData.itemName[selectedItemType] + " for " + itemPrice + "gp", dialogX + 405, dialogY + 239, 1, 0xffff00); + colour = 0xffffff; + if (super.mouseX > dialogX + 2 && super.mouseY >= dialogY + 229 && super.mouseX < dialogX + 112 && super.mouseY <= dialogY + 240) + colour = 0xff0000; + surface.drawstring("Click here to sell", dialogX + 2, dialogY + 239, 3, colour); + return; + } + surface.drawStringCenter("You do not have any of this item to sell", dialogX + 204, dialogY + 239, 3, 0xffff00); + } + } + + private boolean hasInventoryItems(int id, int mincount) { + if (id == 31 && (isItemEquipped(197) || isItemEquipped(615) || isItemEquipped(682))) + return true; + if (id == 32 && (isItemEquipped(102) || isItemEquipped(616) || isItemEquipped(683))) + return true; + if (id == 33 && (isItemEquipped(101) || isItemEquipped(617) || isItemEquipped(684))) + return true; + if (id == 34 && (isItemEquipped(103) || isItemEquipped(618) || isItemEquipped(685))) + return true; + return getInventoryCount(id) >= mincount; + } + + private String getHostnameIP(int i) // and this? re: vvvv + { + return Utility.ip2string(i); + } + + protected void cantLogout() { + logoutTimeout = 0; + showMessage("@cya@Sorry, you can't logout at the moment", 3); + } + + private void drawGame() { + if (deathScreenTimeout != 0) { + surface.fade2black(); + surface.drawStringCenter("Oh dear! You are dead...", gameWidth / 2, gameHeight / 2, 7, 0xff0000); + drawChatMessageTabs(); + surface.draw(0, 0); + return; + } + if (showAppearanceChange) { + drawAppearancePanelCharacterSprites(); + return; + } + if (isSleeping) { + surface.fade2black(); + if (Math.random() < 0.14999999999999999D) + surface.drawStringCenter("ZZZ", (int) (Math.random() * 80D), (int) (Math.random() * 334D), 5, (int) (Math.random() * 16777215D)); + if (Math.random() < 0.14999999999999999D) + surface.drawStringCenter("ZZZ", 512 - (int) (Math.random() * 80D), (int) (Math.random() * 334D), 5, (int) (Math.random() * 16777215D)); + surface.drawBox(gameWidth / 2 - 100, 160, 200, 40, 0); + surface.drawStringCenter("You are sleeping", gameWidth / 2, 50, 7, 0xffff00); + surface.drawStringCenter("Fatigue: " + (fatigueSleeping * 100) / 750 + "%", gameWidth / 2, 90, 7, 0xffff00); + surface.drawStringCenter("When you want to wake up just use your", gameWidth / 2, 140, 5, 0xffffff); + surface.drawStringCenter("keyboard to type the word in the box below", gameWidth / 2, 160, 5, 0xffffff); + surface.drawStringCenter(super.inputTextCurrent + "*", gameWidth / 2, 180, 5, 65535); + if (sleepingStatusText == null) + surface.drawSprite(gameWidth / 2 - 127, 230, spriteTexture + 1); + else + surface.drawStringCenter(sleepingStatusText, gameWidth / 2, 260, 5, 0xff0000); + surface.drawBoxEdge(gameWidth / 2 - 128, 229, 257, 42, 0xffffff); + drawChatMessageTabs(); + surface.drawStringCenter("If you can't read the word", gameWidth / 2, 290, 1, 0xffffff); + surface.drawStringCenter("@yel@click here@whi@ to get a different one", gameWidth / 2, 305, 1, 0xffffff); + surface.draw(0, 0); + return; + } + if (!world.playerAlive) + return; + for (int i = 0; i < 64; i++) { + scene.removeModel(world.roofModels[lastHeightOffset][i]); + if (lastHeightOffset == 0) { + scene.removeModel(world.wallModels[1][i]); + scene.removeModel(world.roofModels[1][i]); + scene.removeModel(world.wallModels[2][i]); + scene.removeModel(world.roofModels[2][i]); + } + fogOfWar = true; + if (lastHeightOffset == 0 && (world.objectAdjacency[localPlayer.currentX / 128][localPlayer.currentY / 128] & 128) == 0) {// 0x80 + scene.addModel(world.roofModels[lastHeightOffset][i]); + if (lastHeightOffset == 0) { + scene.addModel(world.wallModels[1][i]); + scene.addModel(world.roofModels[1][i]); + scene.addModel(world.wallModels[2][i]); + scene.addModel(world.roofModels[2][i]); + } + fogOfWar = false; + } + } + + if (objectAnimationNumberFireLightningSpell != lastObjectAnimationNumberFireLightningSpell) { + lastObjectAnimationNumberFireLightningSpell = objectAnimationNumberFireLightningSpell; + for (int j = 0; j < objectCount; j++) { + if (objectId[j] == 97) + updateObjectAnimation(j, "firea" + (objectAnimationNumberFireLightningSpell + 1)); + if (objectId[j] == 274) + updateObjectAnimation(j, "fireplacea" + (objectAnimationNumberFireLightningSpell + 1)); + if (objectId[j] == 1031) + updateObjectAnimation(j, "lightning" + (objectAnimationNumberFireLightningSpell + 1)); + if (objectId[j] == 1036) + updateObjectAnimation(j, "firespell" + (objectAnimationNumberFireLightningSpell + 1)); + if (objectId[j] == 1147) + updateObjectAnimation(j, "spellcharge" + (objectAnimationNumberFireLightningSpell + 1)); + } + + } + if (objectAnimationNumberTorch != lastObjectAnimationNumberTorch) { + lastObjectAnimationNumberTorch = objectAnimationNumberTorch; + for (int k = 0; k < objectCount; k++) { + if (objectId[k] == 51) + updateObjectAnimation(k, "torcha" + (objectAnimationNumberTorch + 1)); + if (objectId[k] == 143) + updateObjectAnimation(k, "skulltorcha" + (objectAnimationNumberTorch + 1)); + } + + } + if (objectAnimationNumberClaw != lastOjectAnimationNumberClaw) { + lastOjectAnimationNumberClaw = objectAnimationNumberClaw; + for (int l = 0; l < objectCount; l++) + if (objectId[l] == 1142) + updateObjectAnimation(l, "clawspell" + (objectAnimationNumberClaw + 1)); + + } + scene.reduceSprites(spriteCount); + spriteCount = 0; + for (int i = 0; i < playerCount; i++) { + GameCharacter character = players[i]; + if (character.colourBottom != 255) { + int x = character.currentX; + int y = character.currentY; + int elev = -world.getElevation(x, y); + int id = scene.addSprite(5000 + i, x, elev, y, 145, 220, i + 10000); + spriteCount++; + if (character == localPlayer) + scene.setLocalPlayer(id); + if (character.animationCurrent == 8) + scene.setSpriteTranslateX(id, -30); + if (character.animationCurrent == 9) + scene.setSpriteTranslateX(id, 30); + } + } + + for (int i = 0; i < playerCount; i++) { + GameCharacter player = players[i]; + if (player.projectileRange > 0) { + GameCharacter character = null; + if (player.attackingNpcServerIndex != -1) + character = npcsServer[player.attackingNpcServerIndex]; + else if (player.attackingPlayerServerIndex != -1) + character = playerServer[player.attackingPlayerServerIndex]; + if (character != null) { + int sx = player.currentX; + int sy = player.currentY; + int selev = -world.getElevation(sx, sy) - 110; + int dx = character.currentX; + int dy = character.currentY; + int delev = -world.getElevation(dx, dy) - GameData.npcHeight[character.npcId] / 2; + int rx = (sx * player.projectileRange + dx * (projectileMaxRange - player.projectileRange)) / projectileMaxRange; + int rz = (selev * player.projectileRange + delev * (projectileMaxRange - player.projectileRange)) / projectileMaxRange; + int ry = (sy * player.projectileRange + dy * (projectileMaxRange - player.projectileRange)) / projectileMaxRange; + scene.addSprite(spriteProjectile + player.incomingProjectileSprite, rx, rz, ry, 32, 32, 0); + spriteCount++; + } + } + } + + for (int i = 0; i < npcCount; i++) { + GameCharacter character_3 = npcs[i]; + int i3 = character_3.currentX; + int j4 = character_3.currentY; + int i7 = -world.getElevation(i3, j4); + int i9 = scene.addSprite(20000 + i, i3, i7, j4, GameData.npcWidth[character_3.npcId], GameData.npcHeight[character_3.npcId], i + 30000); + spriteCount++; + if (character_3.animationCurrent == 8) + scene.setSpriteTranslateX(i9, -30); + if (character_3.animationCurrent == 9) + scene.setSpriteTranslateX(i9, 30); + } + + for (int i = 0; i < groundItemCount; i++) { + int x = groundItemX[i] * magicLoc + 64; + int y = groundItemY[i] * magicLoc + 64; + scene.addSprite(40000 + groundItemId[i], x, -world.getElevation(x, y) - groundItemZ[i], y, 96, 64, i + 20000); + spriteCount++; + } + + for (int i = 0; i < teleportBubbleCount; i++) { + int l4 = teleportBubbleX[i] * magicLoc + 64; + int j7 = teleportBubbleY[i] * magicLoc + 64; + int j9 = teleportBubbleType[i]; + if (j9 == 0) { + scene.addSprite(50000 + i, l4, -world.getElevation(l4, j7), j7, 128, 256, i + 50000); + spriteCount++; + } + if (j9 == 1) { + scene.addSprite(50000 + i, l4, -world.getElevation(l4, j7), j7, 128, 64, i + 50000); + spriteCount++; + } + } + + surface.interlace = false; + surface.blackScreen(); + surface.interlace = super.interlace; + if (lastHeightOffset == 3) { + int i5 = 40 + (int) (Math.random() * 3D); + int k7 = 40 + (int) (Math.random() * 7D); + scene.setLight(i5, k7, -50, -10, -50); + } + itemsAboveHeadCount = 0; + receivedMessagesCount = 0; + healthBarCount = 0; + if (cameraAutoAngleDebug) { + if (optionCameraModeAuto && !fogOfWar) { + int j5 = cameraAngle; + autorotateCamera(); + if (cameraAngle != j5) { + cameraAutoRotatePlayerX = localPlayer.currentX; + cameraAutoRotatePlayerY = localPlayer.currentY; + } + } + scene.clipFar3d = 3000; + scene.clipFar2d = 3000; + scene.fogZFalloff = 1; + scene.fogZDistance = 2800; + cameraRotation = cameraAngle * 32; + int x = cameraAutoRotatePlayerX + cameraRotationX; + int y = cameraAutoRotatePlayerY + cameraRotationY; + scene.setCamera(x, -world.getElevation(x, y), y, 912, cameraRotation * 4, 0, 2000); + } else { + if (optionCameraModeAuto && !fogOfWar) + autorotateCamera(); + if (!super.interlace) { + scene.clipFar3d = 2400; + scene.clipFar2d = 2400; + scene.fogZFalloff = 1; + scene.fogZDistance = 2300; + } else { + scene.clipFar3d = 2200; + scene.clipFar2d = 2200; + scene.fogZFalloff = 1; + scene.fogZDistance = 2100; + } + int x = cameraAutoRotatePlayerX + cameraRotationX; + int y = cameraAutoRotatePlayerY + cameraRotationY; + scene.setCamera(x, -world.getElevation(x, y), y, 912, cameraRotation * 4, 0, cameraZoom * 2); + } + scene.render(); + drawAboveHeadStuff(); + if (mouseClickXStep > 0) + surface.drawSprite(mouseClickXX - 8, mouseClickXY - 8, spriteMedia + 14 + (24 - mouseClickXStep) / 6); + if (mouseClickXStep < 0) + surface.drawSprite(mouseClickXX - 8, mouseClickXY - 8, spriteMedia + 18 + (24 + mouseClickXStep) / 6); + + this.surface.drawStringCenter( + "Fps: " + this.fps, + this.gameWidth - 62, + this.gameHeight - 10, + 1, + 0xffff00 + ); + + if (systemUpdate != 0) { + int i6 = systemUpdate / 50; + int j8 = i6 / 60; + i6 %= 60; + if (i6 < 10) + surface.drawStringCenter("System update in: " + j8 + ":0" + i6, 256, gameHeight - 7, 1, 0xffff00); + else + surface.drawStringCenter("System update in: " + j8 + ":" + i6, 256, gameHeight - 7, 1, 0xffff00); + } + if (!loadingArea) { + int j6 = 2203 - (localRegionY + planeHeight + regionY); + if (localRegionX + planeWidth + regionX >= 2640) + j6 = -50; + if (j6 > 0) { + int wildlvl = 1 + j6 / 6; + surface.drawSprite(453, gameHeight - 56, spriteMedia + 13); + surface.drawStringCenter("Wilderness", 465, gameHeight - 20, 1, 0xffff00); + surface.drawStringCenter("Level: " + wildlvl, 465, gameHeight - 7, 1, 0xffff00); + if (showUiWildWarn == 0) + showUiWildWarn = 2; + } + if (showUiWildWarn == 0 && j6 > -10 && j6 <= 0) + showUiWildWarn = 1; + } + if (messageTabSelected == 0) { + for (int k6 = 0; k6 < 5; k6++) + if (messageHistoryTimeout[k6] > 0) { + String s = messageHistory[k6]; + surface.drawstring(s, 7, gameHeight - 18 - k6 * 12, 1, 0xffff00); + } + + } + panelMessageTabs.hide(controlTextListChat); + panelMessageTabs.hide(controlTextListQuest); + panelMessageTabs.hide(controlTextListPrivate); + if (messageTabSelected == 1) + panelMessageTabs.show(controlTextListChat); + else if (messageTabSelected == 2) + panelMessageTabs.show(controlTextListQuest); + else if (messageTabSelected == 3) + panelMessageTabs.show(controlTextListPrivate); + Panel.textListEntryHeightMod = 2; + panelMessageTabs.drawPanel(); + Panel.textListEntryHeightMod = 0; + surface.drawSpriteAlpha(surface.width2 - 3 - 197, 3, spriteMedia, 128); + drawUi(); + surface.loggedIn = false; + drawChatMessageTabs(); + surface.draw(0, 0); + } + + private void loadSounds() { + try { + soundData = readDataFile("sounds" + Version.SOUNDS + ".mem", "Sound effects", 90); + audioPlayer = new StreamAudioPlayer(); + return; + } catch (Throwable throwable) { + System.out.println("Unable to init sounds:" + throwable); + } + } + + private boolean isItemEquipped(int i) { + for (int j = 0; j < inventoryItemsCount; j++) + if (inventoryItemId[j] == i && inventoryEquipped[j] == 1) + return true; + + return false; + } + + private void loadEntities() { + byte entityBuff[] = null; + byte indexDat[] = null; + entityBuff = readDataFile("entity" + Version.ENTITY + ".jag", "people and monsters", 30); + if (entityBuff == null) { + errorLoadingData = true; + return; + } + indexDat = Utility.loadData("index.dat", 0, entityBuff); + byte entityBuffMem[] = null; + byte indexDatMem[] = null; + if (members) { + entityBuffMem = readDataFile("entity" + Version.ENTITY + ".mem", "member graphics", 45); + if (entityBuffMem == null) { + errorLoadingData = true; + return; + } + indexDatMem = Utility.loadData("index.dat", 0, entityBuffMem); + } + int frameCount = 0; + anInt659 = 0; + anInt660 = anInt659; + label0: + for (int j = 0; j < GameData.animationCount; j++) { + String s = GameData.animationName[j]; + for (int k = 0; k < j; k++) { + if (!GameData.animationName[k].equalsIgnoreCase(s)) + continue; + GameData.animationNumber[j] = GameData.animationNumber[k]; + continue label0; + } + + byte abyte7[] = Utility.loadData(s + ".dat", 0, entityBuff); + byte abyte4[] = indexDat; + if (abyte7 == null && members) { + abyte7 = Utility.loadData(s + ".dat", 0, entityBuffMem); + abyte4 = indexDatMem; + } + if (abyte7 != null) { + surface.parseSprite(anInt660, abyte7, abyte4, 15); + frameCount += 15; + if (GameData.animationHasA[j] == 1) { + byte aDat[] = Utility.loadData(s + "a.dat", 0, entityBuff); + byte aIndexDat[] = indexDat; + if (aDat == null && members) { + aDat = Utility.loadData(s + "a.dat", 0, entityBuffMem); + aIndexDat = indexDatMem; + } + surface.parseSprite(anInt660 + 15, aDat, aIndexDat, 3); + frameCount += 3; + } + if (GameData.animationHasF[j] == 1) { + byte fDat[] = Utility.loadData(s + "f.dat", 0, entityBuff); + byte fDatIndex[] = indexDat; + if (fDat == null && members) { + fDat = Utility.loadData(s + "f.dat", 0, entityBuffMem); + fDatIndex = indexDatMem; + } + surface.parseSprite(anInt660 + 18, fDat, fDatIndex, 9); + frameCount += 9; + } + if (GameData.animationSomething[j] != 0) { + for (int l = anInt660; l < anInt660 + 27; l++) + surface.loadSprite(l); + + } + } + GameData.animationNumber[j] = anInt660; + anInt660 += 27; + } + + //System.out.println("Loaded: " + frameCount + " frames of animation"); + } + + private void handleAppearancePanelControls() { + panelAppearance.handleMouse(super.mouseX, super.mouseY, super.lastMouseButtonDown, super.mouseButtonDown); + if (panelAppearance.isClicked(controlButtonAppearanceHead1)) + do + appearanceHeadType = ((appearanceHeadType - 1) + GameData.animationCount) % GameData.animationCount; + while ((GameData.animationSomething[appearanceHeadType] & 3) != 1 || (GameData.animationSomething[appearanceHeadType] & 4 * appearanceHeadGender) == 0); + if (panelAppearance.isClicked(controlButtonAppearanceHead2)) + do + appearanceHeadType = (appearanceHeadType + 1) % GameData.animationCount; + while ((GameData.animationSomething[appearanceHeadType] & 3) != 1 || (GameData.animationSomething[appearanceHeadType] & 4 * appearanceHeadGender) == 0); + if (panelAppearance.isClicked(controlButtonAppearanceHair1)) + appearanceHairColour = ((appearanceHairColour - 1) + characterHairColours.length) % characterHairColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceHair2)) + appearanceHairColour = (appearanceHairColour + 1) % characterHairColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceGender1) || panelAppearance.isClicked(controlButtonAppearanceGender2)) { + for (appearanceHeadGender = 3 - appearanceHeadGender; (GameData.animationSomething[appearanceHeadType] & 3) != 1 || (GameData.animationSomething[appearanceHeadType] & 4 * appearanceHeadGender) == 0; appearanceHeadType = (appearanceHeadType + 1) % GameData.animationCount) + ; + for (; (GameData.animationSomething[appearanceBodyGender] & 3) != 2 || (GameData.animationSomething[appearanceBodyGender] & 4 * appearanceHeadGender) == 0; appearanceBodyGender = (appearanceBodyGender + 1) % GameData.animationCount) + ; + } + if (panelAppearance.isClicked(controlButtonAppearanceTop1)) + appearanceTopColour = ((appearanceTopColour - 1) + characterTopBottomColours.length) % characterTopBottomColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceTop2)) + appearanceTopColour = (appearanceTopColour + 1) % characterTopBottomColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceSkin1)) + appearanceSkinColour = ((appearanceSkinColour - 1) + characterSkinColours.length) % characterSkinColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceSkin2)) + appearanceSkinColour = (appearanceSkinColour + 1) % characterSkinColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceBottom1)) + appearanceBottomColour = ((appearanceBottomColour - 1) + characterTopBottomColours.length) % characterTopBottomColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceBottom2)) + appearanceBottomColour = (appearanceBottomColour + 1) % characterTopBottomColours.length; + if (panelAppearance.isClicked(controlButtonAppearanceAccept)) { + super.clientStream.newPacket((Command.CL_APPEARANCE)); + super.clientStream.putByte(appearanceHeadGender); + super.clientStream.putByte(appearanceHeadType); + super.clientStream.putByte(appearanceBodyGender); + super.clientStream.putByte(appearance2Colour); + super.clientStream.putByte(appearanceHairColour); + super.clientStream.putByte(appearanceTopColour); + super.clientStream.putByte(appearanceBottomColour); + super.clientStream.putByte(appearanceSkinColour); + super.clientStream.sendPacket(); + surface.blackScreen(); + showAppearanceChange = false; + } + } + + protected void draw() { + /* + if (errorLoadingData) { + Graphics g = getGraphics(); + g.setColor(Color.black); + g.fillRect(0, 0, 512, 356); + g.setFont(new Font("Helvetica", 1, 16)); + g.setColor(Color.yellow); + int i = 35; + g.drawString("Sorry, an error has occured whilst loading RuneScape", 30, i); + i += 50; + g.setColor(Color.white); + g.drawString("To fix this try the following (in order):", 30, i); + i += 50; + g.setColor(Color.white); + g.setFont(new Font("Helvetica", 1, 12)); + g.drawString("1: Try closing ALL open web-browser windows, and reloading", 30, i); + i += 30; + g.drawString("2: Try clearing your web-browsers cache from tools->internet options", 30, i); + i += 30; + g.drawString("3: Try using a different game-world", 30, i); + i += 30; + g.drawString("4: Try rebooting your computer", 30, i); + i += 30; + g.drawString("5: Try selecting a different version of Java from the play-game menu", 30, i); + setTargetFps(1); + return; + } + + if (errorLoadingCodebase) { + Graphics g1 = getGraphics(); + g1.setColor(Color.black); + g1.fillRect(0, 0, 512, 356); + g1.setFont(new Font("Helvetica", 1, 20)); + g1.setColor(Color.white); + g1.drawString("Error - unable to load game!", 50, 50); + g1.drawString("To play RuneScape make sure you play from", 50, 100); + g1.drawString("http://www.runescape.com", 50, 150); + setTargetFps(1); + return; + } + + if (errorLoadingMemory) { + Graphics g2 = getGraphics(); + g2.setColor(Color.black); + g2.fillRect(0, 0, 512, 356); + g2.setFont(new Font("Helvetica", 1, 20)); + g2.setColor(Color.white); + g2.drawString("Error - out of memory!", 50, 50); + g2.drawString("Close ALL unnecessary programs", 50, 100); + g2.drawString("and windows before loading the game", 50, 150); + g2.drawString("RuneScape needs about 48meg of spare RAM", 50, 200); + setTargetFps(1); + return; + }*/ + + try { + if (loggedIn == 0) { + surface.loggedIn = false; + drawLoginScreens(); + } + if (loggedIn == 1) { + surface.loggedIn = true; + drawGame(); + return; + } + } catch (OutOfMemoryError Ex) { + disposeAndCollect(); + errorLoadingMemory = true; + } + } + + protected void onClosing() { + closeConnection(); + disposeAndCollect(); + if (audioPlayer != null) + audioPlayer.stopPlayer(); + } + + private void drawDialogDuelConfirm() { + int dialogX = gameWidth / 2 - 468 / 2 + 22; + int dialogY = gameHeight / 2 - 262 / 2 + 36; + //byte dialogX = 22; + //byte dialogY = 36; + surface.drawBox(dialogX, dialogY, 468, 16, 192); + surface.drawBoxAlpha(dialogX, dialogY + 16, 468, 246, 0x989898, 160); + surface.drawStringCenter("Please confirm your duel with @yel@" + Utility.hash2username(duelOpponentNameHash), dialogX + 234, dialogY + 12, 1, 0xffffff); + surface.drawStringCenter("Your stake:", dialogX + 117, dialogY + 30, 1, 0xffff00); + for (int itemIndex = 0; itemIndex < duelItemsCount; itemIndex++) { + String s = GameData.itemName[duelItems[itemIndex]]; + if (GameData.itemStackable[duelItems[itemIndex]] == 0) + s = s + " x " + formatNumber(duelItemCount[itemIndex]); + surface.drawStringCenter(s, dialogX + 117, dialogY + 42 + itemIndex * 12, 1, 0xffffff); + } + + if (duelItemsCount == 0) + surface.drawStringCenter("Nothing!", dialogX + 117, dialogY + 42, 1, 0xffffff); + surface.drawStringCenter("Your opponent's stake:", dialogX + 351, dialogY + 30, 1, 0xffff00); + for (int itemIndex = 0; itemIndex < duelOpponentItemsCount; itemIndex++) { + String s1 = GameData.itemName[duelOpponentItems[itemIndex]]; + if (GameData.itemStackable[duelOpponentItems[itemIndex]] == 0) + s1 = s1 + " x " + formatNumber(duelOpponentItemCount[itemIndex]); + surface.drawStringCenter(s1, dialogX + 351, dialogY + 42 + itemIndex * 12, 1, 0xffffff); + } + + if (duelOpponentItemsCount == 0) + surface.drawStringCenter("Nothing!", dialogX + 351, dialogY + 42, 1, 0xffffff); + if (duelOptionRetreat == 0) + surface.drawStringCenter("You can retreat from this duel", dialogX + 234, dialogY + 180, 1, 65280); + else + surface.drawStringCenter("No retreat is possible!", dialogX + 234, dialogY + 180, 1, 0xff0000); + if (duelOptionMagic == 0) + surface.drawStringCenter("Magic may be used", dialogX + 234, dialogY + 192, 1, 65280); + else + surface.drawStringCenter("Magic cannot be used", dialogX + 234, dialogY + 192, 1, 0xff0000); + if (duelOptionPrayer == 0) + surface.drawStringCenter("Prayer may be used", dialogX + 234, dialogY + 204, 1, 65280); + else + surface.drawStringCenter("Prayer cannot be used", dialogX + 234, dialogY + 204, 1, 0xff0000); + if (duelOptionWeapons == 0) + surface.drawStringCenter("Weapons may be used", dialogX + 234, dialogY + 216, 1, 65280); + else + surface.drawStringCenter("Weapons cannot be used", dialogX + 234, dialogY + 216, 1, 0xff0000); + surface.drawStringCenter("If you are sure click 'Accept' to begin the duel", dialogX + 234, dialogY + 230, 1, 0xffffff); + if (!duelAccepted) { + surface.drawSprite((dialogX + 118) - 35, dialogY + 238, spriteMedia + 25); + surface.drawSprite((dialogX + 352) - 35, dialogY + 238, spriteMedia + 26); + } else { + surface.drawStringCenter("Waiting for other player...", dialogX + 234, dialogY + 250, 1, 0xffff00); + } + if (mouseButtonClick == 1) { + if (super.mouseX < dialogX || super.mouseY < dialogY || super.mouseX > dialogX + 468 || super.mouseY > dialogY + 262) { + showDialogDuelConfirm = false; + super.clientStream.newPacket((Command.CL_TRADE_DECLINE)); + super.clientStream.sendPacket(); + } + if (super.mouseX >= (dialogX + 118) - 35 && super.mouseX <= dialogX + 118 + 70 && super.mouseY >= dialogY + 238 && super.mouseY <= dialogY + 238 + 21) { + duelAccepted = true; + super.clientStream.newPacket((Command.CL_DUEL_CONFIRM_ACCEPT)); + super.clientStream.sendPacket(); + } + if (super.mouseX >= (dialogX + 352) - 35 && super.mouseX <= dialogX + 353 + 70 && super.mouseY >= dialogY + 238 && super.mouseY <= dialogY + 238 + 21) { + showDialogDuelConfirm = false; + super.clientStream.newPacket((Command.CL_DUEL_DECLINE)); + super.clientStream.sendPacket(); + } + mouseButtonClick = 0; + } + } + + private void walkToGroundItem(int i, int j, int k, int l, boolean walkToAction) { + if (walkTo(i, j, k, l, k, l, false, walkToAction)) { + return; + } else { + walkToActionSource(i, j, k, l, k, l, true, walkToAction); + return; + } + } + + private void loadModels() { + GameData.getModelIndex("torcha2"); + GameData.getModelIndex("torcha3"); + GameData.getModelIndex("torcha4"); + GameData.getModelIndex("skulltorcha2"); + GameData.getModelIndex("skulltorcha3"); + GameData.getModelIndex("skulltorcha4"); + GameData.getModelIndex("firea2"); + GameData.getModelIndex("firea3"); + GameData.getModelIndex("fireplacea2"); + GameData.getModelIndex("fireplacea3"); + GameData.getModelIndex("firespell2"); + GameData.getModelIndex("firespell3"); + GameData.getModelIndex("lightning2"); + GameData.getModelIndex("lightning3"); + GameData.getModelIndex("clawspell2"); + GameData.getModelIndex("clawspell3"); + GameData.getModelIndex("clawspell4"); + GameData.getModelIndex("clawspell5"); + GameData.getModelIndex("spellcharge2"); + GameData.getModelIndex("spellcharge3"); + //if (getStartedAsApplet()) { // always show models on loading screen viewports + if (true) { + byte abyte0[] = readDataFile("models" + Version.MODELS + ".jag", "3d models", 60); + if (abyte0 == null) { + errorLoadingData = true; + return; + } + for (int j = 0; j < GameData.modelCount; j++) { + int k = Utility.getDataFileOffset(GameData.modelName[j] + ".ob3", abyte0); + if (k != 0) + gameModels[j] = new GameModel(abyte0, k, true); + else + gameModels[j] = new GameModel(1, 1); + if (GameData.modelName[j].equals("giantcrystal")) + gameModels[j].transparent = true; + } + + return; + } + /*showLoadingProgress(70, "Loading 3d models"); + for (int i = 0; i < GameData.modelCount; i++) { + gameModels[i] = new GameModel("../gamedata/models/" + GameData.modelName[i] + ".ob2"); + if (GameData.modelName[i].equals("giantcrystal")) + gameModels[i].transparent = true; + }*/ + } + + private void drawDialogServermessage() { + int width = 400;// '\u0190'; + int height = 100;// 'd'; + if (serverMessageBoxTop) { + height = 450;// '\u01C2'; // why is this set twice + height = 300;// '\u012C'; + } + surface.drawBox(256 - width / 2, 167 - height / 2, width, height, 0); + surface.drawBoxEdge(256 - width / 2, 167 - height / 2, width, height, 0xffffff); + surface.centrepara(serverMessage, 256, (167 - height / 2) + 20, 1, 0xffffff, width - 40); + int i = 157 + height / 2; + int j = 0xffffff; + if (super.mouseY > i - 12 && super.mouseY <= i && super.mouseX > 106 && super.mouseX < 406) + j = 0xff0000; + surface.drawStringCenter("Click here to close window", 256, i, 1, j); + if (mouseButtonClick == 1) { + if (j == 0xff0000) + showDialogServermessage = false; + if ((super.mouseX < 256 - width / 2 || super.mouseX > 256 + width / 2) && (super.mouseY < 167 - height / 2 || super.mouseY > 167 + height / 2)) + showDialogServermessage = false; + } + mouseButtonClick = 0; + } + + private void drawDialogReportAbuseInput() { + if (super.inputTextFinal.length() > 0) { + String s = super.inputTextFinal.trim(); + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + if (s.length() > 0) { + long l = Utility.username2hash(s); + super.clientStream.newPacket((Command.CL_REPORT_ABUSE)); + super.clientStream.putLong(l); + super.clientStream.putByte(reportAbuseOffence); + super.clientStream.putByte(reportAbuseMute ? 1 : 0); + super.clientStream.sendPacket(); + } + showDialogReportAbuseStep = 0; + return; + } + surface.drawBox(56, 130, 400, 100, 0); + surface.drawBoxEdge(56, 130, 400, 100, 0xffffff); + int i = 160; + surface.drawStringCenter("Now type the name of the offending player, and press enter", 256, i, 1, 0xffff00); + i += 18; + surface.drawStringCenter("Name: " + super.inputTextCurrent + "*", 256, i, 4, 0xffffff); + if (super.moderatorLevel > 0) { + i = 207; + if (reportAbuseMute) + surface.drawStringCenter("Moderator option: Mute player for 48 hours: ", 256, i, 1, 0xff8000); + else + surface.drawStringCenter("Moderator option: Mute player for 48 hours: ", 256, i, 1, 0xffffff); + if (super.mouseX > 106 && super.mouseX < 406 && super.mouseY > i - 13 && super.mouseY < i + 2 && mouseButtonClick == 1) { + mouseButtonClick = 0; + reportAbuseMute = !reportAbuseMute; + } + } + i = 222; + int j = 0xffffff; + if (super.mouseX > 196 && super.mouseX < 316 && super.mouseY > i - 13 && super.mouseY < i + 2) { + j = 0xffff00; + if (mouseButtonClick == 1) { + mouseButtonClick = 0; + showDialogReportAbuseStep = 0; + } + } + surface.drawStringCenter("Click here to cancel", 256, i, 1, j); + if (mouseButtonClick == 1 && (super.mouseX < 56 || super.mouseX > 456 || super.mouseY < 130 || super.mouseY > 230)) { + mouseButtonClick = 0; + showDialogReportAbuseStep = 0; + } + } + + private void showMessage(String message, int type) { + if (type == 2 || type == 4 || type == 6) { + for (; message.length() > 5 && message.charAt(0) == '@' && message.charAt(4) == '@'; message = message.substring(5)) + ; + int j = message.indexOf(":"); + if (j != -1) { + String s1 = message.substring(0, j); + long l = Utility.username2hash(s1); + for (int i1 = 0; i1 < super.ignoreListCount; i1++) + if (super.ignoreList[i1] == l) + return; + + } + } + if (type == 2) + message = "@yel@" + message; + if (type == 3 || type == 4) + message = "@whi@" + message; + if (type == 6) + message = "@cya@" + message; + if (messageTabSelected != 0) { + if (type == 4 || type == 3) + messageTabFlashAll = 200; + if (type == 2 && messageTabSelected != 1) + messageTabFlashHistory = 200; + if (type == 5 && messageTabSelected != 2) + messtageTabFlashQuest = 200; + if (type == 6 && messageTabSelected != 3) + messageTabFlashPrivate = 200; + if (type == 3 && messageTabSelected != 0) + messageTabSelected = 0; + if (type == 6 && messageTabSelected != 3 && messageTabSelected != 0) + messageTabSelected = 0; + } + for (int k = 4; k > 0; k--) { + messageHistory[k] = messageHistory[k - 1]; + messageHistoryTimeout[k] = messageHistoryTimeout[k - 1]; + } + + messageHistory[0] = message; + messageHistoryTimeout[0] = 300; + if (type == 2) + if (panelMessageTabs.controlFlashText[controlTextListChat] == panelMessageTabs.controlListEntryCount[controlTextListChat] - 4) + panelMessageTabs.removeListEntry(controlTextListChat, message, true); + else + panelMessageTabs.removeListEntry(controlTextListChat, message, false); + if (type == 5) + if (panelMessageTabs.controlFlashText[controlTextListQuest] == panelMessageTabs.controlListEntryCount[controlTextListQuest] - 4) + panelMessageTabs.removeListEntry(controlTextListQuest, message, true); + else + panelMessageTabs.removeListEntry(controlTextListQuest, message, false); + if (type == 6) { + if (panelMessageTabs.controlFlashText[controlTextListPrivate] == panelMessageTabs.controlListEntryCount[controlTextListPrivate] - 4) { + panelMessageTabs.removeListEntry(controlTextListPrivate, message, true); + return; + } + panelMessageTabs.removeListEntry(controlTextListPrivate, message, false); + } + } + + private void walkToObject(int x, int y, int id, int index) { + int w; + int h; + if (id == 0 || id == 4) { + w = GameData.objectWidth[index]; + h = GameData.objectHeight[index]; + } else { + h = GameData.objectWidth[index]; + w = GameData.objectHeight[index]; + } + if (GameData.objectType[index] == 2 || GameData.objectType[index] == 3) { + if (id == 0) { + x--; + w++; + } + if (id == 2) + h++; + if (id == 4) + w++; + if (id == 6) { + y--; + h++; + } + walkToActionSource(localRegionX, localRegionY, x, y, (x + w) - 1, (y + h) - 1, false, true); + return; + } else { + walkToActionSource(localRegionX, localRegionY, x, y, (x + w) - 1, (y + h) - 1, true, true); + return; + } + } + + private int getInventoryCount(int id) { + int count = 0; + for (int k = 0; k < inventoryItemsCount; k++) + if (inventoryItemId[k] == id) + if (GameData.itemStackable[id] == 1) + count++; + else + count += inventoryItemStackCount[k]; + + return count; + } + + private void drawLoginScreens() { + welcomScreenAlreadyShown = false; + surface.interlace = false; + surface.blackScreen(); + if (loginScreen == 0 || loginScreen == 1 || loginScreen == 2 || loginScreen == 3) { + int i = (loginTimer * 2) % 3072; + if (i < 1024) { + surface.drawSprite(0, 10, spriteLogo); + if (i > 768) + surface.drawSpriteAlpha(0, 10, spriteLogo + 1, i - 768); + } else if (i < 2048) { + surface.drawSprite(0, 10, spriteLogo + 1); + if (i > 1792) + surface.drawSpriteAlpha(0, 10, spriteMedia + 10, i - 1792); + } else { + surface.drawSprite(0, 10, spriteMedia + 10); + if (i > 2816) + surface.drawSpriteAlpha(0, 10, spriteLogo, i - 2816); + } + } + if (loginScreen == 0) + panelLoginWelcome.drawPanel(); + if (loginScreen == 1) + panelLoginNewuser.drawPanel(); + if (loginScreen == 2) + panelLoginExistinguser.drawPanel(); + //surface.drawPicture(0, gameHeight, spriteMedia + 22); // blue bar + //surface.drawLineAlpha(50, 50, 150, 150, 100, 100); + //drawUiTabMinimap(true); + surface.draw(0, 0); + } + + private void drawUiTabOptions(boolean flag) { + int uiX = surface.width2 - 199; + int uiY = 36; + surface.drawSprite(uiX - 49, 3, spriteMedia + 6); + int uiWidth = 196;// '\304'; + surface.drawBoxAlpha(uiX, 36, uiWidth, 65, Surface.rgb2long(181, 181, 181), 160); + surface.drawBoxAlpha(uiX, 101, uiWidth, 65, Surface.rgb2long(201, 201, 201), 160); + surface.drawBoxAlpha(uiX, 166, uiWidth, 95, Surface.rgb2long(181, 181, 181), 160); + surface.drawBoxAlpha(uiX, 261, uiWidth, 40, Surface.rgb2long(201, 201, 201), 160); + int x = uiX + 3; + int y = uiY + 15; + surface.drawstring("Game options - click to toggle", x, y, 1, 0); + y += 15; + if (optionCameraModeAuto) + surface.drawstring("Camera angle mode - @gre@Auto", x, y, 1, 0xffffff); + else + surface.drawstring("Camera angle mode - @red@Manual", x, y, 1, 0xffffff); + y += 15; + if (optionMouseButtonOne) + surface.drawstring("Mouse buttons - @red@One", x, y, 1, 0xffffff); + else + surface.drawstring("Mouse buttons - @gre@Two", x, y, 1, 0xffffff); + y += 15; + if (members) + if (optionSoundDisabled) + surface.drawstring("Sound effects - @red@off", x, y, 1, 0xffffff); + else + surface.drawstring("Sound effects - @gre@on", x, y, 1, 0xffffff); + y += 15; + surface.drawstring("To change your contact details,", x, y, 0, 0xffffff); + y += 15; + surface.drawstring("password, recovery questions, etc..", x, y, 0, 0xffffff); + y += 15; + surface.drawstring("please select 'account management'", x, y, 0, 0xffffff); + y += 15; + if (referid == 0) + surface.drawstring("from the runescape.com front page", x, y, 0, 0xffffff); + else if (referid == 1) + surface.drawstring("from the link below the gamewindow", x, y, 0, 0xffffff); + else + surface.drawstring("from the runescape front webpage", x, y, 0, 0xffffff); + y += 15; + y += 5; + surface.drawstring("Privacy settings. Will be applied to", uiX + 3, y, 1, 0); + y += 15; + surface.drawstring("all people not on your friends list", uiX + 3, y, 1, 0); + y += 15; + if (super.settingsBlockChat == 0) + surface.drawstring("Block chat messages: @red@", uiX + 3, y, 1, 0xffffff); + else + surface.drawstring("Block chat messages: @gre@", uiX + 3, y, 1, 0xffffff); + y += 15; + if (super.settingsBlockPrivate == 0) + surface.drawstring("Block private messages: @red@", uiX + 3, y, 1, 0xffffff); + else + surface.drawstring("Block private messages: @gre@", uiX + 3, y, 1, 0xffffff); + y += 15; + if (super.settingsBlockTrade == 0) + surface.drawstring("Block trade requests: @red@", uiX + 3, y, 1, 0xffffff); + else + surface.drawstring("Block trade requests: @gre@", uiX + 3, y, 1, 0xffffff); + y += 15; + if (members) + if (super.settingsBlockDuel == 0) + surface.drawstring("Block duel requests: @red@", uiX + 3, y, 1, 0xffffff); + else + surface.drawstring("Block duel requests: @gre@", uiX + 3, y, 1, 0xffffff); + y += 15; + y += 5; + surface.drawstring("Always logout when you finish", x, y, 1, 0); + y += 15; + int k1 = 0xffffff; + if (super.mouseX > x && super.mouseX < x + uiWidth && super.mouseY > y - 12 && super.mouseY < y + 4) + k1 = 0xffff00; + surface.drawstring("Click here to logout", uiX + 3, y, 1, k1); + if (!flag) + return; + int mouseX = super.mouseX - (surface.width2 - 199); + int mouseY = super.mouseY - 36; + if (mouseX >= 0 && mouseY >= 0 && mouseX < 196 && mouseY < 265) { + int l1 = surface.width2 - 199; + byte byte0 = 36; + int c1 = 196;// '\304'; + int l = l1 + 3; + int j1 = byte0 + 30; + if (super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) { + optionCameraModeAuto = !optionCameraModeAuto; + super.clientStream.newPacket((Command.CL_SETTINGS_GAME)); + super.clientStream.putByte(0); + super.clientStream.putByte(optionCameraModeAuto ? 1 : 0); + super.clientStream.sendPacket(); + } + j1 += 15; + if (super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) { + optionMouseButtonOne = !optionMouseButtonOne; + super.clientStream.newPacket((Command.CL_SETTINGS_GAME)); + super.clientStream.putByte(2); + super.clientStream.putByte(optionMouseButtonOne ? 1 : 0); + super.clientStream.sendPacket(); + } + j1 += 15; + if (members && super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) { + optionSoundDisabled = !optionSoundDisabled; + super.clientStream.newPacket((Command.CL_SETTINGS_GAME)); + super.clientStream.putByte(3); + super.clientStream.putByte(optionSoundDisabled ? 1 : 0); + super.clientStream.sendPacket(); + } + j1 += 15; + j1 += 15; + j1 += 15; + j1 += 15; + j1 += 15; + boolean flag1 = false; + j1 += 35; + if (super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) { + super.settingsBlockChat = 1 - super.settingsBlockChat; + flag1 = true; + } + j1 += 15; + if (super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) { + super.settingsBlockPrivate = 1 - super.settingsBlockPrivate; + flag1 = true; + } + j1 += 15; + if (super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) { + super.settingsBlockTrade = 1 - super.settingsBlockTrade; + flag1 = true; + } + j1 += 15; + if (members && super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) { + super.settingsBlockDuel = 1 - super.settingsBlockDuel; + flag1 = true; + } + j1 += 15; + if (flag1) + sendPrivacySettings(super.settingsBlockChat, super.settingsBlockPrivate, super.settingsBlockTrade, super.settingsBlockDuel); + j1 += 20; + if (super.mouseX > l && super.mouseX < l + c1 && super.mouseY > j1 - 12 && super.mouseY < j1 + 4 && mouseButtonClick == 1) + sendLogout(); + mouseButtonClick = 0; + } + } + + private void loadTextures() { + byte buffTextures[] = readDataFile("textures" + Version.TEXTURES + ".jag", "Textures", 50); + if (buffTextures == null) { + errorLoadingData = true; + return; + } + byte buffIndex[] = Utility.loadData("index.dat", 0, buffTextures); + scene.allocateTextures(GameData.textureCount, 7, 11); + for (int i = 0; i < GameData.textureCount; i++) { + String name = GameData.textureName[i]; + byte buff1[] = Utility.loadData(name + ".dat", 0, buffTextures); + surface.parseSprite(spriteTexture, buff1, buffIndex, 1); + surface.drawBox(0, 0, 128, 128, 0xff00ff); + surface.drawSprite(0, 0, spriteTexture); + int wh = surface.spriteWidthFull[spriteTexture]; + String nameSub = GameData.textureSubtypeName[i]; + if (nameSub != null && nameSub.length() > 0) { + byte buff2[] = Utility.loadData(nameSub + ".dat", 0, buffTextures); + surface.parseSprite(spriteTexture, buff2, buffIndex, 1); + surface.drawSprite(0, 0, spriteTexture); + } + surface.drawSprite(spriteTextureWorld + i, 0, 0, wh, wh); + int area = wh * wh; + for (int j = 0; j < area; j++) + if (surface.surfacePixels[spriteTextureWorld + i][j] == 65280) + surface.surfacePixels[spriteTextureWorld + i][j] = 0xff00ff; + + surface.drawWorld(spriteTextureWorld + i); + scene.defineTexture(i, surface.spriteColoursUsed[spriteTextureWorld + i], surface.spriteColourList[spriteTextureWorld + i], wh / 64 - 1); + } + + } + + protected void handleMouseDown(int i, int j, int k) { + mouseClickXHistory[mouseClickCount] = j; + mouseClickYHistory[mouseClickCount] = k; + mouseClickCount = mouseClickCount + 1 & 8191;// 0x1fff + for (int l = 10; l < 4000; l++) { + int i1 = mouseClickCount - l & 8191;// 0x1fff + if (mouseClickXHistory[i1] == j && mouseClickYHistory[i1] == k) { + boolean flag = false; + for (int j1 = 1; j1 < l; j1++) { + int k1 = mouseClickCount - j1 & 8191;// 0x1fff + int l1 = i1 - j1 & 8191;// 0x1fff + if (mouseClickXHistory[l1] != j || mouseClickYHistory[l1] != k) + flag = true; + if (mouseClickXHistory[k1] != mouseClickXHistory[l1] || mouseClickYHistory[k1] != mouseClickYHistory[l1]) + break; + if (j1 == l - 1 && flag && combatTimeout == 0 && logoutTimeout == 0) { + sendLogout(); + return; + } + } + + } + } + + } + + void drawTeleportBubble(int x, int y, int w, int h, int id, int tx, int ty) { + int type = teleportBubbleType[id]; + int time = teleportBubbleTime[id]; + if (type == 0) { + int j2 = 255 + time * 5 * 256; + surface.drawCircle(x + w / 2, y + h / 2, 20 + time * 2, j2, 255 - time * 5); + } + if (type == 1) { + int k2 = 0xff0000 + time * 5 * 256; + surface.drawCircle(x + w / 2, y + h / 2, 10 + time, k2, 255 - time * 5); + } + } + + protected void showServerMessage(String s) { + if (s.startsWith("@bor@")) { + showMessage(s, 4); + return; + } + if (s.startsWith("@que@")) { + showMessage("@whi@" + s, 5); + return; + } + if (s.startsWith("@pri@")) { + showMessage(s, 6); + return; + } else { + showMessage(s, 3); + return; + } + } + + private void updateObjectAnimation(int i, String s) { // looks like it just updates objects like torches etc to flip between the different models and appear "animated" + int j = objectX[i]; + int k = objectY[i]; + int l = j - localPlayer.currentX / 128; + int i1 = k - localPlayer.currentY / 128; + byte byte0 = 7; + if (j >= 0 && k >= 0 && j < 96 && k < 96 && l > -byte0 && l < byte0 && i1 > -byte0 && i1 < byte0) { + scene.removeModel(objectModel[i]); + int j1 = GameData.getModelIndex(s); + GameModel gameModel = gameModels[j1].copy(); + scene.addModel(gameModel); + gameModel.setLight(true, 48, 48, -50, -10, -50); + gameModel.copyPosition(objectModel[i]); + gameModel.key = i; + objectModel[i] = gameModel; + } + } + + private void createTopMouseMenu() { + if (selectedSpell >= 0 || selectedItemInventoryIndex >= 0) { + menuItemText1[menuItemsCount] = "Cancel"; + menuItemText2[menuItemsCount] = ""; + menuItemID[menuItemsCount] = 4000; + menuItemsCount++; + } + for (int i = 0; i < menuItemsCount; i++) + menuIndices[i] = i; + + for (boolean flag = false; !flag; ) { + flag = true; + for (int j = 0; j < menuItemsCount - 1; j++) { + int l = menuIndices[j]; + int j1 = menuIndices[j + 1]; + if (menuItemID[l] > menuItemID[j1]) { + menuIndices[j] = j1; + menuIndices[j + 1] = l; + flag = false; + } + } + + } + + if (menuItemsCount > 20) + menuItemsCount = 20; + if (menuItemsCount > 0) { + int k = -1; + for (int i1 = 0; i1 < menuItemsCount; i1++) { + if (menuItemText2[menuIndices[i1]] == null || menuItemText2[menuIndices[i1]].length() <= 0) + continue; + k = i1; + break; + } + + String s = null; + if ((selectedItemInventoryIndex >= 0 || selectedSpell >= 0) && menuItemsCount == 1) + s = "Choose a target"; + else if ((selectedItemInventoryIndex >= 0 || selectedSpell >= 0) && menuItemsCount > 1) + s = "@whi@" + menuItemText1[menuIndices[0]] + " " + menuItemText2[menuIndices[0]]; + else if (k != -1) + s = menuItemText2[menuIndices[k]] + ": @whi@" + menuItemText1[menuIndices[0]]; + if (menuItemsCount == 2 && s != null) + s = s + "@whi@ / 1 more option"; + if (menuItemsCount > 2 && s != null) + s = s + "@whi@ / " + (menuItemsCount - 1) + " more options"; + if (s != null) + surface.drawstring(s, 6, 14, 1, 0xffff00); + if (!optionMouseButtonOne && mouseButtonClick == 1 || optionMouseButtonOne && mouseButtonClick == 1 && menuItemsCount == 1) { + menuItemClick(menuIndices[0]); + mouseButtonClick = 0; + return; + } + if (!optionMouseButtonOne && mouseButtonClick == 2 || optionMouseButtonOne && mouseButtonClick == 1) { + menuHeight = (menuItemsCount + 1) * 15; + menuWidth = surface.textWidth("Choose option", 1) + 5; + for (int k1 = 0; k1 < menuItemsCount; k1++) { + int l1 = surface.textWidth(menuItemText1[k1] + " " + menuItemText2[k1], 1) + 5; + if (l1 > menuWidth) + menuWidth = l1; + } + + menuX = super.mouseX - menuWidth / 2; + menuY = super.mouseY - 7; + showRightClickMenu = true; + if (menuX < 0) + menuX = 0; + if (menuY < 0) + menuY = 0; + if (menuX + menuWidth > 510) + menuX = 510 - menuWidth; + if (menuY + menuHeight > 315) + menuY = 315 - menuHeight; + mouseButtonClick = 0; + } + } + } + + private void drawDialogLogout() { + surface.drawBox(126, 137, 260, 60, 0); + surface.drawBoxEdge(126, 137, 260, 60, 0xffffff); + surface.drawStringCenter("Logging out...", 256, 173, 5, 0xffffff); + } + + private void drawDialogCombatStyle() { + byte byte0 = 7; + byte byte1 = 15; + int width = 175;// '\257'; + if (mouseButtonClick != 0) { + for (int i = 0; i < 5; i++) { + if (i <= 0 || super.mouseX <= byte0 || super.mouseX >= byte0 + width || super.mouseY <= byte1 + i * 20 || super.mouseY >= byte1 + i * 20 + 20) + continue; + combatStyle = i - 1; + mouseButtonClick = 0; + super.clientStream.newPacket((Command.CL_COMBAT_STYLE)); + super.clientStream.putByte(combatStyle); + super.clientStream.sendPacket(); + break; + } + + } + for (int j = 0; j < 5; j++) { + if (j == combatStyle + 1) + surface.drawBoxAlpha(byte0, byte1 + j * 20, width, 20, Surface.rgb2long(255, 0, 0), 128); + else + surface.drawBoxAlpha(byte0, byte1 + j * 20, width, 20, Surface.rgb2long(190, 190, 190), 128); + surface.drawLineHoriz(byte0, byte1 + j * 20, width, 0); + surface.drawLineHoriz(byte0, byte1 + j * 20 + 20, width, 0); + } + + surface.drawStringCenter("Select combat style", byte0 + width / 2, byte1 + 16, 3, 0xffffff); + surface.drawStringCenter("Controlled (+1 of each)", byte0 + width / 2, byte1 + 36, 3, 0); + surface.drawStringCenter("Aggressive (+3 strength)", byte0 + width / 2, byte1 + 56, 3, 0); + surface.drawStringCenter("Accurate (+3 attack)", byte0 + width / 2, byte1 + 76, 3, 0); + surface.drawStringCenter("Defensive (+3 defense)", byte0 + width / 2, byte1 + 96, 3, 0); + } + + private void menuItemClick(int i) { + int mx = menuItemX[i]; + int my = menuItemY[i]; + int midx = menuSourceType[i]; + int msrcidx = menuSourceIndex[i]; + int mtargetindex = menuTargetIndex[i]; + int mitemid = menuItemID[i]; + if (mitemid == 200) { + walkToGroundItem(localRegionX, localRegionY, mx, my, true); + super.clientStream.newPacket((Command.CL_CAST_GROUNDITEM)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 210) { + walkToGroundItem(localRegionX, localRegionY, mx, my, true); + super.clientStream.newPacket((Command.CL_USEWITH_GROUNDITEM)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedItemInventoryIndex = -1; + } + if (mitemid == 220) { + walkToGroundItem(localRegionX, localRegionY, mx, my, true); + super.clientStream.newPacket((Command.CL_GROUNDITEM_TAKE)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + } + if (mitemid == 3200) + showMessage(GameData.itemDescription[midx], 3); + if (mitemid == 300) { + walkToWallObject(mx, my, midx); + super.clientStream.newPacket((Command.CL_CAST_WALLOBJECT)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putByte(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 310) { + walkToWallObject(mx, my, midx); + super.clientStream.newPacket((Command.CL_USEWITH_WALLOBJECT)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putByte(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedItemInventoryIndex = -1; + } + if (mitemid == 320) { + walkToWallObject(mx, my, midx); + super.clientStream.newPacket((Command.CL_WALL_OBJECT_COMMAND1)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putByte(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 2300) { + walkToWallObject(mx, my, midx); + super.clientStream.newPacket((Command.CL_WALL_OBJECT_COMMAND2)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putByte(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 3300) + showMessage(GameData.wallObjectDescription[midx], 3); + if (mitemid == 400) { + walkToObject(mx, my, midx, msrcidx); + super.clientStream.newPacket((Command.CL_CAST_OBJECT)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putShort(mtargetindex); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 410) { + walkToObject(mx, my, midx, msrcidx); + super.clientStream.newPacket((Command.CL_USEWITH_OBJECT)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putShort(mtargetindex); + super.clientStream.sendPacket(); + selectedItemInventoryIndex = -1; + } + if (mitemid == 420) { + walkToObject(mx, my, midx, msrcidx); + super.clientStream.newPacket((Command.CL_OBJECT_CMD1)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.sendPacket(); + } + if (mitemid == 2400) { + walkToObject(mx, my, midx, msrcidx); + super.clientStream.newPacket((Command.CL_OBJECT_CMD2)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.sendPacket(); + } + if (mitemid == 3400) + showMessage(GameData.objectDescription[midx], 3); + if (mitemid == 600) { + super.clientStream.newPacket((Command.CL_CAST_INVITEM)); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 610) { + super.clientStream.newPacket((Command.CL_USEWITH_INVITEM)); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedItemInventoryIndex = -1; + } + if (mitemid == 620) { + super.clientStream.newPacket((Command.CL_INV_UNEQUIP)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 630) { + super.clientStream.newPacket((Command.CL_INV_WEAR)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 640) { + super.clientStream.newPacket((Command.CL_INV_CMD)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 650) { + selectedItemInventoryIndex = midx; + showUiTab = 0; + selectedItemName = GameData.itemName[inventoryItemId[selectedItemInventoryIndex]]; + } + if (mitemid == 660) { + super.clientStream.newPacket((Command.CL_INV_DROP)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + selectedItemInventoryIndex = -1; + showUiTab = 0; + showMessage("Dropping " + GameData.itemName[inventoryItemId[midx]], 4); + } + if (mitemid == 3600) + showMessage(GameData.itemDescription[midx], 3); + if (mitemid == 700) { + int l1 = (mx - 64) / magicLoc; + int l3 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, l1, l3, true); + super.clientStream.newPacket((Command.CL_CAST_NPC)); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 710) { + int i2 = (mx - 64) / magicLoc; + int i4 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, i2, i4, true); + super.clientStream.newPacket((Command.CL_USEWITH_NPC)); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedItemInventoryIndex = -1; + } + if (mitemid == 720) { + int j2 = (mx - 64) / magicLoc; + int j4 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, j2, j4, true); + super.clientStream.newPacket((Command.CL_NPC_TALK)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 725) { + int k2 = (mx - 64) / magicLoc; + int k4 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, k2, k4, true); + super.clientStream.newPacket((Command.CL_NPC_CMD)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 715 || mitemid == 2715) { + int l2 = (mx - 64) / magicLoc; + int l4 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, l2, l4, true); + super.clientStream.newPacket((Command.CL_NPC_ATTACK)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 3700) + showMessage(GameData.npcDescription[midx], 3); + if (mitemid == 800) { + int i3 = (mx - 64) / magicLoc; + int i5 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, i3, i5, true); + super.clientStream.newPacket((Command.CL_CAST_PLAYER)); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 810) { + int j3 = (mx - 64) / magicLoc; + int j5 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, j3, j5, true); + super.clientStream.newPacket((Command.CL_USEWITH_PLAYER)); + super.clientStream.putShort(midx); + super.clientStream.putShort(msrcidx); + super.clientStream.sendPacket(); + selectedItemInventoryIndex = -1; + } + if (mitemid == 805 || mitemid == 2805) { + int k3 = (mx - 64) / magicLoc; + int k5 = (my - 64) / magicLoc; + walkToActionSource(localRegionX, localRegionY, k3, k5, true); + super.clientStream.newPacket((Command.CL_PLAYER_ATTACK)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 2806) { + super.clientStream.newPacket((Command.CL_PLAYER_DUEL)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 2810) { + super.clientStream.newPacket((Command.CL_PLAYER_TRADE)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 2820) { + super.clientStream.newPacket((Command.CL_PLAYER_FOLLOW)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + } + if (mitemid == 900) { + walkToActionSource(localRegionX, localRegionY, mx, my, true); + super.clientStream.newPacket((Command.CL_CAST_GROUND)); + super.clientStream.putShort(mx + regionX); + super.clientStream.putShort(my + regionY); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 920) { + walkToActionSource(localRegionX, localRegionY, mx, my, false); + if (mouseClickXStep == -24) + mouseClickXStep = 24; + } + if (mitemid == 1000) { + super.clientStream.newPacket((Command.CL_CAST_SELF)); + super.clientStream.putShort(midx); + super.clientStream.sendPacket(); + selectedSpell = -1; + } + if (mitemid == 4000) { + selectedItemInventoryIndex = -1; + selectedSpell = -1; + } + } + + protected void showLoginScreenStatus(String s, String s1) { + if (loginScreen == 1) + panelLoginNewuser.updateText(anInt827, s + " " + s1); + if (loginScreen == 2) + panelLoginExistinguser.updateText(controlLoginStatus, s + " " + s1); + loginUserDisp = s1; + drawLoginScreens(); + resetTimings(); + } + + protected void lostConnection() { + systemUpdate = 0; + if (logoutTimeout != 0) { + resetLoginVars(); + return; + } else { + super.lostConnection(); + return; + } + } + + private boolean isValidCameraAngle(int i) { + int j = localPlayer.currentX / 128; + int k = localPlayer.currentY / 128; + for (int l = 2; l >= 1; l--) { + if (i == 1 && ((world.objectAdjacency[j][k - l] & 128) == 128 || (world.objectAdjacency[j - l][k] & 128) == 128 || (world.objectAdjacency[j - l][k - l] & 128) == 128))// 0x80 + return false; + if (i == 3 && ((world.objectAdjacency[j][k + l] & 128) == 128 || (world.objectAdjacency[j - l][k] & 128) == 128 || (world.objectAdjacency[j - l][k + l] & 128) == 128))// 0x80 + return false; + if (i == 5 && ((world.objectAdjacency[j][k + l] & 128) == 128 || (world.objectAdjacency[j + l][k] & 128) == 128 || (world.objectAdjacency[j + l][k + l] & 128) == 128))// 0x80 + return false; + if (i == 7 && ((world.objectAdjacency[j][k - l] & 128) == 128 || (world.objectAdjacency[j + l][k] & 128) == 128 || (world.objectAdjacency[j + l][k - l] & 128) == 128))// 0x80 + return false; + if (i == 0 && (world.objectAdjacency[j][k - l] & 128) == 128)// 0x80 + return false; + if (i == 2 && (world.objectAdjacency[j - l][k] & 128) == 128)// 0x80 + return false; + if (i == 4 && (world.objectAdjacency[j][k + l] & 128) == 128)// 0x80 + return false; + if (i == 6 && (world.objectAdjacency[j + l][k] & 128) == 128)// 0x80 + return false; + } + + return true; + } + + private void resetLoginScreenVariables() { + loggedIn = 0; + loginScreen = 0; + loginUser = ""; + loginPass = ""; + loginUserDesc = "Please enter a username:"; + loginUserDisp = "*" + loginUser + "*"; + playerCount = 0; + npcCount = 0; + } + + byte[] integersToBytes(int[] values) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + + for(int i = 0; i < values.length; i++) { + dos.writeInt(values[i]); + } + + return baos.toByteArray(); + } + + public void dumpPixels() { + for (int i = 0; i < 25; i += 1) { + System.out.println(this.surface.pixels[i]); + } + + try { + byte[] pixelBytes = integersToBytes(this.surface.pixels); + FileOutputStream writer = new FileOutputStream("./pixels.bytes"); + writer.write(pixelBytes); + + /*for (int i = 0; i < pixelBytes.length; i++) { + writer.write(pixelBytes[i]); + }*/ + } catch (IOException e) { + System.err.println(e); + System.exit(1); + } + } + + protected void handleIncomingPacket(int opcode, int ptype, int psize, byte pdata[]) { + try { + if (opcode == Command.SV_REGION_PLAYERS) { + knownPlayerCount = playerCount; + for (int k = 0; k < knownPlayerCount; k++) + knownPlayers[k] = players[k]; + + int k7 = 8; + localRegionX = Utility.getBitMask(pdata, k7, 11); + k7 += 11; + localRegionY = Utility.getBitMask(pdata, k7, 13); + k7 += 13; + int anim = Utility.getBitMask(pdata, k7, 4); + k7 += 4; + boolean flag1 = loadNextRegion(localRegionX, localRegionY); + localRegionX -= regionX; + localRegionY -= regionY; + int l22 = localRegionX * magicLoc + 64; + int l25 = localRegionY * magicLoc + 64; + if (flag1) { + localPlayer.waypointCurrent = 0; + localPlayer.movingStep = 0; + localPlayer.currentX = localPlayer.waypointsX[0] = l22; + localPlayer.currentY = localPlayer.waypointsY[0] = l25; + } + playerCount = 0; + localPlayer = createPlayer(localPlayerServerIndex, l22, l25, anim); + int i29 = Utility.getBitMask(pdata, k7, 8); + k7 += 8; + for (int l33 = 0; l33 < i29; l33++) { + GameCharacter character_3 = knownPlayers[l33 + 1]; + int reqUpdate = Utility.getBitMask(pdata, k7, 1); + k7++; + if (reqUpdate != 0) { + int updateType = Utility.getBitMask(pdata, k7, 1); + k7++; + if (updateType == 0) { + int nextAnim = Utility.getBitMask(pdata, k7, 3); + k7 += 3; + int l43 = character_3.waypointCurrent; + int j44 = character_3.waypointsX[l43]; + int k44 = character_3.waypointsY[l43]; + if (nextAnim == 2 || nextAnim == 1 || nextAnim == 3) + j44 += magicLoc; + if (nextAnim == 6 || nextAnim == 5 || nextAnim == 7) + j44 -= magicLoc; + if (nextAnim == 4 || nextAnim == 3 || nextAnim == 5) + k44 += magicLoc; + if (nextAnim == 0 || nextAnim == 1 || nextAnim == 7) + k44 -= magicLoc; + character_3.animationNext = nextAnim; + character_3.waypointCurrent = l43 = (l43 + 1) % 10; + character_3.waypointsX[l43] = j44; + character_3.waypointsY[l43] = k44; + } else { + int i43 = Utility.getBitMask(pdata, k7, 4); + if ((i43 & 12) == 12) {// 0xc + k7 += 2; + continue; + } + character_3.animationNext = Utility.getBitMask(pdata, k7, 4); + k7 += 4; + } + } + players[playerCount++] = character_3; + } + + int count = 0; + while (k7 + 24 < psize * 8) { + int serverIndex = Utility.getBitMask(pdata, k7, 11); + k7 += 11; + int areaX = Utility.getBitMask(pdata, k7, 5); + k7 += 5; + if (areaX > 15) + areaX -= 32; + int areaY = Utility.getBitMask(pdata, k7, 5); + k7 += 5; + if (areaY > 15) + areaY -= 32; + int animation = Utility.getBitMask(pdata, k7, 4); + k7 += 4; + int i44 = Utility.getBitMask(pdata, k7, 1); + k7++; + int x = (localRegionX + areaX) * magicLoc + 64; + int y = (localRegionY + areaY) * magicLoc + 64; + createPlayer(serverIndex, x, y, animation); + if (i44 == 0) + playerServerIndexes[count++] = serverIndex; + } + if (count > 0) { + super.clientStream.newPacket((Command.CL_KNOWN_PLAYERS)); + super.clientStream.putShort(count); + for (int i = 0; i < count; i++) { + GameCharacter c = playerServer[playerServerIndexes[i]]; + super.clientStream.putShort(c.serverIndex); + super.clientStream.putShort(c.serverId); + } + + super.clientStream.sendPacket(); + count = 0; + } + return; + } + if (opcode == Command.SV_REGION_GROUND_ITEMS) { + //dumpPixels(); + //System.exit(0); + + for (int l = 1; l < psize; ) + if (Utility.getUnsignedByte(pdata[l]) == 255) { + int l7 = 0; + int j14 = localRegionX + pdata[l + 1] >> 3; + int i19 = localRegionY + pdata[l + 2] >> 3; + l += 3; + for (int j23 = 0; j23 < groundItemCount; j23++) { + int j26 = (groundItemX[j23] >> 3) - j14; + int j29 = (groundItemY[j23] >> 3) - i19; + if (j26 != 0 || j29 != 0) { + if (j23 != l7) { + groundItemX[l7] = groundItemX[j23]; + groundItemY[l7] = groundItemY[j23]; + groundItemId[l7] = groundItemId[j23]; + groundItemZ[l7] = groundItemZ[j23]; + } + l7++; + } + } + + groundItemCount = l7; + } else { + int i8 = Utility.getUnsignedShort(pdata, l); + l += 2; + int k14 = localRegionX + pdata[l++]; + int j19 = localRegionY + pdata[l++]; + if ((i8 & 32768) == 0) {// 0x8000 + groundItemX[groundItemCount] = k14; + groundItemY[groundItemCount] = j19; + groundItemId[groundItemCount] = i8; + groundItemZ[groundItemCount] = 0; + for (int k23 = 0; k23 < objectCount; k23++) { + if (objectX[k23] != k14 || objectY[k23] != j19) + continue; + groundItemZ[groundItemCount] = GameData.objectElevation[objectId[k23]]; + break; + } + + groundItemCount++; + } else { + i8 &= 32767;// 0x7fff + int l23 = 0; + for (int k26 = 0; k26 < groundItemCount; k26++) + if (groundItemX[k26] != k14 || groundItemY[k26] != j19 || groundItemId[k26] != i8) { + if (k26 != l23) { + groundItemX[l23] = groundItemX[k26]; + groundItemY[l23] = groundItemY[k26]; + groundItemId[l23] = groundItemId[k26]; + groundItemZ[l23] = groundItemZ[k26]; + } + l23++; + } else { + i8 = -123; + } + + groundItemCount = l23; + } + } + + return; + } + if (opcode == Command.SV_REGION_OBJECTS) { + for (int i1 = 1; i1 < psize; ) + if (Utility.getUnsignedByte(pdata[i1]) == 255) { + int j8 = 0; + int l14 = localRegionX + pdata[i1 + 1] >> 3; + int k19 = localRegionY + pdata[i1 + 2] >> 3; + i1 += 3; + for (int i24 = 0; i24 < objectCount; i24++) { + int l26 = (objectX[i24] >> 3) - l14; + int k29 = (objectY[i24] >> 3) - k19; + if (l26 != 0 || k29 != 0) { + if (i24 != j8) { + objectModel[j8] = objectModel[i24]; + objectModel[j8].key = j8; + objectX[j8] = objectX[i24]; + objectY[j8] = objectY[i24]; + objectId[j8] = objectId[i24]; + objectDirection[j8] = objectDirection[i24]; + } + j8++; + } else { + scene.removeModel(objectModel[i24]); + world.removeObject(objectX[i24], objectY[i24], objectId[i24]); + } + } + + objectCount = j8; + } else { + int id = Utility.getUnsignedShort(pdata, i1); + i1 += 2; + int lX = localRegionX + pdata[i1++]; + int lY = localRegionY + pdata[i1++]; + int j24 = 0; + for (int i27 = 0; i27 < objectCount; i27++) + if (objectX[i27] != lX || objectY[i27] != lY) { + if (i27 != j24) { + objectModel[j24] = objectModel[i27]; + objectModel[j24].key = j24; + objectX[j24] = objectX[i27]; + objectY[j24] = objectY[i27]; + objectId[j24] = objectId[i27]; + objectDirection[j24] = objectDirection[i27]; + } + j24++; + } else { + scene.removeModel(objectModel[i27]); + world.removeObject(objectX[i27], objectY[i27], objectId[i27]); + } + + objectCount = j24; + if (id != 60000) { + int direction = world.getTileDirection(lX, lY); + int width; + int height; + if (direction == 0 || direction == 4) { + width = GameData.objectWidth[id]; + height = GameData.objectHeight[id]; + } else { + height = GameData.objectWidth[id]; + width = GameData.objectHeight[id]; + } + int mX = ((lX + lX + width) * magicLoc) / 2; + int mY = ((lY + lY + height) * magicLoc) / 2; + int modelIdx = GameData.objectModelIndex[id]; + GameModel model = gameModels[modelIdx].copy(); + scene.addModel(model); + model.key = objectCount; + model.rotate(0, direction * 32, 0); + model.translate(mX, -world.getElevation(mX, mY), mY); + model.setLight(true, 48, 48, -50, -10, -50); + world.removeObject2(lX, lY, id); + if (id == 74) + model.translate(0, -480, 0); + objectX[objectCount] = lX; + objectY[objectCount] = lY; + objectId[objectCount] = id; + objectDirection[objectCount] = direction; + objectModel[objectCount++] = model; + } + } + + return; + } + if (opcode == Command.SV_INVENTORY_ITEMS) { + int offset = 1; + inventoryItemsCount = pdata[offset++] & 0xff; + for (int i = 0; i < inventoryItemsCount; i++) { + int idequip = Utility.getUnsignedShort(pdata, offset); + offset += 2; + inventoryItemId[i] = idequip & 32767;// 0x7fff + inventoryEquipped[i] = idequip / 32768; + if (GameData.itemStackable[idequip & 32767] == 0) {// 0x7fff + inventoryItemStackCount[i] = Utility.getUnsignedInt2(pdata, offset); + if (inventoryItemStackCount[i] >= 128) + offset += 4; + else + offset++; + } else { + inventoryItemStackCount[i] = 1; + } + } + + return; + } + if (opcode == Command.SV_REGION_PLAYER_UPDATE) { + int k1 = Utility.getUnsignedShort(pdata, 1); + int offset = 3; + for (int k15 = 0; k15 < k1; k15++) { + int playerId = Utility.getUnsignedShort(pdata, offset); + offset += 2; + GameCharacter character = playerServer[playerId]; + byte updateType = pdata[offset]; + offset++; + if (updateType == 0) { // speech bubble with an item in it + int id = Utility.getUnsignedShort(pdata, offset); + offset += 2; + if (character != null) { + character.bubbleTimeout = 150; + character.bubbleItem = id; + } + } else if (updateType == 1) { // chat + byte messageLength = pdata[offset]; + offset++; + if (character != null) { + String filtered = WordFilter.filter(ChatMessage.descramble(pdata, offset, messageLength)); + boolean ignored = false; + for (int i = 0; i < super.ignoreListCount; i++) + if (super.ignoreList[i] == character.hash) { + ignored = true; + break; + } + + if (!ignored) { + character.messageTimeout = 150; + character.message = filtered; + showMessage(character.name + ": " + character.message, 2); + } + } + offset += messageLength; + } else if (updateType == 2) { // combat damage and hp + int damage = Utility.getUnsignedByte(pdata[offset]); + offset++; + int current = Utility.getUnsignedByte(pdata[offset]); + offset++; + int max = Utility.getUnsignedByte(pdata[offset]); + offset++; + if (character != null) { + character.damageTaken = damage; + character.healthCurrent = current; + character.healthMax = max; + character.combatTimer = 200; + if (character == localPlayer) { + playerStatCurrent[3] = current; + playerStatBase[3] = max; + showDialogWelcome = false; + showDialogServermessage = false; + } + } + } else if (updateType == 3) { // new incoming projectile from npc? + int projectileSprite = Utility.getUnsignedShort(pdata, offset); + offset += 2; + int npcIdx = Utility.getUnsignedShort(pdata, offset); + offset += 2; + if (character != null) { + character.incomingProjectileSprite = projectileSprite; + character.attackingNpcServerIndex = npcIdx; + character.attackingPlayerServerIndex = -1; + character.projectileRange = projectileMaxRange; + } + } else if (updateType == 4) { // new incoming projectile from player + int projectileSprite = Utility.getUnsignedShort(pdata, offset); + offset += 2; + int playerIdx = Utility.getUnsignedShort(pdata, offset); + offset += 2; + if (character != null) { + character.incomingProjectileSprite = projectileSprite; + character.attackingPlayerServerIndex = playerIdx; + character.attackingNpcServerIndex = -1; + character.projectileRange = projectileMaxRange; + } + } else if (updateType == 5) { + if (character != null) { + character.serverId = Utility.getUnsignedShort(pdata, offset); + offset += 2; + character.hash = Utility.getUnsignedLong(pdata, offset); + offset += 8; + character.name = Utility.hash2username(character.hash); + int equippedCount = Utility.getUnsignedByte(pdata[offset]); + offset++; + for (int i = 0; i < equippedCount; i++) { + character.equippedItem[i] = Utility.getUnsignedByte(pdata[offset]); + offset++; + } + + for (int i = equippedCount; i < 12; i++) + character.equippedItem[i] = 0; + + character.colourHair = pdata[offset++] & 0xff; + character.colourTop = pdata[offset++] & 0xff; + character.colourBottom = pdata[offset++] & 0xff; + character.colourSkin = pdata[offset++] & 0xff; + character.level = pdata[offset++] & 0xff; + character.skullVisible = pdata[offset++] & 0xff; + } else { + offset += 14; + int unused = Utility.getUnsignedByte(pdata[offset]); + offset += unused + 1; + } + } else if (updateType == 6) { + byte mLen = pdata[offset]; + offset++; + if (character != null) { + String msg = ChatMessage.descramble(pdata, offset, mLen); + character.messageTimeout = 150; + character.message = msg; + if (character == localPlayer) + showMessage(character.name + ": " + character.message, 5); + } + offset += mLen; + } + } + + return; + } + if (opcode == Command.SV_REGION_WALL_OBJECTS) { + for (int offset = 1; offset < psize; ) + if (Utility.getUnsignedByte(pdata[offset]) == 255) { + int count = 0; + int lX = localRegionX + pdata[offset + 1] >> 3; + int lY = localRegionY + pdata[offset + 2] >> 3; + offset += 3; + for (int i = 0; i < wallObjectCount; i++) { + int sX = (wallObjectX[i] >> 3) - lX; + int sY = (wallObjectY[i] >> 3) - lY; + if (sX != 0 || sY != 0) { + if (i != count) { + wallObjectModel[count] = wallObjectModel[i]; + wallObjectModel[count].key = count + 10000; + wallObjectX[count] = wallObjectX[i]; + wallObjectY[count] = wallObjectY[i]; + wallObjectDirection[count] = wallObjectDirection[i]; + wallObjectId[count] = wallObjectId[i]; + } + count++; + } else { + scene.removeModel(wallObjectModel[i]); + world.removeWallObject(wallObjectX[i], wallObjectY[i], wallObjectDirection[i], wallObjectId[i]); + } + } + + wallObjectCount = count; + } else { + int id = Utility.getUnsignedShort(pdata, offset); + offset += 2; + int lX = localRegionX + pdata[offset++]; + int lY = localRegionY + pdata[offset++]; + byte direction = pdata[offset++]; + int count = 0; + for (int i = 0; i < wallObjectCount; i++) + if (wallObjectX[i] != lX || wallObjectY[i] != lY || wallObjectDirection[i] != direction) { + if (i != count) { + wallObjectModel[count] = wallObjectModel[i]; + wallObjectModel[count].key = count + 10000; + wallObjectX[count] = wallObjectX[i]; + wallObjectY[count] = wallObjectY[i]; + wallObjectDirection[count] = wallObjectDirection[i]; + wallObjectId[count] = wallObjectId[i]; + } + count++; + } else { + scene.removeModel(wallObjectModel[i]); + world.removeWallObject(wallObjectX[i], wallObjectY[i], wallObjectDirection[i], wallObjectId[i]); + } + + wallObjectCount = count; + if (id != 65535) { + world.setObjectAdjacency(lX, lY, direction, id); + GameModel model = createModel(lX, lY, direction, id, wallObjectCount); + wallObjectModel[wallObjectCount] = model; + wallObjectX[wallObjectCount] = lX; + wallObjectY[wallObjectCount] = lY; + wallObjectId[wallObjectCount] = id; + wallObjectDirection[wallObjectCount++] = direction; + } + } + + return; + } + if (opcode == Command.SV_REGION_NPCS) { + npcCacheCount = npcCount; + npcCount = 0; + for (int i2 = 0; i2 < npcCacheCount; i2++) + npcsCache[i2] = npcs[i2]; + + int offset = 8; + int j16 = Utility.getBitMask(pdata, offset, 8); + offset += 8; + for (int l20 = 0; l20 < j16; l20++) { + GameCharacter character_1 = npcsCache[l20]; + int l27 = Utility.getBitMask(pdata, offset, 1); + offset++; + if (l27 != 0) { + int i32 = Utility.getBitMask(pdata, offset, 1); + offset++; + if (i32 == 0) { + int j35 = Utility.getBitMask(pdata, offset, 3); + offset += 3; + int i38 = character_1.waypointCurrent; + int l40 = character_1.waypointsX[i38]; + int j42 = character_1.waypointsY[i38]; + if (j35 == 2 || j35 == 1 || j35 == 3) + l40 += magicLoc; + if (j35 == 6 || j35 == 5 || j35 == 7) + l40 -= magicLoc; + if (j35 == 4 || j35 == 3 || j35 == 5) + j42 += magicLoc; + if (j35 == 0 || j35 == 1 || j35 == 7) + j42 -= magicLoc; + character_1.animationNext = j35; + character_1.waypointCurrent = i38 = (i38 + 1) % 10; + character_1.waypointsX[i38] = l40; + character_1.waypointsY[i38] = j42; + } else { + int k35 = Utility.getBitMask(pdata, offset, 4); + if ((k35 & 12) == 12) {// 0xc + offset += 2; + continue; + } + character_1.animationNext = Utility.getBitMask(pdata, offset, 4); + offset += 4; + } + } + npcs[npcCount++] = character_1; + } + + while (offset + 34 < psize * 8) { + int serverIndex = Utility.getBitMask(pdata, offset, 12); + offset += 12; + int areaX = Utility.getBitMask(pdata, offset, 5); + offset += 5; + if (areaX > 15) + areaX -= 32; + int areaY = Utility.getBitMask(pdata, offset, 5); + offset += 5; + if (areaY > 15) + areaY -= 32; + int sprite = Utility.getBitMask(pdata, offset, 4); + offset += 4; + int x = (localRegionX + areaX) * magicLoc + 64; + int y = (localRegionY + areaY) * magicLoc + 64; + int type = Utility.getBitMask(pdata, offset, 10); + offset += 10; + if (type >= GameData.npcCount) + type = 24; + addNpc(serverIndex, x, y, sprite, type); + } + return; + } + if (opcode == Command.SV_REGION_NPC_UPDATE) { + int j2 = Utility.getUnsignedShort(pdata, 1); + int i10 = 3; + for (int k16 = 0; k16 < j2; k16++) { + int i21 = Utility.getUnsignedShort(pdata, i10); + i10 += 2; + GameCharacter character = npcsServer[i21]; + int j28 = Utility.getUnsignedByte(pdata[i10]); + i10++; + if (j28 == 1) { + int target = Utility.getUnsignedShort(pdata, i10); + i10 += 2; + byte byte9 = pdata[i10]; + i10++; + if (character != null) { + String s4 = ChatMessage.descramble(pdata, i10, byte9); + character.messageTimeout = 150; + character.message = s4; + if (target == localPlayer.serverIndex) + showMessage("@yel@" + GameData.npcName[character.npcId] + ": " + character.message, 5); + } + i10 += byte9; + } else if (j28 == 2) { + int l32 = Utility.getUnsignedByte(pdata[i10]); + i10++; + int i36 = Utility.getUnsignedByte(pdata[i10]); + i10++; + int k38 = Utility.getUnsignedByte(pdata[i10]); + i10++; + if (character != null) { + character.damageTaken = l32; + character.healthCurrent = i36; + character.healthMax = k38; + character.combatTimer = 200; + } + } + } + + return; + } + if (opcode == Command.SV_OPTION_LIST) { + showOptionMenu = true; + int count = Utility.getUnsignedByte(pdata[1]); + optionMenuCount = count; + int offset = 2; + for (int i = 0; i < count; i++) { + int length = Utility.getUnsignedByte(pdata[offset]); + offset++; + optionMenuEntry[i] = new String(pdata, offset, length); + offset += length; + } + + return; + } + if (opcode == Command.SV_OPTION_LIST_CLOSE) { + showOptionMenu = false; + return; + } + if (opcode == Command.SV_WORLD_INFO) { + loadingArea = true; + localPlayerServerIndex = Utility.getUnsignedShort(pdata, 1); + planeWidth = Utility.getUnsignedShort(pdata, 3); + planeHeight = Utility.getUnsignedShort(pdata, 5); + planeIndex = Utility.getUnsignedShort(pdata, 7); + planeMultiplier = Utility.getUnsignedShort(pdata, 9); + planeHeight -= planeIndex * planeMultiplier; + return; + } + if (opcode == Command.SV_PLAYER_STAT_LIST) { + int offset = 1; + for (int i = 0; i < playerStatCount; i++) + playerStatCurrent[i] = Utility.getUnsignedByte(pdata[offset++]); + + for (int i = 0; i < playerStatCount; i++) + playerStatBase[i] = Utility.getUnsignedByte(pdata[offset++]); + + for (int i = 0; i < playerStatCount; i++) { + playerExperience[i] = Utility.getUnsignedInt(pdata, offset); + offset += 4; + } + + playerQuestPoints = Utility.getUnsignedByte(pdata[offset++]); + return; + } + if (opcode == Command.SV_PLAYER_STAT_EQUIPMENT_BONUS) { + for (int i3 = 0; i3 < playerStatEquipmentCount; i3++) + playerStatEquipment[i3] = Utility.getUnsignedByte(pdata[1 + i3]); + + return; + } + if (opcode == Command.SV_PLAYER_DIED) { + deathScreenTimeout = 250; + return; + } + if (opcode == Command.SV_REGION_ENTITY_UPDATE) { + int j3 = (psize - 1) / 4; + for (int l10 = 0; l10 < j3; l10++) { + int j17 = localRegionX + Utility.getSignedShort(pdata, 1 + l10 * 4) >> 3; + int l21 = localRegionY + Utility.getSignedShort(pdata, 3 + l10 * 4) >> 3; + int i25 = 0; + for (int k28 = 0; k28 < groundItemCount; k28++) { + int i33 = (groundItemX[k28] >> 3) - j17; + int j36 = (groundItemY[k28] >> 3) - l21; + if (i33 != 0 || j36 != 0) { + if (k28 != i25) { + groundItemX[i25] = groundItemX[k28]; + groundItemY[i25] = groundItemY[k28]; + groundItemId[i25] = groundItemId[k28]; + groundItemZ[i25] = groundItemZ[k28]; + } + i25++; + } + } + + groundItemCount = i25; + i25 = 0; + for (int j33 = 0; j33 < objectCount; j33++) { + int k36 = (objectX[j33] >> 3) - j17; + int l38 = (objectY[j33] >> 3) - l21; + if (k36 != 0 || l38 != 0) { + if (j33 != i25) { + objectModel[i25] = objectModel[j33]; + objectModel[i25].key = i25; + objectX[i25] = objectX[j33]; + objectY[i25] = objectY[j33]; + objectId[i25] = objectId[j33]; + objectDirection[i25] = objectDirection[j33]; + } + i25++; + } else { + scene.removeModel(objectModel[j33]); + world.removeObject(objectX[j33], objectY[j33], objectId[j33]); + } + } + + objectCount = i25; + i25 = 0; + for (int l36 = 0; l36 < wallObjectCount; l36++) { + int i39 = (wallObjectX[l36] >> 3) - j17; + int j41 = (wallObjectY[l36] >> 3) - l21; + if (i39 != 0 || j41 != 0) { + if (l36 != i25) { + wallObjectModel[i25] = wallObjectModel[l36]; + wallObjectModel[i25].key = i25 + 10000; + wallObjectX[i25] = wallObjectX[l36]; + wallObjectY[i25] = wallObjectY[l36]; + wallObjectDirection[i25] = wallObjectDirection[l36]; + wallObjectId[i25] = wallObjectId[l36]; + } + i25++; + } else { + scene.removeModel(wallObjectModel[l36]); + world.removeWallObject(wallObjectX[l36], wallObjectY[l36], wallObjectDirection[l36], wallObjectId[l36]); + } + } + + wallObjectCount = i25; + } + + return; + } + if (opcode == Command.SV_APPEARANCE) { + showAppearanceChange = true; + return; + } + if (opcode == Command.SV_TRADE_OPEN) { + int k3 = Utility.getUnsignedShort(pdata, 1); + if (playerServer[k3] != null) + tradeRecipientName = playerServer[k3].name; + showDialogTrade = true; + tradeRecipientAccepted = false; + tradeAccepted = false; + tradeItemsCount = 0; + tradeRecipientItemsCount = 0; + return; + } + if (opcode == Command.SV_TRADE_CLOSE) { + showDialogTrade = false; + showDialogTradeConfirm = false; + return; + } + if (opcode == Command.SV_TRADE_ITEMS) { + tradeRecipientItemsCount = pdata[1] & 0xff; + int l3 = 2; + for (int i11 = 0; i11 < tradeRecipientItemsCount; i11++) { + tradeRecipientItems[i11] = Utility.getUnsignedShort(pdata, l3); + l3 += 2; + tradeRecipientItemCount[i11] = Utility.getUnsignedInt(pdata, l3); + l3 += 4; + } + + tradeRecipientAccepted = false; + tradeAccepted = false; + return; + } + if (opcode == Command.SV_TRADE_RECIPIENT_STATUS) { + byte byte0 = pdata[1]; + if (byte0 == 1) { + tradeRecipientAccepted = true; + return; + } else { + tradeRecipientAccepted = false; + return; + } + } + if (opcode == Command.SV_SHOP_OPEN) { + showDialogShop = true; + int off = 1; + int newItemCount = pdata[off++] & 0xff; + byte shopType = pdata[off++]; + shopSellPriceMod = pdata[off++] & 0xff; + shopBuyPriceMod = pdata[off++] & 0xff; + for (int itemIndex = 0; itemIndex < 40; itemIndex++) + shopItem[itemIndex] = -1; + + for (int itemIndex = 0; itemIndex < newItemCount; itemIndex++) { + shopItem[itemIndex] = Utility.getUnsignedShort(pdata, off); + off += 2; + shopItemCount[itemIndex] = Utility.getUnsignedShort(pdata, off); + off += 2; + shopItemPrice[itemIndex] = pdata[off++]; + } + + if (shopType == 1) {// shopType == 1 -> is a general shop + int l28 = 39; + for (int k33 = 0; k33 < inventoryItemsCount; k33++) { + if (l28 < newItemCount) + break; + boolean flag2 = false; + for (int j39 = 0; j39 < 40; j39++) { + if (shopItem[j39] != inventoryItemId[k33]) + continue; + flag2 = true; + break; + } + + if (inventoryItemId[k33] == 10) + flag2 = true; + if (!flag2) { + shopItem[l28] = inventoryItemId[k33] & 32767;// 0x7fff + shopItemCount[l28] = 0; + shopItemPrice[l28] = 0; + l28--; + } + } + + } + if (shopSelectedItemIndex >= 0 && shopSelectedItemIndex < 40 && shopItem[shopSelectedItemIndex] != shopSelectedItemType) { + shopSelectedItemIndex = -1; + shopSelectedItemType = -2; + } + return; + } + if (opcode == Command.SV_SHOP_CLOSE) { + showDialogShop = false; + return; + } + if (opcode == Command.SV_TRADE_STATUS) { + byte byte1 = pdata[1]; + if (byte1 == 1) { + tradeAccepted = true; + return; + } else { + tradeAccepted = false; + return; + } + } + if (opcode == Command.SV_GAME_SETTINGS) { + optionCameraModeAuto = Utility.getUnsignedByte(pdata[1]) == 1; + optionMouseButtonOne = Utility.getUnsignedByte(pdata[2]) == 1; + optionSoundDisabled = Utility.getUnsignedByte(pdata[3]) == 1; + return; + } + if (opcode == Command.SV_PRAYER_STATUS) { + for (int j4 = 0; j4 < psize - 1; j4++) { + boolean on = pdata[j4 + 1] == 1; + if (!prayerOn[j4] && on) + playSoundFile("prayeron"); + if (prayerOn[j4] && !on) + playSoundFile("prayeroff"); + prayerOn[j4] = on; + } + + return; + } + if (opcode == Command.SV_PLAYER_QUEST_LIST) { + for (int k4 = 0; k4 < questCount; k4++) + questComplete[k4] = pdata[k4 + 1] == 1; + + return; + } + if (opcode == Command.SV_BANK_OPEN) { + showDialogBank = true; + int l4 = 1; + newBankItemCount = pdata[l4++] & 0xff; + bankItemsMax = pdata[l4++] & 0xff; + for (int k11 = 0; k11 < newBankItemCount; k11++) { + newBankItems[k11] = Utility.getUnsignedShort(pdata, l4); + l4 += 2; + newBankItemsCount[k11] = Utility.getUnsignedInt2(pdata, l4); + if (newBankItemsCount[k11] >= 128) + l4 += 4; + else + l4++; + } + + updateBankItems(); + return; + } + if (opcode == Command.SV_BANK_CLOSE) { + showDialogBank = false; + return; + } + if (opcode == Command.SV_PLAYER_STAT_EXPERIENCE_UPDATE) { + int i5 = pdata[1] & 0xff; + playerExperience[i5] = Utility.getUnsignedInt(pdata, 2); + return; + } + if (opcode == Command.SV_DUEL_OPEN) { + int j5 = Utility.getUnsignedShort(pdata, 1); + if (playerServer[j5] != null) + duelOpponentName = playerServer[j5].name; + showDialogDuel = true; + duelOfferItemCount = 0; + duelOfferOpponentItemCount = 0; + duelOfferOpponentAccepted = false; + duelOfferAccepted = false; + duelSettingsRetreat = false; + duelSettingsMagic = false; + duelSettingsPrayer = false; + duelSettingsWeapons = false; + return; + } + if (opcode == Command.SV_DUEL_CLOSE) { + showDialogDuel = false; + showDialogDuelConfirm = false; + return; + } + if (opcode == Command.SV_TRADE_CONFIRM_OPEN) { + showDialogTradeConfirm = true; + tradeConfirmAccepted = false; + showDialogTrade = false; + int k5 = 1; + tradeRecipientConfirmHash = Utility.getUnsignedLong(pdata, k5); + k5 += 8; + tradeRecipientConfirmItemsCount = pdata[k5++] & 0xff; + for (int l11 = 0; l11 < tradeRecipientConfirmItemsCount; l11++) { + tradeRecipientConfirmItems[l11] = Utility.getUnsignedShort(pdata, k5); + k5 += 2; + tradeRecipientConfirmItemCount[l11] = Utility.getUnsignedInt(pdata, k5); + k5 += 4; + } + + tradeConfirmItemsCount = pdata[k5++] & 0xff; + for (int k17 = 0; k17 < tradeConfirmItemsCount; k17++) { + tradeConfirmItems[k17] = Utility.getUnsignedShort(pdata, k5); + k5 += 2; + tradeConfirmItemCount[k17] = Utility.getUnsignedInt(pdata, k5); + k5 += 4; + } + + return; + } + if (opcode == Command.SV_DUEL_UPDATE) { + duelOfferOpponentItemCount = pdata[1] & 0xff; + int l5 = 2; + for (int i12 = 0; i12 < duelOfferOpponentItemCount; i12++) { + duelOfferOpponentItemId[i12] = Utility.getUnsignedShort(pdata, l5); + l5 += 2; + duelOfferOpponentItemStack[i12] = Utility.getUnsignedInt(pdata, l5); + l5 += 4; + } + + duelOfferOpponentAccepted = false; + duelOfferAccepted = false; + return; + } + if (opcode == Command.SV_DUEL_SETTINGS) { + if (pdata[1] == 1) + duelSettingsRetreat = true; + else + duelSettingsRetreat = false; + if (pdata[2] == 1) + duelSettingsMagic = true; + else + duelSettingsMagic = false; + if (pdata[3] == 1) + duelSettingsPrayer = true; + else + duelSettingsPrayer = false; + if (pdata[4] == 1) + duelSettingsWeapons = true; + else + duelSettingsWeapons = false; + duelOfferOpponentAccepted = false; + duelOfferAccepted = false; + return; + } + if (opcode == Command.SV_BANK_UPDATE) { + int i6 = 1; + int itemsCountOld = pdata[i6++] & 0xff; + int item = Utility.getUnsignedShort(pdata, i6); + i6 += 2; + int itemCount = Utility.getUnsignedInt2(pdata, i6); + if (itemCount >= 128) + i6 += 4; + else + i6++; + if (itemCount == 0) { + newBankItemCount--; + for (int k25 = itemsCountOld; k25 < newBankItemCount; k25++) { + newBankItems[k25] = newBankItems[k25 + 1]; + newBankItemsCount[k25] = newBankItemsCount[k25 + 1]; + } + + } else { + newBankItems[itemsCountOld] = item; + newBankItemsCount[itemsCountOld] = itemCount; + if (itemsCountOld >= newBankItemCount) + newBankItemCount = itemsCountOld + 1; + } + updateBankItems(); + return; + } + if (opcode == Command.SV_INVENTORY_ITEM_UPDATE) { + int offset = 1; + int stack = 1; + int index = pdata[offset++] & 0xff; + int id = Utility.getUnsignedShort(pdata, offset); + offset += 2; + if (GameData.itemStackable[id & 32767] == 0) {// 0x7fff + stack = Utility.getUnsignedInt2(pdata, offset); + if (stack >= 128) + offset += 4; + else + offset++; + } + inventoryItemId[index] = id & 32767;// 0x7fff + inventoryEquipped[index] = id / 32768; + inventoryItemStackCount[index] = stack; + if (index >= inventoryItemsCount) + inventoryItemsCount = index + 1; + return; + } + if (opcode == Command.SV_INVENTORY_ITEM_REMOVE) { + int index = pdata[1] & 0xff; + inventoryItemsCount--; + for (int l12 = index; l12 < inventoryItemsCount; l12++) { + inventoryItemId[l12] = inventoryItemId[l12 + 1]; + inventoryItemStackCount[l12] = inventoryItemStackCount[l12 + 1]; + inventoryEquipped[l12] = inventoryEquipped[l12 + 1]; + } + + return; + } + if (opcode == Command.SV_PLAYER_STAT_UPDATE) { + int l6 = 1; + int i13 = pdata[l6++] & 0xff; + playerStatCurrent[i13] = Utility.getUnsignedByte(pdata[l6++]); + playerStatBase[i13] = Utility.getUnsignedByte(pdata[l6++]); + playerExperience[i13] = Utility.getUnsignedInt(pdata, l6); + l6 += 4; + return; + } + if (opcode == Command.SV_DUEL_OPPONENT_ACCEPTED) { + byte byte2 = pdata[1]; + if (byte2 == 1) { + duelOfferOpponentAccepted = true; + return; + } else { + duelOfferOpponentAccepted = false; + return; + } + } + if (opcode == Command.SV_DUEL_ACCEPTED) { + byte byte3 = pdata[1]; + if (byte3 == 1) { + duelOfferAccepted = true; + return; + } else { + duelOfferAccepted = false; + return; + } + } + if (opcode == Command.SV_DUEL_CONFIRM_OPEN) { + showDialogDuelConfirm = true; + duelAccepted = false; + showDialogDuel = false; + int off = 1; + duelOpponentNameHash = Utility.getUnsignedLong(pdata, off); + off += 8; + duelOpponentItemsCount = pdata[off++] & 0xff; + for (int j13 = 0; j13 < duelOpponentItemsCount; j13++) { + duelOpponentItems[j13] = Utility.getUnsignedShort(pdata, off); + off += 2; + duelOpponentItemCount[j13] = Utility.getUnsignedInt(pdata, off); + off += 4; + } + + duelItemsCount = pdata[off++] & 0xff; + for (int j18 = 0; j18 < duelItemsCount; j18++) { + duelItems[j18] = Utility.getUnsignedShort(pdata, off); + off += 2; + duelItemCount[j18] = Utility.getUnsignedInt(pdata, off); + off += 4; + } + + duelOptionRetreat = pdata[off++] & 0xff; + duelOptionMagic = pdata[off++] & 0xff; + duelOptionPrayer = pdata[off++] & 0xff; + duelOptionWeapons = pdata[off++] & 0xff; + return; + } + if (opcode == Command.SV_SOUND) { + String s = new String(pdata, 1, psize - 1); + playSoundFile(s); + return; + } + if (opcode == Command.SV_TELEPORT_BUBBLE) { + if (teleportBubbleCount < 50) { + int type = pdata[1] & 0xff; + int x = pdata[2] + localRegionX; + int y = pdata[3] + localRegionY; + teleportBubbleType[teleportBubbleCount] = type; + teleportBubbleTime[teleportBubbleCount] = 0; + teleportBubbleX[teleportBubbleCount] = x; + teleportBubbleY[teleportBubbleCount] = y; + teleportBubbleCount++; + } + return; + } + if (opcode == Command.SV_WELCOME) { + if (!welcomScreenAlreadyShown) { + welcomeLastLoggedInIP = Utility.getUnsignedInt(pdata, 1); + welcomeLastLoggedInDays = Utility.getUnsignedShort(pdata, 5); + welcomeRecoverySetDays = pdata[7] & 0xff; + welcomeUnreadMessages = Utility.getUnsignedShort(pdata, 8); + showDialogWelcome = true; + welcomScreenAlreadyShown = true; + welcomeLastLoggedInHost = null; + } + return; + } + if (opcode == Command.SV_SERVER_MESSAGE) { + serverMessage = new String(pdata, 1, psize - 1); + showDialogServermessage = true; + serverMessageBoxTop = false; + return; + } + if (opcode == Command.SV_SERVER_MESSAGE_ONTOP) { + serverMessage = new String(pdata, 1, psize - 1); + showDialogServermessage = true; + serverMessageBoxTop = true; + return; + } + if (opcode == Command.SV_PLAYER_STAT_FATIGUE) { + statFatigue = Utility.getUnsignedShort(pdata, 1); + return; + } + if (opcode == Command.SV_SLEEP_OPEN) { + if (!isSleeping) + fatigueSleeping = statFatigue; + isSleeping = true; + super.inputTextCurrent = ""; + super.inputTextFinal = ""; + surface.readSleepWord(spriteTexture + 1, pdata); + sleepingStatusText = null; + return; + } + if (opcode == Command.SV_PLAYER_STAT_FATIGUE_ASLEEP) { + fatigueSleeping = Utility.getUnsignedShort(pdata, 1); + return; + } + if (opcode == Command.SV_SLEEP_CLOSE) { + isSleeping = false; + return; + } + if (opcode == Command.SV_SLEEP_INCORRECT) { + sleepingStatusText = "Incorrect - Please wait..."; + return; + } + if (opcode == Command.SV_SYSTEM_UPDATE) { + systemUpdate = Utility.getUnsignedShort(pdata, 1) * 32; + return; + } + } catch (RuntimeException runtimeexception) { + if (packetErrorCount < 3) { + String s1 = runtimeexception.toString(); + int slen = s1.length(); + super.clientStream.newPacket((Command.CL_PACKET_EXCEPTION)); + super.clientStream.putShort(slen); + super.clientStream.putString(s1); + super.clientStream.putShort(slen = (s1 = "p-type: " + opcode + "(" + ptype + ") p-size:" + psize).length()); + super.clientStream.putString(s1); + super.clientStream.putShort(slen = (s1 = "rx:" + localRegionX + " ry:" + localRegionY + " num3l:" + objectCount).length()); + super.clientStream.putString(s1); + s1 = ""; + for (int l18 = 0; l18 < 80 && l18 < psize; l18++) + s1 = s1 + pdata[l18] + " "; + super.clientStream.putShort(s1.length()); + super.clientStream.putString(s1); + super.clientStream.sendPacket(); + packetErrorCount++; + } + super.clientStream.closeStream(); + resetLoginVars(); + } + } + + private void drawUiTabPlayerInfo(boolean nomenus) { + int uiX = surface.width2 - 199; + int uiY = 36; + surface.drawSprite(uiX - 49, 3, spriteMedia + 3); + int uiWidth = 196;// '\304'; + int uiHeight = 275;// '\u0113'; + int l; + int k = l = Surface.rgb2long(160, 160, 160); + if (uiTabPlayerInfoSubTab == 0) + k = Surface.rgb2long(220, 220, 220); + else + l = Surface.rgb2long(220, 220, 220); + surface.drawBoxAlpha(uiX, uiY, uiWidth / 2, 24, k, 128); + surface.drawBoxAlpha(uiX + uiWidth / 2, uiY, uiWidth / 2, 24, l, 128); + surface.drawBoxAlpha(uiX, uiY + 24, uiWidth, uiHeight - 24, Surface.rgb2long(220, 220, 220), 128); + surface.drawLineHoriz(uiX, uiY + 24, uiWidth, 0); + surface.drawLineVert(uiX + uiWidth / 2, uiY, 24, 0); + surface.drawStringCenter("Stats", uiX + uiWidth / 4, uiY + 16, 4, 0); + surface.drawStringCenter("Quests", uiX + uiWidth / 4 + uiWidth / 2, uiY + 16, 4, 0); + if (uiTabPlayerInfoSubTab == 0) { + int i1 = 72; + int k1 = -1; + surface.drawstring("Skills", uiX + 5, i1, 3, 0xffff00); + i1 += 13; + for (int l1 = 0; l1 < 9; l1++) { + int i2 = 0xffffff; + if (super.mouseX > uiX + 3 && super.mouseY >= i1 - 11 && super.mouseY < i1 + 2 && super.mouseX < uiX + 90) { + i2 = 0xff0000; + k1 = l1; + } + surface.drawstring(skillNameShort[l1] + ":@yel@" + playerStatCurrent[l1] + "/" + playerStatBase[l1], uiX + 5, i1, 1, i2); + i2 = 0xffffff; + if (super.mouseX >= uiX + 90 && super.mouseY >= i1 - 13 - 11 && super.mouseY < (i1 - 13) + 2 && super.mouseX < uiX + 196) { + i2 = 0xff0000; + k1 = l1 + 9; + } + surface.drawstring(skillNameShort[l1 + 9] + ":@yel@" + playerStatCurrent[l1 + 9] + "/" + playerStatBase[l1 + 9], (uiX + uiWidth / 2) - 5, i1 - 13, 1, i2); + i1 += 13; + } + + surface.drawstring("Quest Points:@yel@" + playerQuestPoints, (uiX + uiWidth / 2) - 5, i1 - 13, 1, 0xffffff); + i1 += 12; + surface.drawstring("Fatigue: @yel@" + (statFatigue * 100) / 750 + "%", uiX + 5, i1 - 13, 1, 0xffffff); + i1 += 8; + surface.drawstring("Equipment Status", uiX + 5, i1, 3, 0xffff00); + i1 += 12; + for (int j2 = 0; j2 < 3; j2++) { + surface.drawstring(equipmentStatNames[j2] + ":@yel@" + playerStatEquipment[j2], uiX + 5, i1, 1, 0xffffff); + if (j2 < 2) + surface.drawstring(equipmentStatNames[j2 + 3] + ":@yel@" + playerStatEquipment[j2 + 3], uiX + uiWidth / 2 + 25, i1, 1, 0xffffff); + i1 += 13; + } + + i1 += 6; + surface.drawLineHoriz(uiX, i1 - 15, uiWidth, 0); + if (k1 != -1) { + surface.drawstring(skillNameLong[k1] + " skill", uiX + 5, i1, 1, 0xffff00); + i1 += 12; + int k2 = experienceArray[0]; + for (int i3 = 0; i3 < 98; i3++) + if (playerExperience[k1] >= experienceArray[i3]) + k2 = experienceArray[i3 + 1]; + + surface.drawstring("Total xp: " + playerExperience[k1] / 4, uiX + 5, i1, 1, 0xffffff); + i1 += 12; + surface.drawstring("Next level at: " + k2 / 4, uiX + 5, i1, 1, 0xffffff); + } else { + surface.drawstring("Overall levels", uiX + 5, i1, 1, 0xffff00); + i1 += 12; + int l2 = 0; + for (int j3 = 0; j3 < playerStatCount; j3++) + l2 += playerStatBase[j3]; + + surface.drawstring("Skill total: " + l2, uiX + 5, i1, 1, 0xffffff); + i1 += 12; + surface.drawstring("Combat level: " + localPlayer.level, uiX + 5, i1, 1, 0xffffff); + i1 += 12; + } + } + if (uiTabPlayerInfoSubTab == 1) { + panelQuestList.clearList(controlListQuest); + panelQuestList.addListEntry(controlListQuest, 0, "@whi@Quest-list (green=completed)"); + for (int j1 = 0; j1 < questCount; j1++) + panelQuestList.addListEntry(controlListQuest, j1 + 1, (questComplete[j1] ? "@gre@" : "@red@") + questName[j1]); + + panelQuestList.drawPanel(); + } + if (!nomenus) + return; + int mouseX = super.mouseX - (surface.width2 - 199); + int mouseY = super.mouseY - 36; + if (mouseX >= 0 && mouseY >= 0 && mouseX < uiWidth && mouseY < uiHeight) { + if (uiTabPlayerInfoSubTab == 1) + panelQuestList.handleMouse(mouseX + (surface.width2 - 199), mouseY + 36, super.lastMouseButtonDown, super.mouseButtonDown); + if (mouseY <= 24 && mouseButtonClick == 1) { + if (mouseX < 98) { + uiTabPlayerInfoSubTab = 0; + return; + } + if (mouseX > 98) + uiTabPlayerInfoSubTab = 1; + } + } + } + + private void createRightClickMenu() { + int i = 2203 - (localRegionY + planeHeight + regionY); + if (localRegionX + planeWidth + regionX >= 2640) + i = -50; + int j = -1; + for (int k = 0; k < objectCount; k++) + objectAlreadyInMenu[k] = false; + + for (int l = 0; l < wallObjectCount; l++) + wallObjectAlreadyInMenu[l] = false; + + int i1 = scene.getMousePickedCount(); + GameModel objs[] = scene.getMousePickedModels(); + int plyrs[] = scene.getMousePickedFaces(); + for (int menuidx = 0; menuidx < i1; menuidx++) { + if (menuItemsCount > 200) + break; + int pid = plyrs[menuidx]; + GameModel gameModel = objs[menuidx]; + if (gameModel.faceTag[pid] <= 65535 || gameModel.faceTag[pid] >= 200000 && gameModel.faceTag[pid] <= 300000)// 0x30d40 0x493e0 + if (gameModel == scene.view) { + int idx = gameModel.faceTag[pid] % 10000; + int type = gameModel.faceTag[pid] / 10000; + if (type == 1) { + String s = ""; + int k3 = 0; + if (localPlayer.level > 0 && players[idx].level > 0) + k3 = localPlayer.level - players[idx].level; + if (k3 < 0) + s = "@or1@"; + if (k3 < -3) + s = "@or2@"; + if (k3 < -6) + s = "@or3@"; + if (k3 < -9) + s = "@red@"; + if (k3 > 0) + s = "@gr1@"; + if (k3 > 3) + s = "@gr2@"; + if (k3 > 6) + s = "@gr3@"; + if (k3 > 9) + s = "@gre@"; + s = " " + s + "(level-" + players[idx].level + ")"; + if (selectedSpell >= 0) { + if (GameData.spellType[selectedSpell] == 1 || GameData.spellType[selectedSpell] == 2) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on"; + menuItemText2[menuItemsCount] = "@whi@" + players[idx].name + s; + menuItemID[menuItemsCount] = 800; + menuItemX[menuItemsCount] = players[idx].currentX; + menuItemY[menuItemsCount] = players[idx].currentY; + menuSourceType[menuItemsCount] = players[idx].serverIndex; + menuSourceIndex[menuItemsCount] = selectedSpell; + menuItemsCount++; + } + } else if (selectedItemInventoryIndex >= 0) { + menuItemText1[menuItemsCount] = "Use " + selectedItemName + " with"; + menuItemText2[menuItemsCount] = "@whi@" + players[idx].name + s; + menuItemID[menuItemsCount] = 810; + menuItemX[menuItemsCount] = players[idx].currentX; + menuItemY[menuItemsCount] = players[idx].currentY; + menuSourceType[menuItemsCount] = players[idx].serverIndex; + menuSourceIndex[menuItemsCount] = selectedItemInventoryIndex; + menuItemsCount++; + } else { + if (i > 0 && (players[idx].currentY - 64) / magicLoc + planeHeight + regionY < 2203) { + menuItemText1[menuItemsCount] = "Attack"; + menuItemText2[menuItemsCount] = "@whi@" + players[idx].name + s; + if (k3 >= 0 && k3 < 5) + menuItemID[menuItemsCount] = 805; + else + menuItemID[menuItemsCount] = 2805; + menuItemX[menuItemsCount] = players[idx].currentX; + menuItemY[menuItemsCount] = players[idx].currentY; + menuSourceType[menuItemsCount] = players[idx].serverIndex; + menuItemsCount++; + } else if (members) { + menuItemText1[menuItemsCount] = "Duel with"; + menuItemText2[menuItemsCount] = "@whi@" + players[idx].name + s; + menuItemX[menuItemsCount] = players[idx].currentX; + menuItemY[menuItemsCount] = players[idx].currentY; + menuItemID[menuItemsCount] = 2806; + menuSourceType[menuItemsCount] = players[idx].serverIndex; + menuItemsCount++; + } + menuItemText1[menuItemsCount] = "Trade with"; + menuItemText2[menuItemsCount] = "@whi@" + players[idx].name + s; + menuItemID[menuItemsCount] = 2810; + menuSourceType[menuItemsCount] = players[idx].serverIndex; + menuItemsCount++; + menuItemText1[menuItemsCount] = "Follow"; + menuItemText2[menuItemsCount] = "@whi@" + players[idx].name + s; + menuItemID[menuItemsCount] = 2820; + menuSourceType[menuItemsCount] = players[idx].serverIndex; + menuItemsCount++; + } + } else if (type == 2) { + if (selectedSpell >= 0) { + if (GameData.spellType[selectedSpell] == 3) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[groundItemId[idx]]; + menuItemID[menuItemsCount] = 200; + menuItemX[menuItemsCount] = groundItemX[idx]; + menuItemY[menuItemsCount] = groundItemY[idx]; + menuSourceType[menuItemsCount] = groundItemId[idx]; + menuSourceIndex[menuItemsCount] = selectedSpell; + menuItemsCount++; + } + } else if (selectedItemInventoryIndex >= 0) { + menuItemText1[menuItemsCount] = "Use " + selectedItemName + " with"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[groundItemId[idx]]; + menuItemID[menuItemsCount] = 210; + menuItemX[menuItemsCount] = groundItemX[idx]; + menuItemY[menuItemsCount] = groundItemY[idx]; + menuSourceType[menuItemsCount] = groundItemId[idx]; + menuSourceIndex[menuItemsCount] = selectedItemInventoryIndex; + menuItemsCount++; + } else { + menuItemText1[menuItemsCount] = "Take"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[groundItemId[idx]]; + menuItemID[menuItemsCount] = 220; + menuItemX[menuItemsCount] = groundItemX[idx]; + menuItemY[menuItemsCount] = groundItemY[idx]; + menuSourceType[menuItemsCount] = groundItemId[idx]; + menuItemsCount++; + menuItemText1[menuItemsCount] = "Examine"; + menuItemText2[menuItemsCount] = "@lre@" + GameData.itemName[groundItemId[idx]]; + menuItemID[menuItemsCount] = 3200; + menuSourceType[menuItemsCount] = groundItemId[idx]; + menuItemsCount++; + } + } else if (type == 3) { + String s1 = ""; + int leveldiff = -1; + int id = npcs[idx].npcId; + if (GameData.npcAttackable[id] > 0) { + int npclevel = (GameData.npcAttack[id] + GameData.npcDefense[id] + GameData.npcStrength[id] + GameData.npcHits[id]) / 4; + int playerlevel = (playerStatBase[0] + playerStatBase[1] + playerStatBase[2] + playerStatBase[3] + 27) / 4; + leveldiff = playerlevel - npclevel; + s1 = "@yel@"; + if (leveldiff < 0) + s1 = "@or1@"; + if (leveldiff < -3) + s1 = "@or2@"; + if (leveldiff < -6) + s1 = "@or3@"; + if (leveldiff < -9) + s1 = "@red@"; + if (leveldiff > 0) + s1 = "@gr1@"; + if (leveldiff > 3) + s1 = "@gr2@"; + if (leveldiff > 6) + s1 = "@gr3@"; + if (leveldiff > 9) + s1 = "@gre@"; + s1 = " " + s1 + "(level-" + npclevel + ")"; + } + if (selectedSpell >= 0) { + if (GameData.spellType[selectedSpell] == 2) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on"; + menuItemText2[menuItemsCount] = "@yel@" + GameData.npcName[npcs[idx].npcId]; + menuItemID[menuItemsCount] = 700; + menuItemX[menuItemsCount] = npcs[idx].currentX; + menuItemY[menuItemsCount] = npcs[idx].currentY; + menuSourceType[menuItemsCount] = npcs[idx].serverIndex; + menuSourceIndex[menuItemsCount] = selectedSpell; + menuItemsCount++; + } + } else if (selectedItemInventoryIndex >= 0) { + menuItemText1[menuItemsCount] = "Use " + selectedItemName + " with"; + menuItemText2[menuItemsCount] = "@yel@" + GameData.npcName[npcs[idx].npcId]; + menuItemID[menuItemsCount] = 710; + menuItemX[menuItemsCount] = npcs[idx].currentX; + menuItemY[menuItemsCount] = npcs[idx].currentY; + menuSourceType[menuItemsCount] = npcs[idx].serverIndex; + menuSourceIndex[menuItemsCount] = selectedItemInventoryIndex; + menuItemsCount++; + } else { + if (GameData.npcAttackable[id] > 0) { + menuItemText1[menuItemsCount] = "Attack"; + menuItemText2[menuItemsCount] = "@yel@" + GameData.npcName[npcs[idx].npcId] + s1; + if (leveldiff >= 0) + menuItemID[menuItemsCount] = 715; + else + menuItemID[menuItemsCount] = 2715; + menuItemX[menuItemsCount] = npcs[idx].currentX; + menuItemY[menuItemsCount] = npcs[idx].currentY; + menuSourceType[menuItemsCount] = npcs[idx].serverIndex; + menuItemsCount++; + } + menuItemText1[menuItemsCount] = "Talk-to"; + menuItemText2[menuItemsCount] = "@yel@" + GameData.npcName[npcs[idx].npcId]; + menuItemID[menuItemsCount] = 720; + menuItemX[menuItemsCount] = npcs[idx].currentX; + menuItemY[menuItemsCount] = npcs[idx].currentY; + menuSourceType[menuItemsCount] = npcs[idx].serverIndex; + menuItemsCount++; + if (!GameData.npcCommand[id].equals("")) { + menuItemText1[menuItemsCount] = GameData.npcCommand[id]; + menuItemText2[menuItemsCount] = "@yel@" + GameData.npcName[npcs[idx].npcId]; + menuItemID[menuItemsCount] = 725; + menuItemX[menuItemsCount] = npcs[idx].currentX; + menuItemY[menuItemsCount] = npcs[idx].currentY; + menuSourceType[menuItemsCount] = npcs[idx].serverIndex; + menuItemsCount++; + } + menuItemText1[menuItemsCount] = "Examine"; + menuItemText2[menuItemsCount] = "@yel@" + GameData.npcName[npcs[idx].npcId]; + menuItemID[menuItemsCount] = 3700; + menuSourceType[menuItemsCount] = npcs[idx].npcId; + menuItemsCount++; + } + } + } else if (gameModel != null && gameModel.key >= 10000) { + int idx = gameModel.key - 10000; + int id = wallObjectId[idx]; + if (!wallObjectAlreadyInMenu[idx]) { + if (selectedSpell >= 0) { + if (GameData.spellType[selectedSpell] == 4) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on"; + menuItemText2[menuItemsCount] = "@cya@" + GameData.wallObjectName[id]; + menuItemID[menuItemsCount] = 300; + menuItemX[menuItemsCount] = wallObjectX[idx]; + menuItemY[menuItemsCount] = wallObjectY[idx]; + menuSourceType[menuItemsCount] = wallObjectDirection[idx]; + menuSourceIndex[menuItemsCount] = selectedSpell; + menuItemsCount++; + } + } else if (selectedItemInventoryIndex >= 0) { + menuItemText1[menuItemsCount] = "Use " + selectedItemName + " with"; + menuItemText2[menuItemsCount] = "@cya@" + GameData.wallObjectName[id]; + menuItemID[menuItemsCount] = 310; + menuItemX[menuItemsCount] = wallObjectX[idx]; + menuItemY[menuItemsCount] = wallObjectY[idx]; + menuSourceType[menuItemsCount] = wallObjectDirection[idx]; + menuSourceIndex[menuItemsCount] = selectedItemInventoryIndex; + menuItemsCount++; + } else { + if (!GameData.wallObjectCommand1[id].equalsIgnoreCase("WalkTo")) { + menuItemText1[menuItemsCount] = GameData.wallObjectCommand1[id]; + menuItemText2[menuItemsCount] = "@cya@" + GameData.wallObjectName[id]; + menuItemID[menuItemsCount] = 320; + menuItemX[menuItemsCount] = wallObjectX[idx]; + menuItemY[menuItemsCount] = wallObjectY[idx]; + menuSourceType[menuItemsCount] = wallObjectDirection[idx]; + menuItemsCount++; + } + if (!GameData.wallObjectCommand2[id].equalsIgnoreCase("Examine")) { + menuItemText1[menuItemsCount] = GameData.wallObjectCommand2[id]; + menuItemText2[menuItemsCount] = "@cya@" + GameData.wallObjectName[id]; + menuItemID[menuItemsCount] = 2300; + menuItemX[menuItemsCount] = wallObjectX[idx]; + menuItemY[menuItemsCount] = wallObjectY[idx]; + menuSourceType[menuItemsCount] = wallObjectDirection[idx]; + menuItemsCount++; + } + menuItemText1[menuItemsCount] = "Examine"; + menuItemText2[menuItemsCount] = "@cya@" + GameData.wallObjectName[id]; + menuItemID[menuItemsCount] = 3300; + menuSourceType[menuItemsCount] = id; + menuItemsCount++; + } + wallObjectAlreadyInMenu[idx] = true; + } + } else if (gameModel != null && gameModel.key >= 0) { + int idx = gameModel.key; + int id = objectId[idx]; + if (!objectAlreadyInMenu[idx]) { + if (selectedSpell >= 0) { + if (GameData.spellType[selectedSpell] == 5) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on"; + menuItemText2[menuItemsCount] = "@cya@" + GameData.objectName[id]; + menuItemID[menuItemsCount] = 400; + menuItemX[menuItemsCount] = objectX[idx]; + menuItemY[menuItemsCount] = objectY[idx]; + menuSourceType[menuItemsCount] = objectDirection[idx]; + menuSourceIndex[menuItemsCount] = objectId[idx]; + menuTargetIndex[menuItemsCount] = selectedSpell; + menuItemsCount++; + } + } else if (selectedItemInventoryIndex >= 0) { + menuItemText1[menuItemsCount] = "Use " + selectedItemName + " with"; + menuItemText2[menuItemsCount] = "@cya@" + GameData.objectName[id]; + menuItemID[menuItemsCount] = 410; + menuItemX[menuItemsCount] = objectX[idx]; + menuItemY[menuItemsCount] = objectY[idx]; + menuSourceType[menuItemsCount] = objectDirection[idx]; + menuSourceIndex[menuItemsCount] = objectId[idx]; + menuTargetIndex[menuItemsCount] = selectedItemInventoryIndex; + menuItemsCount++; + } else { + if (!GameData.objectCommand1[id].equalsIgnoreCase("WalkTo")) { + menuItemText1[menuItemsCount] = GameData.objectCommand1[id]; + menuItemText2[menuItemsCount] = "@cya@" + GameData.objectName[id]; + menuItemID[menuItemsCount] = 420; + menuItemX[menuItemsCount] = objectX[idx]; + menuItemY[menuItemsCount] = objectY[idx]; + menuSourceType[menuItemsCount] = objectDirection[idx]; + menuSourceIndex[menuItemsCount] = objectId[idx]; + menuItemsCount++; + } + if (!GameData.objectCommand2[id].equalsIgnoreCase("Examine")) { + menuItemText1[menuItemsCount] = GameData.objectCommand2[id]; + menuItemText2[menuItemsCount] = "@cya@" + GameData.objectName[id]; + menuItemID[menuItemsCount] = 2400; + menuItemX[menuItemsCount] = objectX[idx]; + menuItemY[menuItemsCount] = objectY[idx]; + menuSourceType[menuItemsCount] = objectDirection[idx]; + menuSourceIndex[menuItemsCount] = objectId[idx]; + menuItemsCount++; + } + menuItemText1[menuItemsCount] = "Examine"; + menuItemText2[menuItemsCount] = "@cya@" + GameData.objectName[id]; + menuItemID[menuItemsCount] = 3400; + menuSourceType[menuItemsCount] = id; + menuItemsCount++; + } + objectAlreadyInMenu[idx] = true; + } + } else { + if (pid >= 0) + pid = gameModel.faceTag[pid] - 200000; + if (pid >= 0) + j = pid; + } + } + + if (selectedSpell >= 0 && GameData.spellType[selectedSpell] <= 1) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on self"; + menuItemText2[menuItemsCount] = ""; + menuItemID[menuItemsCount] = 1000; + menuSourceType[menuItemsCount] = selectedSpell; + menuItemsCount++; + } + if (j != -1) { + if (selectedSpell >= 0) { + if (GameData.spellType[selectedSpell] == 6) { + menuItemText1[menuItemsCount] = "Cast " + GameData.spellName[selectedSpell] + " on ground"; + menuItemText2[menuItemsCount] = ""; + menuItemID[menuItemsCount] = 900; + menuItemX[menuItemsCount] = world.localX[j]; + menuItemY[menuItemsCount] = world.localY[j]; + menuSourceType[menuItemsCount] = selectedSpell; + menuItemsCount++; + return; + } + } else if (selectedItemInventoryIndex < 0) { + menuItemText1[menuItemsCount] = "Walk here"; + menuItemText2[menuItemsCount] = ""; + menuItemID[menuItemsCount] = 920; + menuItemX[menuItemsCount] = world.localX[j]; + menuItemY[menuItemsCount] = world.localY[j]; + menuItemsCount++; + } + } + } + + protected void handleInputs() { + if (errorLoadingCodebase) + return; + if (errorLoadingMemory) + return; + if (errorLoadingData) + return; + try { + loginTimer++; + if (loggedIn == 0) { + super.mouseActionTimeout = 0; + handleLoginScreenInput(); + } + if (loggedIn == 1) { + super.mouseActionTimeout++; + handleGameInput(); + } + super.lastMouseButtonDown = 0; + //super.unusedKeyCode2 = 0; + cameraRotationTime++; + if (cameraRotationTime > 500) { + cameraRotationTime = 0; + int i = (int) (Math.random() * 4D); + if ((i & 1) == 1) + cameraRotationX += cameraRotationXIncrement; + if ((i & 2) == 2) + cameraRotationY += cameraRotationYIncrement; + } + if (cameraRotationX < -50) + cameraRotationXIncrement = 2; + if (cameraRotationX > 50) + cameraRotationXIncrement = -2; + if (cameraRotationY < -50) + cameraRotationYIncrement = 2; + if (cameraRotationY > 50) + cameraRotationYIncrement = -2; + if (messageTabFlashAll > 0) + messageTabFlashAll--; + if (messageTabFlashHistory > 0) + messageTabFlashHistory--; + if (messtageTabFlashQuest > 0) + messtageTabFlashQuest--; + if (messageTabFlashPrivate > 0) { + messageTabFlashPrivate--; + return; + } + } catch (OutOfMemoryError Ex) { + disposeAndCollect(); + errorLoadingMemory = true; + } + } + + private void handleLoginScreenInput() { + if (super.worldFullTimeout > 0) + super.worldFullTimeout--; + if (loginScreen == 0) { + panelLoginWelcome.handleMouse(super.mouseX, super.mouseY, super.lastMouseButtonDown, super.mouseButtonDown); + if (panelLoginWelcome.isClicked(controlWelcomeNewuser)) + loginScreen = 1; + if (panelLoginWelcome.isClicked(controlWelcomeExistinguser)) { + loginScreen = 2; + panelLoginExistinguser.updateText(controlLoginStatus, "Please enter your username and password"); + panelLoginExistinguser.updateText(controlLoginUser, ""); + panelLoginExistinguser.updateText(controlLoginPass, ""); + panelLoginExistinguser.setFocus(controlLoginUser); + return; + } + } else if (loginScreen == 1) { + panelLoginNewuser.handleMouse(super.mouseX, super.mouseY, super.lastMouseButtonDown, super.mouseButtonDown); + if (panelLoginNewuser.isClicked(controlLoginNewOk)) { + loginScreen = 0; + return; + } + } else if (loginScreen == 2) { + panelLoginExistinguser.handleMouse(super.mouseX, super.mouseY, super.lastMouseButtonDown, super.mouseButtonDown); + if (panelLoginExistinguser.isClicked(controlLoginCancel)) + loginScreen = 0; + if (panelLoginExistinguser.isClicked(controlLoginUser)) + panelLoginExistinguser.setFocus(controlLoginPass); + if (panelLoginExistinguser.isClicked(controlLoginPass) || panelLoginExistinguser.isClicked(controlLoginOk)) { + loginUser = panelLoginExistinguser.getText(controlLoginUser); + loginPass = panelLoginExistinguser.getText(controlLoginPass); + login(loginUser, loginPass, false); + } + } + } + + private void loadMaps() { + world.mapPack = readDataFile("maps" + Version.MAPS + ".jag", "map", 70); + if (members) + world.memberMapPack = readDataFile("maps" + Version.MAPS + ".mem", "members map", 75); + world.landscapePack = readDataFile("land" + Version.MAPS + ".jag", "landscape", 80); + if (members) + world.memberLandscapePack = readDataFile("land" + Version.MAPS + ".mem", "members landscape", 85); + } + + private GameModel createModel(int x, int y, int direction, int id, int count) { + int x1 = x; + int y1 = y; + int x2 = x; + int y2 = y; + int j2 = GameData.wallObjectTextureFront[id]; + int k2 = GameData.wallObjectTextureBack[id]; + int l2 = GameData.wallObjectHeight[id]; + GameModel gameModel = new GameModel(4, 1); + if (direction == 0) + x2 = x + 1; + if (direction == 1) + y2 = y + 1; + if (direction == 2) { + x1 = x + 1; + y2 = y + 1; + } + if (direction == 3) { + x2 = x + 1; + y2 = y + 1; + } + x1 *= magicLoc; + y1 *= magicLoc; + x2 *= magicLoc; + y2 *= magicLoc; + int i3 = gameModel.vertexAt(x1, -world.getElevation(x1, y1), y1); + int j3 = gameModel.vertexAt(x1, -world.getElevation(x1, y1) - l2, y1); + int k3 = gameModel.vertexAt(x2, -world.getElevation(x2, y2) - l2, y2); + int l3 = gameModel.vertexAt(x2, -world.getElevation(x2, y2), y2); + int ai[] = { + i3, j3, k3, l3 + }; + gameModel.createFace(4, ai, j2, k2); + gameModel.setLight(false, 60, 24, -50, -10, -50); + if (x >= 0 && y >= 0 && x < 96 && y < 96) + scene.addModel(gameModel); + gameModel.key = count + 10000; + return gameModel; + } + /* unused + private String recoveryQuestions[] = { + "Where were you born?", "What was your first teachers name?", "What is your fathers middle name?", "Who was your first best friend?", "What is your favourite vacation spot?", "What is your mothers middle name?", "What was your first pets name?", "What was the name of your first school?", "What is your mothers maiden name?", "Who was your first boyfriend/girlfriend?", + "What was the first computer game you purchased?", "Who is your favourite actor/actress?", "Who is your favourite author?", "Who is your favourite musician?", "Who is your favourite cartoon character?", "What is your favourite book?", "What is your favourite food?", "What is your favourite movie?" + };*/ +}