commit b5183f51c3d20e5e046d4fa9aa37cb8fe02e73a1 Author: Ethan Date: Sun Dec 15 20:35:23 2019 -0600 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..744289d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Project exclude paths +/target/ \ No newline at end of file diff --git a/.idea/$PRODUCT_WORKSPACE_FILE$ b/.idea/$PRODUCT_WORKSPACE_FILE$ new file mode 100644 index 0000000..3733e0d --- /dev/null +++ b/.idea/$PRODUCT_WORKSPACE_FILE$ @@ -0,0 +1,19 @@ + + + + + + + 1.8 + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..347b36b --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4b661a5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/2006RebottedClient.iml b/2006RebottedClient.iml new file mode 100644 index 0000000..78b2cc5 --- /dev/null +++ b/2006RebottedClient.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Cache/.scape-settings.dat b/Cache/.scape-settings.dat new file mode 100644 index 0000000..ae9010a Binary files /dev/null and b/Cache/.scape-settings.dat differ diff --git a/Cache/added.txt b/Cache/added.txt new file mode 100644 index 0000000..b7b79ac --- /dev/null +++ b/Cache/added.txt @@ -0,0 +1,10 @@ +#149 item defs +#149 npc defs +#149 object defs +#149 varbits +#149 gfx +#149 models +#149 anims +#149 maps +#149 idk +- Freyr \ No newline at end of file diff --git a/Cache/bsp_1.49.jar b/Cache/bsp_1.49.jar new file mode 100644 index 0000000..34a177f Binary files /dev/null and b/Cache/bsp_1.49.jar differ diff --git a/Cache/full_image.png b/Cache/full_image.png new file mode 100644 index 0000000..6c03254 Binary files /dev/null and b/Cache/full_image.png differ diff --git a/Cache/jingle1.mid b/Cache/jingle1.mid new file mode 100644 index 0000000..a7b9cf2 Binary files /dev/null and b/Cache/jingle1.mid differ diff --git a/Cache/main_file_cache.dat b/Cache/main_file_cache.dat new file mode 100644 index 0000000..c11bbca Binary files /dev/null and b/Cache/main_file_cache.dat differ diff --git a/Cache/main_file_cache.idx0 b/Cache/main_file_cache.idx0 new file mode 100644 index 0000000..dd9cdf6 Binary files /dev/null and b/Cache/main_file_cache.idx0 differ diff --git a/Cache/main_file_cache.idx1 b/Cache/main_file_cache.idx1 new file mode 100644 index 0000000..062b005 Binary files /dev/null and b/Cache/main_file_cache.idx1 differ diff --git a/Cache/main_file_cache.idx2 b/Cache/main_file_cache.idx2 new file mode 100644 index 0000000..dded7ef Binary files /dev/null and b/Cache/main_file_cache.idx2 differ diff --git a/Cache/main_file_cache.idx3 b/Cache/main_file_cache.idx3 new file mode 100644 index 0000000..605dcc5 Binary files /dev/null and b/Cache/main_file_cache.idx3 differ diff --git a/Cache/main_file_cache.idx4 b/Cache/main_file_cache.idx4 new file mode 100644 index 0000000..6bc7875 Binary files /dev/null and b/Cache/main_file_cache.idx4 differ diff --git a/Cache/main_file_sprites.dat b/Cache/main_file_sprites.dat new file mode 100644 index 0000000..bb91434 Binary files /dev/null and b/Cache/main_file_sprites.dat differ diff --git a/Cache/sound0.wav b/Cache/sound0.wav new file mode 100644 index 0000000..061d21b Binary files /dev/null and b/Cache/sound0.wav differ diff --git a/Cache/sound1.wav b/Cache/sound1.wav new file mode 100644 index 0000000..061d21b Binary files /dev/null and b/Cache/sound1.wav differ diff --git a/Cache/sound2.wav b/Cache/sound2.wav new file mode 100644 index 0000000..061d21b Binary files /dev/null and b/Cache/sound2.wav differ diff --git a/Cache/sound3.wav b/Cache/sound3.wav new file mode 100644 index 0000000..061d21b Binary files /dev/null and b/Cache/sound3.wav differ diff --git a/Cache/sound4.wav b/Cache/sound4.wav new file mode 100644 index 0000000..061d21b Binary files /dev/null and b/Cache/sound4.wav differ diff --git a/Cache/uid.dat b/Cache/uid.dat new file mode 100644 index 0000000..cd54d73 --- /dev/null +++ b/Cache/uid.dat @@ -0,0 +1 @@ +Í+É \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..d979ecb --- /dev/null +++ b/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + org.rebotted.client + client + 1.0-SNAPSHOT + + + 1.8 + 1.8 + + + + + com.github.insubstantial + substance + 7.3 + + + org.pushing-pixels + radiance-trident + 2.0.0 + + + org.apache.commons + commons-compress + 1.13 + + + org.tukaani + xz + 1.6 + + + + + + + + src/main/resources + + **/*.fxml + **/*.css + **/*.png + rebotted.colorschemes + + + + + \ No newline at end of file diff --git a/src/main/java/net/rebotted/cache/graphics/RSFont.java b/src/main/java/net/rebotted/cache/graphics/RSFont.java new file mode 100644 index 0000000..dc785c2 --- /dev/null +++ b/src/main/java/net/rebotted/cache/graphics/RSFont.java @@ -0,0 +1,846 @@ +package net.rebotted.cache.graphics; +import java.awt.Color; + +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.graphics.GameFont; +import org.rebotted.cache.graphics.Sprite; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.io.Buffer; + +public class RSFont extends Rasterizer2D { + + public int baseCharacterHeight = 0; + public int anInt4142; + public int anInt4144; + public int[] characterDrawYOffsets; + public int[] characterHeights; + public int[] characterDrawXOffsets; + public int[] characterWidths; + public int[] iconWidths; + public byte[] aByteArray4151; + public byte[][] fontPixels; + public int[] characterScreenWidths; + public static Sprite[] chatImages; + public static Sprite[] clanImages; + public static String aRSString_4135; + public static String startTransparency; + public static String startDefaultShadow; + public static String endShadow = "/shad"; + public static String endEffect; + public static String aRSString_4143; + public static String endStrikethrough = "/str"; + public static String aRSString_4147; + public static String startColor; + public static String lineBreak; + public static String startStrikethrough; + public static String endColor; + public static String startImage; + public static String startClanImage; + public static String endUnderline; + public static String defaultStrikethrough; + public static String startShadow; + public static String startEffect; + public static String aRSString_4162; + public static String aRSString_4163; + public static String endTransparency; + public static String aRSString_4165; + public static String startUnderline; + public static String startDefaultUnderline; + public static String aRSString_4169; + public static String[] splitTextStrings; + public static int defaultColor; + public static int textShadowColor; + public static int strikethroughColor; + public static int defaultTransparency; + public static int anInt4175; + public static int underlineColor; + public static int defaultShadow; + public static int anInt4178; + public static int transparency; + public static int textColor; + + public RSFont(boolean TypeFont, String s, FileArchive archive) { + fontPixels = new byte[256][]; + characterWidths = new int[256]; + characterHeights = new int[256]; + characterDrawXOffsets = new int[256]; + characterDrawYOffsets = new int[256]; + characterScreenWidths = new int[256]; + Buffer stream = new Buffer(archive.readFile(s + ".dat")); + Buffer stream_1 = new Buffer(archive.readFile("index.dat")); + stream_1.currentPosition = stream.readUShort() + 4; + int k = stream_1.readUnsignedByte(); + if (k > 0) { + stream_1.currentPosition += 3 * (k - 1); + } + for (int l = 0; l < 256; l++) { + characterDrawXOffsets[l] = stream_1.readUnsignedByte(); + characterDrawYOffsets[l] = stream_1.readUnsignedByte(); + int i1 = characterWidths[l] = stream_1.readUShort(); + int j1 = characterHeights[l] = stream_1.readUShort(); + int k1 = stream_1.readUnsignedByte(); + int l1 = i1 * j1; + fontPixels[l] = new byte[l1]; + if (k1 == 0) { + for (int i2 = 0; i2 < l1; i2++) { + fontPixels[l][i2] = stream.readSignedByte(); + } + + } else if (k1 == 1) { + for (int j2 = 0; j2 < i1; j2++) { + for (int l2 = 0; l2 < j1; l2++) { + fontPixels[l][j2 + l2 * i1] = stream.readSignedByte(); + } + + } + + } + if (j1 > baseCharacterHeight && l < 128) { + baseCharacterHeight = j1; + } + characterDrawXOffsets[l] = 1; + characterScreenWidths[l] = i1 + 2; + int k2 = 0; + for (int i3 = j1 / 7; i3 < j1; i3++) { + k2 += fontPixels[l][i3 * i1]; + } + + if (k2 <= j1 / 7) { + characterScreenWidths[l]--; + characterDrawXOffsets[l] = 0; + } + k2 = 0; + for (int j3 = j1 / 7; j3 < j1; j3++) { + k2 += fontPixels[l][(i1 - 1) + j3 * i1]; + } + + if (k2 <= j1 / 7) { + characterScreenWidths[l]--; + } + } + + if (TypeFont) { + characterScreenWidths[32] = characterScreenWidths[73]; + } else { + characterScreenWidths[32] = characterScreenWidths[105]; + } + } + + public void drawStringMoveY(String string, int drawX, int drawY, int color, + int shadow, int randomMod, int randomMod2) { + if (string != null) { + setColorAndShadow(color, shadow); + double d = 7.0 - (double) randomMod2 / 8.0; + if (d < 0.0) { + d = 0.0; + } + int[] yOffset = new int[string.length()]; + for (int index = 0; index < string.length(); index++) { + yOffset[index] = (int) (Math.sin((double) index / 1.5 + (double) randomMod) * d); + } + drawBaseStringMoveXY(string, drawX - getTextWidth(string) / 2, drawY, null, yOffset); + } + } + + public int getCharacterWidth(int i) { + return characterScreenWidths[i & 0xff]; + } + + public void setTrans(int i, int j, int k) { + textShadowColor = defaultShadow = i; + textColor = defaultColor = j; + transparency = defaultTransparency = k; + } + + public void drawCenteredString(String s, int i, int j) { + if(s != null) + drawBasicString(s, i - getTextWidth(s) / 2, j); + } + + public void setDefaultTextEffectValues(int color, int shadow, int trans) { + strikethroughColor = -1; + underlineColor = -1; + textShadowColor = defaultShadow = shadow; + textColor = defaultColor = color; + transparency = defaultTransparency = trans; + anInt4178 = 0; + anInt4175 = 0; + } + + public static int method1014(byte[][] is, byte[][] is_27_, int[] is_28_, + int[] is_29_, int[] is_30_, int i, + int i_31_) { + int i_32_ = is_28_[i]; + int i_33_ = i_32_ + is_30_[i]; + int i_34_ = is_28_[i_31_]; + int i_35_ = i_34_ + is_30_[i_31_]; + int i_36_ = i_32_; + if (i_34_ > i_32_) { + i_36_ = i_34_; + } + int i_37_ = i_33_; + if (i_35_ < i_33_) { + i_37_ = i_35_; + } + int i_38_ = is_29_[i]; + if (is_29_[i_31_] < i_38_) { + i_38_ = is_29_[i_31_]; + } + byte[] is_39_ = is_27_[i]; + byte[] is_40_ = is[i_31_]; + int i_41_ = i_36_ - i_32_; + int i_42_ = i_36_ - i_34_; + for (int i_43_ = i_36_; i_43_ < i_37_; i_43_++) { + int i_44_ = is_39_[i_41_++] + is_40_[i_42_++]; + if (i_44_ < i_38_) { + i_38_ = i_44_; + } + } + return -i_38_; + } + + public void drawCenteredStringMoveXY(String string, int drawX, int drawY, int color, + int shadow, int randomMod) { + if (string != null) { + setColorAndShadow(color, shadow); + int[] xMods = new int[string.length()]; + int[] yMods = new int[string.length()]; + for (int index = 0; index < string.length(); index++) { + xMods[index] = (int) (Math.sin((double) index / 5.0 + (double) randomMod / 5.0) * 5.0); + yMods[index] = (int) (Math.sin((double) index / 3.0 + (double) randomMod / 5.0) * 5.0); + } + drawBaseStringMoveXY(string, drawX - getTextWidth(string) / 2, drawY, xMods, + yMods); + } + } + + public void drawCenteredStringMoveY(String class100, int drawX, int drawY, int color, + int shadow, int i_54_) { + if (class100 != null) { + setColorAndShadow(color, shadow); + int[] yOffset = new int[class100.length()]; + for (int index = 0; index < class100.length(); index++) { + yOffset[index] = (int) (Math.sin((double) index / 2.0 + (double) i_54_ / 5.0) * 5.0); + } + drawBaseStringMoveXY(class100, drawX - getTextWidth(class100) / 2, drawY, null, + yOffset); + } + } + + public static void unpackImages(Sprite[] icons, Sprite[] clan) { + chatImages = icons; + clanImages = clan; + } + + public void drawBasicString(String string, int drawX, int drawY) { + drawY -= baseCharacterHeight; + int startIndex = -1; + string = handleOldSyntax(string); + for (int currentCharacter = 0; currentCharacter < string.length(); currentCharacter++) { + int character = string.charAt(currentCharacter); + if (character > 255) { + character = 32; + } + if (character == 60) { + startIndex = currentCharacter; + } else { + if (character == 62 && startIndex != -1) { + String effectString = string.substring(startIndex + 1, currentCharacter); + startIndex = -1; + if (effectString.equals(startEffect)) { + character = 60; + } else if (effectString.equals(endEffect)) { + character = 62; + } else if (effectString.equals(aRSString_4135)) { + character = 160; + } else if (effectString.equals(aRSString_4162)) { + character = 173; + } else if (effectString.equals(aRSString_4165)) { + character = 215; + } else if (effectString.equals(aRSString_4147)) { + character = 128; + } else if (effectString.equals(aRSString_4163)) { + character = 169; + } else if (effectString.equals(aRSString_4169)) { + character = 174; + } else { + if (effectString.startsWith(startImage)) { + try { + int imageId = Integer.valueOf(effectString.substring(4)); + Sprite chatImageId = chatImages[imageId]; + int iconModY = chatImageId.getMaxHeight(); + if (transparency == 256) { + chatImageId.method346(drawX, (drawY + baseCharacterHeight - iconModY)); + } else { + chatImageId.drawSprite(drawX,(drawY + baseCharacterHeight - iconModY), transparency); + } + drawX += chatImageId.getMaxWidth(); + } catch (Exception exception) { + /* empty */ + } + } else if (effectString.startsWith(startClanImage)) { + try { + int imageId = Integer.valueOf(effectString + .substring(5)); + Sprite icon = clanImages[imageId]; + int iconModY = icon.getMyHeight() + icon.getOffsetY() + + 1; + if (transparency == 256) { + icon.drawSprite(drawX, (drawY + + baseCharacterHeight - iconModY)); + } else { + icon.drawSprite(drawX, (drawY + + baseCharacterHeight - iconModY), + transparency); + } + drawX += 11; + } catch (Exception exception) { + exception.printStackTrace(); + } + } else { + setTextEffects(effectString); + } + continue; + } + } + if (startIndex == -1) { + int width = characterWidths[character]; + int height = characterHeights[character]; + if (character != 32) { + if (transparency == 256) { + if (textShadowColor != -1) { + drawCharacter(character, + drawX + characterDrawXOffsets[character] + 1, + drawY + characterDrawYOffsets[character] + 1, + width, height, textShadowColor, true); + } + drawCharacter(character, drawX + characterDrawXOffsets[character], + drawY + characterDrawYOffsets[character], width, + height, textColor, false); + } else { + if (textShadowColor != -1) { + drawTransparentCharacter(character, + drawX + characterDrawXOffsets[character] + 1, + drawY + characterDrawYOffsets[character] + 1, + width, height, textShadowColor, transparency, + true); + } + drawTransparentCharacter(character, drawX + characterDrawXOffsets[character], + drawY + characterDrawYOffsets[character], width, + height, textColor, transparency, false); + } + } else if (anInt4178 > 0) { + anInt4175 += anInt4178; + drawX += anInt4175 >> 8; + anInt4175 &= 0xff; + } + int lineWidth = characterScreenWidths[character]; + if (strikethroughColor != -1) { + GameFont.drawHorizontalLine(drawX, drawY + (int) ((double) baseCharacterHeight * 0.69999999999999996D), lineWidth, strikethroughColor); + } + if (underlineColor != -1) { + GameFont.drawHorizontalLine(drawX, drawY + baseCharacterHeight, lineWidth, underlineColor); + } + drawX += lineWidth; + } + } + } + } + + public void drawRAString(String string, int drawX, int drawY, int color, + int shadow) { + if (string != null) { + setColorAndShadow(color, shadow); + drawBasicString(string, drawX - getTextWidth(string), drawY); + } + } + + public void drawBaseStringMoveXY(String string, int drawX, int drawY, int[] xModifier, + int[] yModifier) { + drawY -= baseCharacterHeight; + int startIndex = -1; + int modifierOffset = 0; + for (int currentCharacter = 0; currentCharacter < string.length(); currentCharacter++) { + int character = string.charAt(currentCharacter); + if (character == 60) { + startIndex = currentCharacter; + } else { + if (character == 62 && startIndex != -1) { + String effectString = string.substring(startIndex + 1, currentCharacter); + startIndex = -1; + if (effectString.equals(startEffect)) { + character = 60; + } else if (effectString.equals(endEffect)) { + character = 62; + } else if (effectString.equals(aRSString_4135)) { + character = 160; + } else if (effectString.equals(aRSString_4162)) { + character = 173; + } else if (effectString.equals(aRSString_4165)) { + character = 215; + } else if (effectString.equals(aRSString_4147)) { + character = 128; + } else if (effectString.equals(aRSString_4163)) { + character = 169; + } else if (effectString.equals(aRSString_4169)) { + character = 174; + } else { + if (effectString.startsWith(startImage)) { + try { + int xModI; + if (xModifier != null) { + xModI = xModifier[modifierOffset]; + } else { + xModI = 0; + } + int yMod; + if (yModifier != null) { + yMod = yModifier[modifierOffset]; + } else { + yMod = 0; + } + modifierOffset++; + int iconId = Integer.valueOf(effectString.substring(4)); + Sprite class92 = chatImages[iconId]; + int iconOffsetY = class92.getMaxHeight(); + if (transparency == 256) { + class92.drawSprite(drawX + xModI, + (drawY + baseCharacterHeight - iconOffsetY + yMod)); + } else { + class92.drawSprite(drawX + xModI, + (drawY + baseCharacterHeight - iconOffsetY + yMod), + transparency); + } + drawX += class92.getMaxWidth(); + } catch (Exception exception) { + /* empty */ + } + } else { + setTextEffects(effectString); + } + continue; + } + } + if (startIndex == -1) { + int width = characterWidths[character]; + int height = characterHeights[character]; + int xOff; + if (xModifier != null) { + xOff = xModifier[modifierOffset]; + } else { + xOff = 0; + } + int yOff; + if (yModifier != null) { + yOff = yModifier[modifierOffset]; + } else { + yOff = 0; + } + modifierOffset++; + if (character != 32) { + if (transparency == 256) { + if (textShadowColor != -1) { + drawCharacter(character, + (drawX + characterDrawXOffsets[character] + 1 + xOff), + (drawY + characterDrawYOffsets[character] + 1 + yOff), + width, height, textShadowColor, true); + } + drawCharacter(character, + drawX + characterDrawXOffsets[character] + xOff, + drawY + characterDrawYOffsets[character] + yOff, + width, height, textColor, false); + } else { + if (textShadowColor != -1) { + drawTransparentCharacter(character, + (drawX + characterDrawXOffsets[character] + 1 + xOff), + (drawY + characterDrawYOffsets[character] + 1 + yOff), + width, height, textShadowColor, + transparency, true); + } + drawTransparentCharacter(character, + drawX + characterDrawXOffsets[character] + xOff, + drawY + characterDrawYOffsets[character] + yOff, + width, height, textColor, transparency, + false); + } + } else if (anInt4178 > 0) { + anInt4175 += anInt4178; + drawX += anInt4175 >> 8; + anInt4175 &= 0xff; + } + int i_109_ = characterScreenWidths[character]; + if (strikethroughColor != -1) { + GameFont.drawHorizontalLine(drawX, drawY + (int) ((double) baseCharacterHeight * 0.7), i_109_, strikethroughColor); + } + if (underlineColor != -1) { + GameFont.drawHorizontalLine(drawX, drawY + baseCharacterHeight, i_109_, underlineColor); + } + drawX += i_109_; + } + } + } + } + + public void setTextEffects(String string) { + do { + try { + if (string.startsWith(startColor)) { + String color = string.substring(4); + textColor = color.length() < 6 ? Color.decode(color).getRGB() : Integer.parseInt(color, 16); + } else if (string.equals(endColor)) { + textColor = defaultColor; + } else if (string.startsWith(startTransparency)) { + transparency = Integer.valueOf(string.substring(6)); + } else if (string.equals(endTransparency)) { + transparency = defaultTransparency; + } else if (string.startsWith(startStrikethrough)) { + strikethroughColor = Integer.valueOf(string.substring(4)); + } else if (string.equals(defaultStrikethrough)) { + strikethroughColor = 8388608; + } else if (string.equals(endStrikethrough)) { + strikethroughColor = -1; + } else if (string.startsWith(startUnderline)) { + underlineColor = Integer.valueOf(string.substring(2)); + } else if (string.equals(startDefaultUnderline)) { + underlineColor = 0; + } else if (string.equals(endUnderline)) { + underlineColor = -1; + } else if (string.startsWith(startShadow)) { + textShadowColor = Integer.valueOf(string.substring(5)); + } else if (string.equals(startDefaultShadow)) { + textShadowColor = 0; + } else if (string.equals(endShadow)) { + textShadowColor = defaultShadow; + } else { + if (!string.equals(lineBreak)) { + break; + } + setDefaultTextEffectValues(defaultColor, defaultShadow, defaultTransparency); + } + } catch (Exception exception) { + break; + } + break; + } while (false); + } + + public void setColorAndShadow(int color, int shadow) { + strikethroughColor = -1; + underlineColor = -1; + textShadowColor = defaultShadow = shadow; + textColor = defaultColor = color; + transparency = defaultTransparency = 256; + anInt4178 = 0; + anInt4175 = 0; + } + + public int getTextWidth(String string) { + if (string == null) { + return 0; + } + int startIndex = -1; + int finalWidth = 0; + for (int currentCharacter = 0; currentCharacter < string.length(); currentCharacter++) { + int character = string.charAt(currentCharacter); + if (character > 255) { + character = 32; + } + if (character == 60) { + startIndex = currentCharacter; + } else { + if (character == 62 && startIndex != -1) { + String effectString = string.substring(startIndex + 1, currentCharacter); + startIndex = -1; + if (effectString.equals(startEffect)) { + character = 60; + } else if (effectString.equals(endEffect)) { + character = 62; + } else if (effectString.equals(aRSString_4135)) { + character = 160; + } else if (effectString.equals(aRSString_4162)) { + character = 173; + } else if (effectString.equals(aRSString_4165)) { + character = 215; + } else if (effectString.equals(aRSString_4147)) { + character = 128; + } else if (effectString.equals(aRSString_4163)) { + character = 169; + } else if (effectString.equals(aRSString_4169)) { + character = 174; + } else { + if (effectString.startsWith(startImage)) { + try {//> 8; + i_7_ = 256 - i_7_; + for (int i_8_ = -i_4_; i_8_ < 0; i_8_++) { + for (int i_9_ = -i_3_; i_9_ < 0; i_9_++) { + if (is_0_[i_1_++] != 0) { + int i_10_ = is[i_2_]; + is[i_2_++] = ((((i_10_ & 0xff00ff) * i_7_ & ~0xff00ff) + ((i_10_ & 0xff00) * i_7_ & 0xff0000)) >> 8) + i; + } else { + i_2_++; + } + } + i_2_ += i_5_; + i_1_ += i_6_; + } + } + + public void drawTransparentCharacter(int i, int i_11_, int i_12_, int i_13_, int i_14_, + int i_15_, int i_16_, boolean bool) { + int i_17_ = i_11_ + i_12_ * Rasterizer2D.width; + int i_18_ = Rasterizer2D.width - i_13_; + int i_19_ = 0; + int i_20_ = 0; + if (i_12_ < Rasterizer2D.topY) { + int i_21_ = Rasterizer2D.topY - i_12_; + i_14_ -= i_21_; + i_12_ = Rasterizer2D.topY; + i_20_ += i_21_ * i_13_; + i_17_ += i_21_ * Rasterizer2D.width; + } + if (i_12_ + i_14_ > Rasterizer2D.bottomY) { + i_14_ -= i_12_ + i_14_ - Rasterizer2D.bottomY; + } + if (i_11_ < Rasterizer2D.leftX) { + int i_22_ = Rasterizer2D.leftX - i_11_; + i_13_ -= i_22_; + i_11_ = Rasterizer2D.leftX; + i_20_ += i_22_; + i_17_ += i_22_; + i_19_ += i_22_; + i_18_ += i_22_; + } + if (i_11_ + i_13_ > Rasterizer2D.bottomX) { + int i_23_ = i_11_ + i_13_ - Rasterizer2D.bottomX; + i_13_ -= i_23_; + i_19_ += i_23_; + i_18_ += i_23_; + } + if (i_13_ > 0 && i_14_ > 0) { + createTransparentCharacterPixels(Rasterizer2D.pixels, fontPixels[i], i_15_ ,i_20_, i_17_, i_13_, i_14_, i_18_, i_19_, i_16_); + } + } + + public static void createCharacterPixels(int[] is, byte[] is_24_, int i, int i_25_, + int i_26_, int i_27_, int i_28_, int i_29_, + int i_30_) { + int i_31_ = -(i_27_ >> 2); + i_27_ = -(i_27_ & 0x3); + for (int i_32_ = -i_28_; i_32_ < 0; i_32_++) { + for (int i_33_ = i_31_; i_33_ < 0; i_33_++) { + if (is_24_[i_25_++] != 0) { + is[i_26_++] = i; + } else { + i_26_++; + } + if (is_24_[i_25_++] != 0) { + is[i_26_++] = i; + } else { + i_26_++; + } + if (is_24_[i_25_++] != 0) { + is[i_26_++] = i; + } else { + i_26_++; + } + if (is_24_[i_25_++] != 0) { + is[i_26_++] = i; + } else { + i_26_++; + } + } + for (int i_34_ = i_27_; i_34_ < 0; i_34_++) { + if (is_24_[i_25_++] != 0) { + is[i_26_++] = i; + } else { + i_26_++; + } + } + i_26_ += i_29_; + i_25_ += i_30_; + } + } + + public static String handleOldSyntax(String text) { + text = text.replaceAll("@red@", ""); + text = text.replaceAll("@gre@", ""); + text = text.replaceAll("@blu@", ""); + text = text.replaceAll("@yel@", ""); + text = text.replaceAll("@cya@", ""); + text = text.replaceAll("@mag@", ""); + text = text.replaceAll("@whi@", ""); + text = text.replaceAll("@lre@", ""); + text = text.replaceAll("@dre@", ""); + text = text.replaceAll("@bla@", ""); + text = text.replaceAll("@or1@", ""); + text = text.replaceAll("@or2@", ""); + text = text.replaceAll("@or3@", ""); + text = text.replaceAll("@gr1@", ""); + text = text.replaceAll("@gr2@", ""); + text = text.replaceAll("@gr3@", ""); + text = text.replaceAll("@RED@", ""); + text = text.replaceAll("@GRE@", ""); + text = text.replaceAll("@BLU@", ""); + text = text.replaceAll("@YEL@", ""); + text = text.replaceAll("@CYA@", ""); + text = text.replaceAll("@MAG@", ""); + text = text.replaceAll("@WHI@", ""); + text = text.replaceAll("@LRE@", ""); + text = text.replaceAll("@DRE@", ""); + text = text.replaceAll("@BLA@", ""); + text = text.replaceAll("@OR1@", ""); + text = text.replaceAll("@OR2@", ""); + text = text.replaceAll("@OR3@", ""); + text = text.replaceAll("@GR1@", ""); + text = text.replaceAll("@GR2@", ""); + text = text.replaceAll("@GR3@", ""); + text = text.replaceAll("@cr1@", ""); + text = text.replaceAll("@cr2@", ""); + text = text.replaceAll("@cr3@", ""); + text = text.replaceAll("@cr4@", ""); + text = text.replaceAll("@cr5@", ""); + text = text.replaceAll("@cr6@", ""); + return text; + } + + public void drawCharacter(int character, int i_35_, int i_36_, int i_37_, int i_38_, + int i_39_, boolean bool) { + int i_40_ = i_35_ + i_36_ * Rasterizer2D.width; + int i_41_ = Rasterizer2D.width - i_37_; + int i_42_ = 0; + int i_43_ = 0; + if (i_36_ < Rasterizer2D.topY) { + int i_44_ = Rasterizer2D.topY - i_36_; + i_38_ -= i_44_; + i_36_ = Rasterizer2D.topY; + i_43_ += i_44_ * i_37_; + i_40_ += i_44_ * Rasterizer2D.width; + } + if (i_36_ + i_38_ > Rasterizer2D.bottomY) { + i_38_ -= i_36_ + i_38_ - Rasterizer2D.bottomY; + } + if (i_35_ < Rasterizer2D.leftX) { + int i_45_ = Rasterizer2D.leftX - i_35_; + i_37_ -= i_45_; + i_35_ = Rasterizer2D.leftX; + i_43_ += i_45_; + i_40_ += i_45_; + i_42_ += i_45_; + i_41_ += i_45_; + } + if (i_35_ + i_37_ > Rasterizer2D.bottomX) { + int i_46_ = i_35_ + i_37_ - Rasterizer2D.bottomX; + i_37_ -= i_46_; + i_42_ += i_46_; + i_41_ += i_46_; + } + if (i_37_ > 0 && i_38_ > 0) { + createCharacterPixels(Rasterizer2D.pixels, fontPixels[character], + i_39_, i_43_, i_40_, i_37_, i_38_, i_41_, i_42_); + + } + } + + static { + startTransparency = "trans="; + startStrikethrough = "str="; + startDefaultShadow = "shad"; + startColor = "col="; + lineBreak = "br"; + defaultStrikethrough = "str"; + endUnderline = "/u"; + startImage = "img="; + startClanImage = "clan="; + startShadow = "shad="; + startUnderline = "u="; + endColor = "/col"; + startDefaultUnderline = "u"; + endTransparency = "/trans"; + aRSString_4143 = Integer.toString(100); + aRSString_4135 = "nbsp"; + aRSString_4169 = "reg"; + aRSString_4165 = "times"; + aRSString_4162 = "shy"; + aRSString_4163 = "copy"; + endEffect = "gt"; + aRSString_4147 = "euro"; + startEffect = "lt"; + defaultTransparency = 256; + defaultShadow = -1; + anInt4175 = 0; + textShadowColor = -1; + textColor = 0; + defaultColor = 0; + strikethroughColor = -1; + splitTextStrings = new String[100]; + underlineColor = -1; + anInt4178 = 0; + transparency = 256; + } +} \ No newline at end of file diff --git a/src/main/java/net/rebotted/net/protocol/ProtocolConstants.java b/src/main/java/net/rebotted/net/protocol/ProtocolConstants.java new file mode 100644 index 0000000..32a24fb --- /dev/null +++ b/src/main/java/net/rebotted/net/protocol/ProtocolConstants.java @@ -0,0 +1,39 @@ +package net.rebotted.net.protocol; + +/** + * Class containing protocol-related constants. + * @author SeVen + */ +public class ProtocolConstants { + + /** + * Signifies a connection to the game server. + */ + public static final int GAME_SEVER_OPCODE = 14; + + /** + * The algorithm to encrypt to the login block. + */ + public static final int LOGIN_BLOCK_ENCRYPTION_KEY = (0x24 + 0x1 + 0x1 + 0x2); + + /** + * The magic number. + */ + public static final int MAGIC_NUMBER_OPCODE = 0xFF; + + /** + * Signifies a new connection. + */ + public static final int NEW_CONNECTION_OPCODE = 16; + + /** + * Signifies the return of an existing connection. + */ + public static final int RECONNECTION_OPCODE = 18; + + /** + * Signifies the client's protocol revision. + */ + public static final int PROTOCOL_REVISION = 317; + +} diff --git a/src/main/java/net/rebotted/scene/graphic/Fog.java b/src/main/java/net/rebotted/scene/graphic/Fog.java new file mode 100644 index 0000000..7f92799 --- /dev/null +++ b/src/main/java/net/rebotted/scene/graphic/Fog.java @@ -0,0 +1,61 @@ +package net.rebotted.scene.graphic; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.draw.Rasterizer3D; + +public class Fog { + /** + * Grabs distance from player. + */ + private float fogDistance; + + /** + * Sets the fog color. + */ + public static int setColor = 0xA7C5C7; + + /** + * + * @param fogStartDistance + * @param fogEndDistance + * @param fogIntensity + */ + public void renderFog(boolean belowGround, int fogStartDistance, int fogEndDistance, int fogIntensity) { + getColor(setColor); + int pos = Rasterizer3D.scanOffsets[0]; + int src, dst, alpha; + int fogBegin = (int) (fogStartDistance + fogDistance); + int fogEnd = (int) (fogEndDistance + fogDistance); + for (int y = 0; y < Rasterizer2D.bottomY; y++) { + for (int x = 0; x < Rasterizer2D.lastX; x++) { + if (Rasterizer2D.depthBuffer[pos] >= fogEnd) { + Rasterizer2D.pixels[pos] = setColor; + } else if (Rasterizer2D.depthBuffer[pos] >= fogBegin) { + alpha = (int)(Rasterizer2D.depthBuffer[pos] - fogBegin) / fogIntensity; + src = ((setColor & 0xff00ff) * alpha >> 8 & 0xff00ff) + ((setColor & 0xff00) * alpha >> 8 & 0xff00); + alpha = 256 - alpha; + dst = Rasterizer2D.pixels[pos]; + dst = ((dst & 0xff00ff) * alpha >> 8 & 0xff00ff) + ((dst & 0xff00) * alpha >> 8 & 0xff00); + Rasterizer2D.pixels[pos] = src + dst; + } + pos++; + } + pos += Rasterizer2D.width - Rasterizer2D.lastX; + } + } + + /** + * + * @param fogDistance + */ + public void setFogDistance(float fogDistance) { + this.fogDistance = fogDistance; + } + + /** + * + * @param fogColor + */ + public void getColor(int fogColor) { + setColor = fogColor; + } +} diff --git a/src/main/java/org/rebotted/Client.java b/src/main/java/org/rebotted/Client.java new file mode 100644 index 0000000..47ee5d4 --- /dev/null +++ b/src/main/java/org/rebotted/Client.java @@ -0,0 +1,13848 @@ +package org.rebotted; + +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.FileStore; +import org.rebotted.cache.FileStore.Store; +import org.rebotted.cache.anim.Animation; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.anim.Graphic; +import org.rebotted.cache.config.Varbit; +import org.rebotted.cache.config.Varp; +import org.rebotted.cache.def.FloorDefinition; +import org.rebotted.cache.def.ItemDefinition; +import org.rebotted.cache.def.NpcDefinition; +import org.rebotted.cache.def.ObjectDefinition; +import org.rebotted.cache.graphics.*; +import org.rebotted.cache.idk.IdentityKit; +import org.rebotted.collection.Deque; +import org.rebotted.collection.Linkable; +import org.rebotted.draw.ProducingGraphicsBuffer; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.draw.Rasterizer3D; +import org.rebotted.entity.*; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; +import org.rebotted.net.BufferedConnection; +import org.rebotted.net.IsaacCipher; +import org.rebotted.net.requester.Resource; +import org.rebotted.net.requester.ResourceProvider; +import org.rebotted.scene.*; +import org.rebotted.scene.object.GroundDecoration; +import org.rebotted.scene.object.SpawnedObject; +import org.rebotted.scene.object.WallDecoration; +import org.rebotted.scene.object.WallObject; +import org.rebotted.sign.SignLink; +import org.rebotted.sound.SoundConstants; +import org.rebotted.sound.SoundPlayer; +import org.rebotted.sound.Track; +import net.rebotted.cache.graphics.RSFont; +import net.rebotted.net.protocol.ProtocolConstants; +import net.rebotted.scene.graphic.Fog; +import org.rebotted.ui.themes.SubstanceDark; +import org.rebotted.ui.BotFrame; +import org.rebotted.util.*; + +import javax.imageio.ImageIO; +import javax.swing.*; +import java.applet.AppletContext; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.InetAddress; +import java.net.Socket; +import java.net.URL; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.zip.CRC32; + +public class Client extends GameApplet { + + public static final int[][] PLAYER_BODY_RECOLOURS = { + {6798, 107, 10283, 16, 4797, 7744, 5799, 4634, 33697, 22433, 2983, 54193}, + {8741, 12, 64030, 43162, 7735, 8404, 1701, 38430, 24094, 10153, 56621, 4783, 1341, 16578, 35003, 25239}, + {25238, 8742, 12, 64030, 43162, 7735, 8404, 1701, 38430, 24094, 10153, 56621, 4783, 1341, 16578, 35003}, + {4626, 11146, 6439, 12, 4758, 10270}, {4550, 4537, 5681, 5673, 5790, 6806, 8076, 4574}}; + public static final int[] tabInterfaceIDs = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1}; + public static final int[] anIntArray1204 = {9104, 10275, 7595, 3610, 7975, 8526, 918, 38802, 24466, 10145, 58654, + 5027, 1457, 16565, 34991, 25486}; + private static final long serialVersionUID = 5707517957054703648L; + private static final int[] SKILL_EXPERIENCE; + private static final String validUserPassChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"\243$%^&*()-_=+[{]};:'@#~,<.>/?\\| "; + public static ScreenMode frameMode = ScreenMode.FIXED; + public static int frameWidth = 765; + public static int frameHeight = 503; + public static int screenAreaWidth = 512; + public static int screenAreaHeight = 334; + public static int cameraZoom = 600; + public static boolean showChatComponents = true; + public static boolean showTabComponents = true; + public static boolean changeTabArea = frameMode != ScreenMode.FIXED; + public static boolean changeChatArea = frameMode != ScreenMode.FIXED; + public static boolean transparentTabArea = false; + public static Client instance; + public static int portOffset; + public static int anInt1089; + public static int spellId = 0; + public static int totalRead = 0; + public static Player localPlayer; + public static boolean loggedIn; + public static int tick; + public static boolean updateChatbox; + public static int[] BIT_MASKS; + public static int anInt1290; + public static String server = ""; + public static int[] fullScreenTextureArray; + static int openInterfaceId; + static int anInt1211; + static int tabId; + private static int anInt849; + private static int anInt854; + private static int anInt924; + private static int nodeID = 10; + private static boolean isMembers = true; + private static boolean lowMemory = false; + private static int anInt986; + private static int anInt1005; + private static int anInt1051; + private static int anInt1097; + private static boolean tabAreaAltered; + private static ProducingGraphicsBuffer loginBoxImageProducer; + private static int anInt1117; + private static int anInt1134; + private static int anInt1142; + private static int anInt1155; + private static boolean fpsOn; + private static ProducingGraphicsBuffer tabImageProducer; + private static ProducingGraphicsBuffer gameScreenImageProducer; + private static ProducingGraphicsBuffer chatboxImageProducer; + private static int anInt1175; + private static int[] anIntArray1180; + private static int[] anIntArray1181; + private static int[] anIntArray1182; + private static int anInt1188; + private static boolean flagged; + private static int anInt1226; + private static int anInt1288; + + static { + SKILL_EXPERIENCE = new int[99]; + int i = 0; + for (int j = 0; j < 99; j++) { + int l = j + 1; + int i1 = (int) ((double) l + 300D * Math.pow(2D, (double) l / 7D)); + i += i1; + SKILL_EXPERIENCE[j] = i / 4; + } + BIT_MASKS = new int[32]; + i = 2; + for (int k = 0; k < 32; k++) { + BIT_MASKS[k] = i - 1; + i += i; + } + } + public static BotFrame botFrame = null; + public final int[] // Perfected (Hp, pray and run orb) + orbX = {0, 0, 24}, orbY = {41, 85, 122}, orbTextX = {15, 16, 40}, orbTextY = {67, 111, 148}, + coloredOrbX = {27, 27, 51}, coloredOrbY = {45, 89, 126}, currentInterface = {4016, 4012, 149}, + maximumInterface = {4017, 4013, 149}, orbIconX = {33, 30, 58}, orbIconY = {51, 92, 130}; + public final FileStore[] indices; + public final Widget aClass9_1059; + public final int anInt1239 = 100; + private final int[] soundVolume; + private final int[] modeX = {164, 230, 296, 362}, modeNamesX = {26, 86, 150, 212, 286, 349, 427}, + modeNamesY = {158, 158, 153, 153, 153, 153, 158}, channelButtonsX = {5, 71, 137, 203, 269, 335, 404}; + private final String[] modeNames = {"All", "Game", "Public", "Private", "Clan", "Trade", "Report Abuse"}; + private final int[] hitmarks562 = {31, 32, 33, 34}; + private final int[] tabClickX = {38, 33, 33, 33, 33, 33, 38, 38, 33, 33, 33, 33, 33, 38}, + tabClickStart = {522, 560, 593, 625, 659, 692, 724, 522, 560, 593, 625, 659, 692, 724}, + tabClickY = {169, 169, 169, 169, 169, 169, 169, 466, 466, 466, 466, 466, 466, 466}; + private final int[] chatRights; + private final int[] currentExp; + private final int[] quakeMagnitudes; + private final boolean[] quakeDirectionActive; + private final int maxPlayers; + private final int internalLocalPlayerIndex; + private final int[] currentStats; + private final long[] ignoreListAsLongs; + private final int[] quake4PiOverPeriods; + private final int[] chatTypes; + private final String[] chatNames; + private final String[] chatMessages; + private final int[] anIntArray965 = {0xffff00, 0xff0000, 65280, 65535, 0xff00ff, 0xffffff}; + private final int[] anIntArray968; + private final int[] anIntArray969; + private final int anInt975; + private final int[] anIntArray976; + private final int[] anIntArray977; + private final int[] anIntArray978; + private final int[] anIntArray979; + private final int[] textColourEffect; + private final int[] anIntArray981; + private final int[] anIntArray982; + private final String[] aStringArray983; + private final int[] characterDesignColours; + private final boolean aBoolean994; + private final int[] quakeTimes; + private final int[] maximumLevels; + private final int[] anIntArray1045; + private final int[] minimapLeft; + private final int[] anIntArray1057; + private final int barFillColor; + private final int[] anIntArray1065; + private final int[] archiveCRCs; + private final String[] playerOptions; + private final boolean[] playerOptionsHighPriority; + private final int[][][] localRegions; + private final int[] objectGroups = {0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3}; + private final int[] quakeAmplitudes; + private final int[] tracks; + private final Sprite[] modIcons; + private final int[] minimapLineWidth; + private final int[] privateMessageIds; + private final int[] trackLoops; + private final int[] soundDelay; + private final boolean rsAlreadyLoaded; + public FileArchive mediaStreamLoader; + public boolean isPoisoned, clickedQuickPrayers; + public int digits = 0; + public int xpCounter, xpAddedPos, expAdded; + public int rights; + public String name; + public String defaultText; + public String clanname; + public int chatTypeView; + public int clanChatMode; + public int autoCastId = 0; + public String prayerBook; + public int localPlayerIndex; + public int anInt897; + public int[] settings; + public int anInt988; + public ResourceProvider resourceProvider; + public int regionX; + public int regionY; + public int anInt1132; + public int anInt1171; + public int anInt1210; + public int anInt1254; + public RSFont newSmallFont, newRegularFont, newBoldFont; + public RSFont newFancyFont; + public int anInt1279; + public int drawCount; + public int fullscreenInterfaceID; + public int anInt1044;// 377 + public int anInt1129;// 377 + public int anInt1315;// 377 + public int anInt1500;// 377 + public int anInt1501;// 377 + private Fog fog = new Fog(); + private int[][] xp_added = new int[10][3]; + private Sprite[] skill_sprites = new Sprite[SkillConstants.SKILL_COUNT]; + /** + * CRC32 is one of hash functions based on on the "polynomial" division + * idea. The CRC is acronym for Cyclic Redundancy Code (other variants + * instead "Code" is "Check" and "Checksum") algorithm. The number 32 is + * specifying the size of resulting hash value (checksum The value + * calculated from content of file. + */ + private CRC32 indexCrc = new CRC32(); + private int cButtonHPos; + private int cButtonCPos; + private int setChannel; + private int currentTrackTime; + private long trackTimer; + @SuppressWarnings("unused") + private int currentTrackLoop; + private int poisonType = 0; + private int specialOrb = 0; + private ProducingGraphicsBuffer loginScreenAccessories; + private int specialEnabled = 0; + private boolean runHover, prayHover, hpHover, prayClicked, specialHover, worldHover, autocast; + @SuppressWarnings("unused") + private int currentTrackPlaying; + private ProducingGraphicsBuffer leftFrame; + private ProducingGraphicsBuffer topFrame; + private int ignoreCount; + private long loadingStartTime; + private int[][] anIntArrayArray825; + private int[] friendsNodeIDs; + private Deque[][][] groundItems; + private int[] anIntArray828; + private int[] anIntArray829; + private volatile boolean aBoolean831; + private Socket jaggrab; + private int loginScreenState; + private Buffer chatBuffer; + private Npc[] npcs; + private int npcCount; + private int[] npcIndices; + private int removedMobCount; + private int[] removedMobs; + private int lastOpcode; + private int secondLastOpcode; + private int thirdLastOpcode; + private String clickToContinueString; + private int privateChatMode; + private Buffer login; + private boolean aBoolean848; + private int[] anIntArray850; + private int[] anIntArray851; + private int[] anIntArray852; + private int[] anIntArray853; + private int hintIconDrawType; + private int xCameraPos; + private int zCameraPos; + private int yCameraPos; + private int yCameraCurve; + private int xCameraCurve; + private int myPrivilege; + private Sprite mapFlag; + private Sprite mapMarker; + private int weight; + private MouseDetection mouseDetection; + private volatile boolean drawFlames; + private String reportAbuseInput; + private boolean menuOpen; + private int anInt886; + private String inputString; + private Player[] players; + private int playerCount; + private int[] playerList; + private int mobsAwaitingUpdateCount; + private int[] mobsAwaitingUpdate; + private Buffer[] playerSynchronizationBuffers; + private int cameraRotation; + private int friendsCount; + private int friendServerStatus; + private int[][] anIntArrayArray901; + private byte[] aByteArray912; + private int anInt913; + private int crossX; + private int crossY; + private int crossIndex; + private int crossType; + private int plane; + private boolean loadingError; + private int[][] anIntArrayArray929; + private Sprite aClass30_Sub2_Sub1_Sub1_931; + private Sprite aClass30_Sub2_Sub1_Sub1_932; + private int hintIconPlayerId; + private int hintIconX; + private int hintIconY; + private int hintIconLocationArrowHeight; + private int hintIconLocationArrowRelX; + private int hintIconLocationArrowRelY; + private int tickDelta; + private SceneGraph scene; + private Sprite[] sideIcons; + private int menuScreenArea; + private int menuOffsetX; + private int menuOffsetY; + private int menuWidth; + private int menuHeight; + private long aLong953; + private boolean aBoolean954; + private long[] friendsListAsLongs; + private String[] clanList = new String[100]; + private int currentSong; + private volatile boolean drawingFlames; + private int spriteDrawX; + private int spriteDrawY; + private IndexedImage titleBoxIndexedImage; + private IndexedImage titleButtonIndexedImage; + private boolean aBoolean972; + private int anInt984; + private int anInt985; + private Sprite[] hitMarks; + private int anInt989; + private int cinematicCamXViewpointLoc; + private int cinematicCamYViewpointLoc; + private int cinematicCamZViewpointLoc; + private int constCinematicCamRotationSpeed; + private int varCinematicCamRotationSpeedPromille; + private IsaacCipher encryption; + private Sprite multiOverlay; + private String amountOrNameInput; + private int daysSinceLastLogin; + private int packetSize; + private int opcode; + private int timeoutCounter; + private int anInt1010; + private int anInt1011; + private Deque projectiles; + private int anInt1014; + private int anInt1015; + private int anInt1016; + private boolean aBoolean1017; + private int openWalkableInterface; + private int minimapState; + private int duplicateClickCount; + private int loadingStage; + private Sprite scrollBar1; + private Sprite scrollBar2; + private int anInt1026; + private boolean aBoolean1031; + private Sprite[] mapFunctions; + private int regionBaseX; + private int regionBaseY; + private int previousAbsoluteX; + private int previousAbsoluteY; + private int loginFailures; + private int anInt1039; + private int anInt1040; + private int anInt1041; + private int dialogueId; + private int member; + private boolean maleCharacter; + private int anInt1048; + private String aString1049; + private FileArchive titleArchive; + private int flashingSidebarId; + private int multicombat; + private Deque incompleteAnimables; + private IndexedImage[] mapScenes; + private int trackCount; + private int friendsListAction; + private int mouseInvInterfaceIndex; + private int lastActiveInvInterface; + private int anInt1071; + private int[] minimapHintX; + private int[] minimapHintY; + private Sprite mapDotItem; + private Sprite mapDotNPC; + private Sprite mapDotPlayer; + private Sprite mapDotFriend; + private Sprite mapDotTeam; + private Sprite mapDotClan; + private int anInt1079; + private boolean validLocalMap; + private String[] friendsList; + private Buffer incoming; + private int anInt1084; + private int anInt1085; + private int activeInterfaceType; + private int anInt1087; + private int anInt1088; + private int[] firstMenuAction; + private int[] secondMenuAction; + private int[] menuActionTypes; + private int[] selectedMenuActions; + private Sprite[] headIcons; + private Sprite[] skullIcons; + private Sprite[] headIconsHint; + private int x; + private int y; + private int height; + private int speed; + private int angle; + private int systemUpdateTime; + private ProducingGraphicsBuffer topLeft1BackgroundTile; + private ProducingGraphicsBuffer bottomLeft1BackgroundTile; + private ProducingGraphicsBuffer flameLeftBackground; + private ProducingGraphicsBuffer flameRightBackground; + private ProducingGraphicsBuffer bottomLeft0BackgroundTile; + private ProducingGraphicsBuffer bottomRightImageProducer; + private ProducingGraphicsBuffer loginMusicImageProducer; + private ProducingGraphicsBuffer middleLeft1BackgroundTile; + private ProducingGraphicsBuffer aRSImageProducer_1115; + private int membersInt; + private String aString1121; + private Sprite compass; + private ProducingGraphicsBuffer chatSettingImageProducer; + private int cameraY; + private int menuActionRow; + private int spellSelected; + private int anInt1137; + private int spellUsableOn; + private String spellTooltip; + private Sprite[] minimapHint; + private boolean inPlayerOwnedHouse; + private int runEnergy = 100; + private boolean continuedDialogue; + private Sprite[] crosses; + private IndexedImage[] titleIndexedImages; + private int unreadMessages; + private boolean canMute; + private boolean constructedViewport; + private boolean oriented; + private ProducingGraphicsBuffer minimapImageProducer; + private int daysSinceRecovChange; + private BufferedConnection socketStream; + private int privateMessageCount; + private int minimapZoom; + private String myUsername; + private String myPassword; + private boolean genericLoadingError; + private int reportAbuseInterfaceID; + private Deque spawns; + private byte[][] localRegionMapData; + private int anInt1184; + private int cameraHorizontal; + private int anInt1186; + private int anInt1187; + private int overlayInterfaceId; + private int[] anIntArray1190; + private int[] anIntArray1191; + private Buffer outgoing; + private int anInt1193; + private int splitPrivateChat; + private IndexedImage mapBack; + private String[] menuActionText; + private Sprite flameLeftSprite; + private Sprite flameRightSprite; + private int minimapRotation; + private String promptInput; + private int anInt1213; + private int[][][] tileHeights; + private long serverSeed; + private int loginScreenCursorPos; + private long aLong1220; + private int hintIconNpcId; + private int inputDialogState; + private int nextSong; + private boolean fadeMusic; + private CollisionMap[] collisionMaps; + private int[] localRegionIds; + private int[] localRegionMapIds; + private int[] localRegionLandscapeIds; + private int anInt1237; + private int anInt1238; + private boolean aBoolean1242; + private int atInventoryLoopCycle; + private int atInventoryInterface; + private int atInventoryIndex; + private int atInventoryInterfaceType; + private byte[][] localRegionLandscapeData; + private int tradeMode; + private int anInt1249; + private int onTutorialIsland; + private int anInt1253; + private boolean welcomeScreenRaised; + private boolean messagePromptRaised; + private byte[][][] tileFlags; + private int prevSong; + private int destinationX; + private int destY; + private Sprite minimapImage; + private int anInt1264; + private int anInt1265; + private String firstLoginMessage; + private String secondLoginMessage; + private int localX; + private int localY; + private GameFont smallText; + private GameFont regularText; + private GameFont boldText; + private GameFont gameFont; + private int anInt1275; + private int backDialogueId; + private int cameraX; + private int[] bigX; + private int[] bigY; + private int itemSelected; + private int anInt1283; + private int anInt1284; + private int anInt1285; + private String selectedItemName; + private int publicChatMode; + public Client() { + xpAddedPos = xpCounter = expAdded = 0; + fullscreenInterfaceID = -1; + chatRights = new int[500]; + soundVolume = new int[50]; + chatTypeView = 0; + clanChatMode = 0; + cButtonHPos = -1; + currentTrackPlaying = -1; + cButtonCPos = 0; + server = Configuration.server_address; + anIntArrayArray825 = new int[104][104]; + friendsNodeIDs = new int[200]; + groundItems = new Deque[4][104][104]; + aBoolean831 = false; + chatBuffer = new Buffer(new byte[5000]); + npcs = new Npc[16384]; + npcIndices = new int[16384]; + removedMobs = new int[1000]; + login = Buffer.create(); + aBoolean848 = true; + openInterfaceId = -1; + currentExp = new int[SkillConstants.SKILL_COUNT]; + quakeMagnitudes = new int[5]; + quakeDirectionActive = new boolean[5]; + drawFlames = false; + reportAbuseInput = ""; + localPlayerIndex = -1; + menuOpen = false; + inputString = ""; + maxPlayers = 2048; + internalLocalPlayerIndex = 2047; + players = new Player[maxPlayers]; + playerList = new int[maxPlayers]; + mobsAwaitingUpdate = new int[maxPlayers]; + playerSynchronizationBuffers = new Buffer[maxPlayers]; + anInt897 = 1; + anIntArrayArray901 = new int[104][104]; + aByteArray912 = new byte[16384]; + currentStats = new int[SkillConstants.SKILL_COUNT]; + ignoreListAsLongs = new long[100]; + loadingError = false; + quake4PiOverPeriods = new int[5]; + anIntArrayArray929 = new int[104][104]; + chatTypes = new int[500]; + chatNames = new String[500]; + chatMessages = new String[500]; + sideIcons = new Sprite[15]; + aBoolean954 = true; + friendsListAsLongs = new long[200]; + currentSong = -1; + drawingFlames = false; + spriteDrawX = -1; + spriteDrawY = -1; + anIntArray968 = new int[33]; + anIntArray969 = new int[256]; + indices = new FileStore[5]; + settings = new int[2000]; + aBoolean972 = false; + anInt975 = 50; + anIntArray976 = new int[anInt975]; + anIntArray977 = new int[anInt975]; + anIntArray978 = new int[anInt975]; + anIntArray979 = new int[anInt975]; + textColourEffect = new int[anInt975]; + anIntArray981 = new int[anInt975]; + anIntArray982 = new int[anInt975]; + aStringArray983 = new String[anInt975]; + anInt985 = -1; + hitMarks = new Sprite[20]; + characterDesignColours = new int[5]; + aBoolean994 = false; + amountOrNameInput = ""; + projectiles = new Deque(); + aBoolean1017 = false; + openWalkableInterface = -1; + quakeTimes = new int[5]; + aBoolean1031 = false; + mapFunctions = new Sprite[100]; + dialogueId = -1; + maximumLevels = new int[SkillConstants.SKILL_COUNT]; + anIntArray1045 = new int[2000]; + maleCharacter = true; + minimapLeft = new int[152]; + minimapLineWidth = new int[152]; + flashingSidebarId = -1; + incompleteAnimables = new Deque(); + anIntArray1057 = new int[33]; + aClass9_1059 = new Widget(); + mapScenes = new IndexedImage[100]; + barFillColor = 0x4d4233; + anIntArray1065 = new int[7]; + minimapHintX = new int[1000]; + minimapHintY = new int[1000]; + validLocalMap = false; + friendsList = new String[200]; + incoming = Buffer.create(); + archiveCRCs = new int[9]; + firstMenuAction = new int[500]; + secondMenuAction = new int[500]; + menuActionTypes = new int[500]; + selectedMenuActions = new int[500]; + headIcons = new Sprite[20]; + skullIcons = new Sprite[20]; + headIconsHint = new Sprite[20]; + tabAreaAltered = false; + aString1121 = ""; + playerOptions = new String[5]; + playerOptionsHighPriority = new boolean[5]; + localRegions = new int[4][13][13]; + anInt1132 = 2; + minimapHint = new Sprite[1000]; + inPlayerOwnedHouse = false; + continuedDialogue = false; + crosses = new Sprite[8]; + Configuration.enableMusic = true; + loggedIn = false; + canMute = false; + constructedViewport = false; + oriented = false; + anInt1171 = 1; + myUsername = "packet"; + myPassword = ""; + genericLoadingError = false; + reportAbuseInterfaceID = -1; + spawns = new Deque(); + anInt1184 = 128; + overlayInterfaceId = -1; + outgoing = Buffer.create(); + menuActionText = new String[500]; + quakeAmplitudes = new int[5]; + tracks = new int[50]; + anInt1210 = 2; + anInt1211 = 78; + promptInput = ""; + modIcons = new Sprite[2]; + tabId = 3; + updateChatbox = false; + fadeMusic = true; + collisionMaps = new CollisionMap[4]; + privateMessageIds = new int[100]; + trackLoops = new int[50]; + aBoolean1242 = false; + soundDelay = new int[50]; + rsAlreadyLoaded = false; + welcomeScreenRaised = false; + messagePromptRaised = false; + firstLoginMessage = ""; + secondLoginMessage = ""; + backDialogueId = -1; + anInt1279 = 2; + bigX = new int[4000]; + bigY = new int[4000]; + } + + public static void frameMode(ScreenMode screenMode) { + if (frameMode != screenMode) { + frameMode = screenMode; + if (screenMode == ScreenMode.FIXED) { + frameWidth = 765; + frameHeight = 503; + cameraZoom = 600; + SceneGraph.viewDistance = 9; + changeChatArea = false; + changeTabArea = false; + } else if (screenMode == ScreenMode.RESIZABLE) { + frameWidth = 766; + frameHeight = 529; + cameraZoom = 850; + SceneGraph.viewDistance = 10; + } else if (screenMode == ScreenMode.FULLSCREEN) { + cameraZoom = 600; + SceneGraph.viewDistance = 10; + frameWidth = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth(); + frameHeight = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight(); + } + rebuildFrameSize(screenMode, frameWidth, frameHeight); + setBounds(); + System.out.println("ScreenMode: " + screenMode.toString()); + } + showChatComponents = screenMode == ScreenMode.FIXED || showChatComponents; + showTabComponents = screenMode == ScreenMode.FIXED || showTabComponents; + } + + public static void rebuildFrameSize(ScreenMode screenMode, int screenWidth, int screenHeight) { + try { + screenAreaWidth = (screenMode == ScreenMode.FIXED) ? 512 : screenWidth; + screenAreaHeight = (screenMode == ScreenMode.FIXED) ? 334 : screenHeight; + frameWidth = screenWidth; + frameHeight = screenHeight; + instance.refreshFrameSize(screenMode == ScreenMode.FULLSCREEN, screenWidth, screenHeight, + screenMode == ScreenMode.RESIZABLE, screenMode != ScreenMode.FIXED); + setBounds(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void setBounds() { + Rasterizer3D.reposition(frameWidth, frameHeight); + fullScreenTextureArray = Rasterizer3D.scanOffsets; + Rasterizer3D.reposition( + frameMode == ScreenMode.FIXED ? (chatboxImageProducer != null ? chatboxImageProducer.canvasWidth : 519) + : frameWidth, + frameMode == ScreenMode.FIXED ? (chatboxImageProducer != null ? chatboxImageProducer.canvasHeight : 165) + : frameHeight); + anIntArray1180 = Rasterizer3D.scanOffsets; + Rasterizer3D.reposition( + frameMode == ScreenMode.FIXED ? (tabImageProducer != null ? tabImageProducer.canvasWidth : 249) + : frameWidth, + frameMode == ScreenMode.FIXED ? (tabImageProducer != null ? tabImageProducer.canvasHeight : 335) + : frameHeight); + anIntArray1181 = Rasterizer3D.scanOffsets; + Rasterizer3D.reposition(screenAreaWidth, screenAreaHeight); + anIntArray1182 = Rasterizer3D.scanOffsets; + int[] ai = new int[9]; + for (int i8 = 0; i8 < 9; i8++) { + int k8 = 128 + i8 * 32 + 15; + int l8 = 600 + k8 * 3; + int i9 = Rasterizer3D.anIntArray1470[k8]; + ai[i8] = l8 * i9 >> 16; + } + if (frameMode == ScreenMode.RESIZABLE && (frameWidth >= 766) && (frameWidth <= 1025) && (frameHeight >= 504) + && (frameHeight <= 850)) { + SceneGraph.viewDistance = 9; + cameraZoom = 575; + } else if (frameMode == ScreenMode.FIXED) { + cameraZoom = 600; + } else if (frameMode == ScreenMode.RESIZABLE || frameMode == ScreenMode.FULLSCREEN) { + SceneGraph.viewDistance = 10; + cameraZoom = 600; + } + SceneGraph.setupViewport(500, 800, screenAreaWidth, screenAreaHeight, ai); + if (loggedIn) { + gameScreenImageProducer = new ProducingGraphicsBuffer(screenAreaWidth, screenAreaHeight); + } + } + + private static String intToKOrMilLongName(int i) { + String s = String.valueOf(i); + for (int k = s.length() - 3; k > 0; k -= 3) + s = s.substring(0, k) + "," + s.substring(k); + 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; + } + + public static final byte[] ReadFile(String fileName) { + try { + byte[] abyte0; + File file = new File(fileName); + int i = (int) file.length(); + abyte0 = new byte[i]; + DataInputStream datainputstream = new DataInputStream( + new BufferedInputStream(new FileInputStream(fileName))); + datainputstream.readFully(abyte0, 0, i); + datainputstream.close(); + return abyte0; + } catch (Exception e) { + System.out.println((new StringBuilder()).append("Read Error: ").append(fileName).toString()); + return null; + } + } + + public static String capitalize(String s) { + for (int i = 0; i < s.length(); i++) { + if (i == 0) { + s = String.format("%s%s", Character.toUpperCase(s.charAt(0)), s.substring(1)); + } + if (!Character.isLetterOrDigit(s.charAt(i))) { + if (i + 1 < s.length()) { + s = String.format("%s%s%s", s.subSequence(0, i + 1), Character.toUpperCase(s.charAt(i + 1)), + s.substring(i + 2)); + } + } + } + return s; + } + + public static String getFileNameWithoutExtension(String fileName) { + File tmpFile = new File(fileName); + tmpFile.getName(); + int whereDot = tmpFile.getName().lastIndexOf('.'); + if (0 < whereDot && whereDot <= tmpFile.getName().length() - 2) { + return tmpFile.getName().substring(0, whereDot); + } + return ""; + } + + public static AbstractMap.SimpleEntry getNextInteger(ArrayList values) { + ArrayList> frequencies = new ArrayList<>(); + int maxIndex = 0; + main: + for (int i = 0; i < values.size(); ++i) { + int value = values.get(i); + for (int j = 0; j < frequencies.size(); ++j) { + if (frequencies.get(j).getKey() == value) { + frequencies.get(j).setValue(frequencies.get(j).getValue() + 1); + if (frequencies.get(maxIndex).getValue() < frequencies.get(j).getValue()) { + maxIndex = j; + } + continue main; + } + } + frequencies.add(new AbstractMap.SimpleEntry(value, 1)); + } + return frequencies.get(maxIndex); + } + + private static String intToKOrMil(int j) { + if (j < 0x186a0) + return String.valueOf(j); + if (j < 0x989680) + return j / 1000 + "K"; + else + return j / 0xf4240 + "M"; + } + + private static void setHighMem() { + SceneGraph.lowMem = false; + Rasterizer3D.lowMem = false; + lowMemory = false; + MapRegion.lowMem = false; + ObjectDefinition.lowMemory = false; + } + + private static void setLowMem() { + SceneGraph.lowMem = true; + Rasterizer3D.lowMem = true; + lowMemory = true; + MapRegion.lowMem = true; + ObjectDefinition.lowMemory = true; + } + + + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + try { + JFrame.setDefaultLookAndFeelDecorated(true); + JPopupMenu.setDefaultLightWeightPopupEnabled(false); + ToolTipManager toolTipManager = ToolTipManager.sharedInstance(); + toolTipManager.setLightWeightPopupEnabled(false); + UIManager.setLookAndFeel(new SubstanceDark()); + nodeID = 10; + portOffset = 0; + setHighMem(); + isMembers = true; + SignLink.storeid = 32; + SignLink.startpriv(InetAddress.getLocalHost()); + frameMode(ScreenMode.FIXED); + instance = new Client(); + botFrame = new BotFrame(instance, false); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + + public static void setTab(int id) { + tabId = id; + tabAreaAltered = true; + } + + private static String combatDiffColor(int i, int j) { + int k = i - j; + if (k < -9) + return "@red@"; + if (k < -6) + return "@or3@"; + if (k < -3) + return "@or2@"; + if (k < 0) + return "@or1@"; + if (k > 9) + return "@gre@"; + if (k > 6) + return "@gr3@"; + if (k > 3) + return "@gr2@"; + if (k > 0) + return "@gr1@"; + else + return "@yel@"; + } + + private void addToXPCounter(int skill, int xp) { + int font_height = 24; + if (xp <= 0) + return; + + xpCounter += xp; + + int lowest_y_off = Integer.MAX_VALUE; + for (int i = 0; i < xp_added.length; i++) + if (xp_added[i][0] > -1) + lowest_y_off = Math.min(lowest_y_off, xp_added[i][2]); + + if (Configuration.xp_merge && lowest_y_off != Integer.MAX_VALUE && lowest_y_off <= 0) { + for (int i = 0; i < xp_added.length; i++) { + if (xp_added[i][2] != lowest_y_off) + continue; + + xp_added[i][0] |= (1 << skill); + xp_added[i][1] += xp; + return; + } + } else { + ArrayList list = new ArrayList(); + int y = font_height; + + boolean go_on = true; + while (go_on) { + go_on = false; + + for (int i = 0; i < xp_added.length; i++) { + if (xp_added[i][0] == -1 || list.contains(new Integer(i))) + continue; + + if (xp_added[i][2] < y) { + xp_added[i][2] = y; + y += font_height; + go_on = true; + list.add(new Integer(i)); + } + } + } + + if (lowest_y_off == Integer.MAX_VALUE || lowest_y_off >= font_height) + lowest_y_off = 0; + else + lowest_y_off = 0; + + for (int i = 0; i < xp_added.length; i++) + if (xp_added[i][0] == -1) { + xp_added[i][0] = (1 << skill); + xp_added[i][1] = xp; + xp_added[i][2] = lowest_y_off; + return; + } + } + System.out.println("Failed to add to exp counter."); + } + + public void refreshFrameSize() { + if (frameMode == ScreenMode.RESIZABLE) { + if (frameWidth != (appletClient() ? getGameComponent().getWidth() : botFrame.getHeight())) { + frameWidth = (appletClient() ? getGameComponent().getWidth() : botFrame.getWidth()); + screenAreaWidth = frameWidth; + setBounds(); + } + if (frameHeight != (appletClient() ? getGameComponent().getHeight() : botFrame.getHeight())) { + frameHeight = (appletClient() ? getGameComponent().getHeight() : botFrame.getWidth()); + screenAreaHeight = frameHeight; + setBounds(); + } + } + } + + public boolean getMousePositions() { + if (mouseInRegion(frameWidth - (frameWidth <= 1000 ? 240 : 420), frameHeight - (frameWidth <= 1000 ? 90 : 37), + frameWidth, frameHeight)) { + return false; + } + if (showChatComponents) { + if (changeChatArea) { + if (super.mouseX > 0 && super.mouseX < 494 && super.mouseY > frameHeight - 175 + && super.mouseY < frameHeight) { + return true; + } else { + if (super.mouseX > 494 && super.mouseX < 515 && super.mouseY > frameHeight - 175 + && super.mouseY < frameHeight) { + return false; + } + } + } else if (!changeChatArea) { + if (super.mouseX > 0 && super.mouseX < 519 && super.mouseY > frameHeight - 175 + && super.mouseY < frameHeight) { + return false; + } + } + } + if (mouseInRegion(frameWidth - 216, 0, frameWidth, 172)) { + return false; + } + if (!changeTabArea) { + if (super.mouseX > 0 && super.mouseY > 0 && super.mouseY < frameWidth && super.mouseY < frameHeight) { + return super.mouseX < frameWidth - 242 || super.mouseY < frameHeight - 335; + } + return false; + } + if (showTabComponents) { + if (frameWidth > 1000) { + return (super.mouseX < frameWidth - 420 || super.mouseX > frameWidth || super.mouseY < frameHeight - 37 + || super.mouseY > frameHeight) + && (super.mouseX <= frameWidth - 225 || super.mouseX >= frameWidth + || super.mouseY <= frameHeight - 37 - 274 || super.mouseY >= frameHeight); + } else { + return (super.mouseX < frameWidth - 210 || super.mouseX > frameWidth || super.mouseY < frameHeight - 74 + || super.mouseY > frameHeight) + && (super.mouseX <= frameWidth - 225 || super.mouseX >= frameWidth + || super.mouseY <= frameHeight - 74 - 274 || super.mouseY >= frameHeight); + } + } + return true; + } + + public boolean mouseInRegion(int x1, int y1, int x2, int y2) { + return super.mouseX >= x1 && super.mouseX <= x2 && super.mouseY >= y1 && super.mouseY <= y2; + } + + public boolean mouseMapPosition() { + return super.mouseX < frameWidth - 21 || super.mouseX > frameWidth || super.mouseY < 0 || super.mouseY > 21; + } + + private void drawLoadingMessages(int used, String s, String s1) { + int width = regularText.getTextWidth(used == 1 ? s : s1); + int height = s1 == null ? 25 : 38; + Rasterizer2D.drawBox(1, 1, width + 6, height, 0); + Rasterizer2D.drawBox(1, 1, width + 6, 1, 0xffffff); + Rasterizer2D.drawBox(1, 1, 1, height, 0xffffff); + Rasterizer2D.drawBox(1, height, width + 6, 1, 0xffffff); + Rasterizer2D.drawBox(width + 6, 1, 1, height, 0xffffff); + regularText.drawText(0xffffff, s, 18, width / 2 + 5); + if (s1 != null) { + regularText.drawText(0xffffff, s1, 31, width / 2 + 5); + } + } + + public final String formatCoins(int coins) { + if (coins >= 0 && coins < 10000) + return String.valueOf(coins); + if (coins >= 10000 && coins < 10000000) + return coins / 1000 + "K"; + if (coins >= 10000000 && coins < 999999999) + return coins / 1000000 + "M"; + if (coins >= 999999999) + return "*"; + else + return "?"; + } + + private boolean menuHasAddFriend(int j) { + if (j < 0) + return false; + int k = menuActionTypes[j]; + if (k >= 2000) + k -= 2000; + return k == 337; + } + + public void drawChannelButtons() { + final int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 165; + SpriteCache.lookup(49).drawSprite(0, 143 + yOffset); + String[] text = {"On", "Friends", "Off", "Hide"}; + int[] textColor = {65280, 0xffff00, 0xff0000, 65535}; + switch (cButtonCPos) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + SpriteCache.lookup(16).drawSprite(channelButtonsX[cButtonCPos], 143 + yOffset); + break; + } + if (cButtonHPos == cButtonCPos) { + switch (cButtonHPos) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + SpriteCache.lookup(17).drawSprite(channelButtonsX[cButtonHPos], 143 + yOffset); + break; + } + } else { + switch (cButtonHPos) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + SpriteCache.lookup(15).drawSprite(channelButtonsX[cButtonHPos], 143 + yOffset); + break; + case 6: + SpriteCache.lookup(18).drawSprite(channelButtonsX[cButtonHPos], 143 + yOffset); + break; + } + } + int[] modes = {publicChatMode, privateChatMode, clanChatMode, tradeMode}; + for (int i = 0; i < modeNamesX.length; i++) { + smallText.drawTextWithPotentialShadow(true, modeNamesX[i], 0xffffff, modeNames[i], modeNamesY[i] + yOffset); + } + for (int i = 0; i < modeX.length; i++) { + smallText.method382(textColor[modes[i]], modeX[i], text[modes[i]], 164 + yOffset, true); + } + } + + private boolean chatStateCheck() { + return messagePromptRaised || inputDialogState != 0 || clickToContinueString != null || backDialogueId != -1 + || dialogueId != -1; + } + + private void drawChatArea() { + int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 165; + if (frameMode == ScreenMode.FIXED) { + chatboxImageProducer.initDrawingArea(); + } + Rasterizer3D.scanOffsets = anIntArray1180; + if (chatStateCheck()) { + showChatComponents = true; + SpriteCache.lookup(20).drawSprite(0, yOffset); + } + if (showChatComponents) { + if (changeChatArea && !chatStateCheck()) { + Rasterizer2D.drawHorizontalLine(7, 7 + yOffset, 506, 0x575757); + Rasterizer2D.drawTransparentGradientBox(7, 7 + yOffset, 506, 135, 0, 0xFFFFFF, 20); + } else { + SpriteCache.lookup(20).drawSprite(0, yOffset); + } + } + if (!showChatComponents || changeChatArea) { + Rasterizer2D.drawTransparentBox(7, frameHeight - 23, 506, 24, 0, 100); + } + drawChannelButtons(); + GameFont font = regularText; + if (messagePromptRaised) { + newBoldFont.drawCenteredString(aString1121, 259, 60 + yOffset, 0, -1); + newBoldFont.drawCenteredString(promptInput + "*", 259, 80 + yOffset, 128, -1); + } else if (inputDialogState == 1) { + newBoldFont.drawCenteredString("Enter amount:", 259, yOffset + 60, 0, -1); + newBoldFont.drawCenteredString(amountOrNameInput + "*", 259, 80 + yOffset, 128, -1); + } else if (inputDialogState == 2) { + newBoldFont.drawCenteredString("Enter Name:", 259, 60 + yOffset, 0, -1); + newBoldFont.drawCenteredString(amountOrNameInput + "*", 259, 80 + yOffset, 128, -1); + } else if (clickToContinueString != null) { + newBoldFont.drawCenteredString(clickToContinueString, 259, 60 + yOffset, 0, -1); + newBoldFont.drawCenteredString("Click to continue", 259, 80 + yOffset, 128, -1); + } else if (backDialogueId != -1) { + try { + drawInterface(0, 20, Widget.interfaceCache[backDialogueId], 20 + yOffset); + } catch (Exception ex) { + + } + } else if (dialogueId != -1) { + try { + drawInterface(0, 20, Widget.interfaceCache[dialogueId], 20 + yOffset); + } catch (Exception ex) { + + } + } else if (showChatComponents) { + int j77 = -3; + int j = 0; + int shadow = changeChatArea ? 0 : -1; + Rasterizer2D.setDrawingArea(122 + yOffset, 8, 497, 7 + yOffset); + for (int k = 0; k < 500; k++) { + if (chatMessages[k] != null) { + int chatType = chatTypes[k]; + int yPos = (70 - j77 * 14) + anInt1089 + 5; + String s1 = chatNames[k]; + byte data = 0; + if (s1 != null && s1.startsWith("@cr1@")) { + s1 = s1.substring(5); + data = 1; + } else if (s1 != null && s1.startsWith("@cr2@")) { + s1 = s1.substring(5); + data = 2; + } else if (s1 != null && s1.startsWith("@cr3@")) { + s1 = s1.substring(5); + data = 3; + } + if (chatType == 0) { + if (chatTypeView == 5 || chatTypeView == 0) { + newRegularFont.drawBasicString(chatMessages[k], 11, yPos + yOffset, + changeChatArea ? 0xFFFFFF : 0, shadow); + j++; + j77++; + } + } + if ((chatType == 1 || chatType == 2) + && (chatType == 1 || publicChatMode == 0 || publicChatMode == 1 && isFriendOrSelf(s1))) { + if (chatTypeView == 1 || chatTypeView == 0) { + int xPos = 11; + if (data == 1) { + modIcons[0].drawSprite(xPos + 1, yPos - 12 + yOffset); + xPos += 14; + } else if (data == 2) { + modIcons[1].drawSprite(xPos + 1, yPos - 12 + yOffset); + xPos += 14; + } else if (data == 3) { + modIcons[2].drawSprite(xPos + 1, yPos - 12 + yOffset); + xPos += 14; + } + newRegularFont.drawBasicString(s1 + ":", xPos, yPos + yOffset, + changeChatArea ? 0xFFFFFF : 0, shadow); + xPos += font.getTextWidth(s1) + 8; + newRegularFont.drawBasicString(chatMessages[k], xPos, yPos + yOffset, + changeChatArea ? 0x7FA9FF : 255, shadow); + j++; + j77++; + } + } + if ((chatType == 3 || chatType == 7) && (splitPrivateChat == 0 || chatTypeView == 2) + && (chatType == 7 || privateChatMode == 0 || privateChatMode == 1 && isFriendOrSelf(s1))) { + if (chatTypeView == 2 || chatTypeView == 0) { + int k1 = 11; + newRegularFont.drawBasicString("From", k1, yPos + yOffset, changeChatArea ? 0 : 0xFFFFFF, + shadow); + k1 += font.getTextWidth("From "); + if (data == 1) { + modIcons[0].drawSprite(k1, yPos - 12 + yOffset); + k1 += 12; + } else if (data == 2) { + modIcons[1].drawSprite(k1, yPos - 12 + yOffset); + k1 += 12; + } else if (data == 3) { + modIcons[2].drawSprite(k1, yPos - 12 + yOffset); + k1 += 12; + } + newRegularFont.drawBasicString(s1 + ":", k1, yPos + yOffset, changeChatArea ? 0xFFFFFF : 0, + shadow); + k1 += font.getTextWidth(s1) + 8; + newRegularFont.drawBasicString(chatMessages[k], k1, yPos + yOffset, 0x800080, shadow); + j++; + j77++; + } + } + if (chatType == 4 && (tradeMode == 0 || tradeMode == 1 && isFriendOrSelf(s1))) { + if (chatTypeView == 3 || chatTypeView == 0) { + newRegularFont.drawBasicString(s1 + " " + chatMessages[k], 11, yPos + yOffset, 0x800080, + shadow); + j++; + j77++; + } + } + if (chatType == 5 && splitPrivateChat == 0 && privateChatMode < 2) { + if (chatTypeView == 2 || chatTypeView == 0) { + newRegularFont.drawBasicString(s1 + " " + chatMessages[k], 11, yPos + yOffset, 0x800080, + shadow); + j++; + j77++; + } + } + if (chatType == 6 && (splitPrivateChat == 0 || chatTypeView == 2) && privateChatMode < 2) { + if (chatTypeView == 2 || chatTypeView == 0) { + newRegularFont.drawBasicString("To " + s1 + ":", 11, yPos + yOffset, + changeChatArea ? 0xFFFFFF : 0, shadow); + newRegularFont.drawBasicString(chatMessages[k], 15 + font.getTextWidth("To :" + s1), + yPos + yOffset, 0x800080, shadow); + j++; + j77++; + } + } + if (chatType == 8 && (tradeMode == 0 || tradeMode == 1 && isFriendOrSelf(s1))) { + if (chatTypeView == 3 || chatTypeView == 0) { + newRegularFont.drawBasicString(s1 + " " + chatMessages[k], 11, yPos + yOffset, 0x7e3200, + shadow); + j++; + j77++; + } + if (chatType == 11 && (clanChatMode == 0)) { + if (chatTypeView == 11) { + newRegularFont.drawBasicString(s1 + " " + chatMessages[k], 11, yPos + yOffset, 0x7e3200, + shadow); + j++; + j77++; + } + if (chatType == 12) { + newRegularFont.drawBasicString(chatMessages[k] + "", 11, yPos + yOffset, 0x7e3200, + shadow); + j++; + } + } + } + if (chatType == 16) { + int j2 = 40; + int clanNameWidth = font.getTextWidth(clanname); + if (chatTypeView == 11 || chatTypeView == 0) { + switch (chatRights[k]) { + case 1: + j2 += clanNameWidth; + modIcons[0].drawSprite(j2 - 18, yPos - 12 + yOffset); + j2 += 14; + break; + + case 2: + j2 += clanNameWidth; + modIcons[1].drawSprite(j2 - 18, yPos - 12 + yOffset); + j2 += 14; + break; + + case 3: + j2 += clanNameWidth; + modIcons[1].drawSprite(j2 - 18, yPos - 12 + yOffset); + j2 += 14; + break; + + default: + j2 += clanNameWidth; + break; + } + newRegularFont.drawBasicString("[", 8, yPos + yOffset, changeChatArea ? 0xFFFFFF : 0, + shadow); + newRegularFont.drawBasicString(clanname, 14, yPos + yOffset, + changeChatArea ? 0x7FA9FF : 255, shadow); + newRegularFont.drawBasicString("]", clanNameWidth + 14, yPos + yOffset, + changeChatArea ? 0xFFFFFF : 0, shadow); + newRegularFont.drawBasicString(chatNames[k] + ":", j2 - 17, yPos + yOffset, + changeChatArea ? 0xFFFFFF : 0, shadow); + j2 += font.getTextWidth(chatNames[k]) + 7; + newRegularFont.drawBasicString(chatMessages[k], j2 - 16, yPos + yOffset, 0x800080, shadow); + j++; + j77++; + } + } + } + } + Rasterizer2D.defaultDrawingAreaSize(); + anInt1211 = j * 14 + 7 + 5; + if (anInt1211 < 111) { + anInt1211 = 111; + } + drawScrollbar(114, anInt1211 - anInt1089 - 113, 7 + yOffset, 496, anInt1211, changeChatArea); + String s; + if (localPlayer != null && localPlayer.name != null) { + s = localPlayer.name; + } else { + s = StringUtils.formatUsername(capitalize(myUsername)); + } + Rasterizer2D.setDrawingArea(140 + yOffset, 8, 509, 120 + yOffset); + int xOffset = 0; + if (myPrivilege > 0) { + modIcons[myPrivilege - 1].drawSprite(10, 122 + yOffset); + xOffset += 14; + } + newRegularFont.drawBasicString(s + ":", xOffset + 11, 133 + yOffset, changeChatArea ? 0xFFFFFF : 0, shadow); + newRegularFont.drawBasicString(inputString + "*", xOffset + 12 + font.getTextWidth(s + ": "), 133 + yOffset, + changeChatArea ? 0x7FA9FF : 255, shadow); + Rasterizer2D.drawHorizontalLine(7, 121 + yOffset, 506, changeChatArea ? 0x575757 : 0x807660); + Rasterizer2D.defaultDrawingAreaSize(); + } + if (menuOpen) { + drawMenu(0, frameMode == ScreenMode.FIXED ? 338 : 0); + } + if (frameMode == ScreenMode.FIXED) { + chatboxImageProducer.drawGraphics(338, super.graphics, 0); + } + gameScreenImageProducer.initDrawingArea(); + Rasterizer3D.scanOffsets = anIntArray1182; + } + + /** + * Initializes the client for startup + */ + public void initialize() { + try { + nodeID = 10; + portOffset = 0; + setHighMem(); + isMembers = true; + SignLink.storeid = 32; + SignLink.startpriv(InetAddress.getLocalHost()); + initClientFrame(frameWidth, frameHeight); + instance = this; + } catch (Exception exception) { + return; + } + } + + public void startRunnable(Runnable runnable, int priority) { + if (priority > 10) + priority = 10; + if (SignLink.mainapp != null) { + SignLink.startthread(runnable, priority); + } else { + super.startRunnable(runnable, priority); + } + } + + public Socket openSocket(int port) throws IOException { + return new Socket(InetAddress.getByName(server), port); + } + + private void processMenuClick() { + if (activeInterfaceType != 0) + return; + int j = super.clickMode3; + if (spellSelected == 1 && super.saveClickX >= 516 && super.saveClickY >= 160 && super.saveClickX <= 765 + && super.saveClickY <= 205) + j = 0; + if (menuOpen) { + if (j != 1) { + int k = super.mouseX; + int j1 = super.mouseY; + if (menuScreenArea == 0) { + k -= 4; + j1 -= 4; + } + if (menuScreenArea == 1) { + k -= 519; + j1 -= 168; + } + if (menuScreenArea == 2) { + k -= 17; + j1 -= 338; + } + if (menuScreenArea == 3) { + k -= 519; + j1 -= 0; + } + if (k < menuOffsetX - 10 || k > menuOffsetX + menuWidth + 10 || j1 < menuOffsetY - 10 + || j1 > menuOffsetY + menuHeight + 10) { + menuOpen = false; + if (menuScreenArea == 1) { + } + if (menuScreenArea == 2) + updateChatbox = true; + } + } + if (j == 1) { + int l = menuOffsetX; + int k1 = menuOffsetY; + int i2 = menuWidth; + int k2 = super.saveClickX; + int l2 = super.saveClickY; + switch (menuScreenArea) { + case 0: + k2 -= 4; + l2 -= 4; + break; + case 1: + k2 -= 519; + l2 -= 168; + break; + case 2: + k2 -= 5; + l2 -= 338; + break; + case 3: + k2 -= 519; + l2 -= 0; + break; + } + int i3 = -1; + for (int j3 = 0; j3 < menuActionRow; j3++) { + int k3 = k1 + 31 + (menuActionRow - 1 - j3) * 15; + if (k2 > l && k2 < l + i2 && l2 > k3 - 13 && l2 < k3 + 3) + i3 = j3; + } + if (i3 != -1) + processMenuActions(i3); + menuOpen = false; + if (menuScreenArea == 1) { + } + if (menuScreenArea == 2) { + updateChatbox = true; + } + } + } else { + if (j == 1 && menuActionRow > 0) { + int i1 = menuActionTypes[menuActionRow - 1]; + if (i1 == 632 || i1 == 78 || i1 == 867 || i1 == 431 || i1 == 53 || i1 == 74 || i1 == 454 || i1 == 539 + || i1 == 493 || i1 == 847 || i1 == 447 || i1 == 1125) { + int l1 = firstMenuAction[menuActionRow - 1]; + int j2 = secondMenuAction[menuActionRow - 1]; + Widget class9 = Widget.interfaceCache[j2]; + if (class9.aBoolean259 || class9.replaceItems) { + aBoolean1242 = false; + anInt989 = 0; + anInt1084 = j2; + anInt1085 = l1; + activeInterfaceType = 2; + anInt1087 = super.saveClickX; + anInt1088 = super.saveClickY; + if (Widget.interfaceCache[j2].parent == openInterfaceId) + activeInterfaceType = 1; + if (Widget.interfaceCache[j2].parent == backDialogueId) + activeInterfaceType = 3; + return; + } + } + } + if (j == 1 && (anInt1253 == 1 || menuHasAddFriend(menuActionRow - 1)) && menuActionRow > 2) + j = 2; + if (j == 1 && menuActionRow > 0) + processMenuActions(menuActionRow - 1); + if (j == 2 && menuActionRow > 0) + determineMenuSize(); + processMainScreenClick(); + processTabClick(); + processChatModeClick(); + minimapHovers(); + } + } + + private void saveMidi(boolean flag, byte[] abyte0) { + SignLink.fadeMidi = flag ? 1 : 0; + SignLink.saveMidi(abyte0, abyte0.length); + } + + private void updateWorldObjects() { + try { + anInt985 = -1; + incompleteAnimables.clear(); + projectiles.clear(); + Rasterizer3D.clearTextureCache(); + unlinkCaches(); + scene.initToNull(); + System.gc(); + for (int i = 0; i < 4; i++) + collisionMaps[i].initialize(); + for (int l = 0; l < 4; l++) { + for (int k1 = 0; k1 < 104; k1++) { + for (int j2 = 0; j2 < 104; j2++) + tileFlags[l][k1][j2] = 0; + } + } + + MapRegion objectManager = new MapRegion(tileFlags, tileHeights); + int k2 = localRegionMapData.length; + outgoing.writeOpcode(PacketConstants.IDLE); + if (!constructedViewport) { + for (int i3 = 0; i3 < k2; i3++) { + int i4 = (localRegionIds[i3] >> 8) * 64 - regionBaseX; + int k5 = (localRegionIds[i3] & 0xff) * 64 - regionBaseY; + byte[] abyte0 = localRegionMapData[i3]; + if (abyte0 != null) + objectManager.method180(abyte0, k5, i4, (this.regionX - 6) * 8, (this.regionY - 6) * 8, + collisionMaps); + } + for (int j4 = 0; j4 < k2; j4++) { + int l5 = (localRegionIds[j4] >> 8) * 64 - regionBaseX; + int k7 = (localRegionIds[j4] & 0xff) * 64 - regionBaseY; + byte[] abyte2 = localRegionMapData[j4]; + if (abyte2 == null && this.regionY < 800) + objectManager.initiateVertexHeights(k7, 64, 64, l5); + } + anInt1097++; + if (anInt1097 > 160) { + anInt1097 = 0; + // TODO anticheat? + outgoing.writeOpcode(238); + outgoing.writeByte(96); + } + outgoing.writeOpcode(PacketConstants.IDLE); + for (int i6 = 0; i6 < k2; i6++) { + byte[] abyte1 = localRegionLandscapeData[i6]; + if (abyte1 != null) { + int l8 = (localRegionIds[i6] >> 8) * 64 - regionBaseX; + int k9 = (localRegionIds[i6] & 0xff) * 64 - regionBaseY; + objectManager.method190(l8, collisionMaps, k9, scene, abyte1); + } + } + + } + if (constructedViewport) { + for (int j3 = 0; j3 < 4; j3++) { + for (int k4 = 0; k4 < 13; k4++) { + for (int j6 = 0; j6 < 13; j6++) { + int l7 = localRegions[j3][k4][j6]; + if (l7 != -1) { + int i9 = l7 >> 24 & 3; + int l9 = l7 >> 1 & 3; + int j10 = l7 >> 14 & 0x3ff; + int l10 = l7 >> 3 & 0x7ff; + int j11 = (j10 / 8 << 8) + l10 / 8; + for (int l11 = 0; l11 < localRegionIds.length; l11++) { + if (localRegionIds[l11] != j11 || localRegionMapData[l11] == null) + continue; + objectManager.method179(i9, l9, collisionMaps, k4 * 8, (j10 & 7) * 8, + localRegionMapData[l11], (l10 & 7) * 8, j3, j6 * 8); + break; + } + + } + } + } + } + for (int l4 = 0; l4 < 13; l4++) { + for (int k6 = 0; k6 < 13; k6++) { + int i8 = localRegions[0][l4][k6]; + if (i8 == -1) + objectManager.initiateVertexHeights(k6 * 8, 8, 8, l4 * 8); + } + } + + outgoing.writeOpcode(PacketConstants.IDLE); + for (int l6 = 0; l6 < 4; l6++) { + for (int j8 = 0; j8 < 13; j8++) { + for (int j9 = 0; j9 < 13; j9++) { + int i10 = localRegions[l6][j8][j9]; + if (i10 != -1) { + int k10 = i10 >> 24 & 3; + int i11 = i10 >> 1 & 3; + int k11 = i10 >> 14 & 0x3ff; + int i12 = i10 >> 3 & 0x7ff; + int j12 = (k11 / 8 << 8) + i12 / 8; + for (int k12 = 0; k12 < localRegionIds.length; k12++) { + if (localRegionIds[k12] != j12 || localRegionLandscapeData[k12] == null) + continue; + objectManager.method183(collisionMaps, scene, k10, j8 * 8, (i12 & 7) * 8, l6, + localRegionLandscapeData[k12], (k11 & 7) * 8, i11, j9 * 8); + break; + } + + } + } + + } + + } + + } + outgoing.writeOpcode(PacketConstants.IDLE); + objectManager.createRegionScene(collisionMaps, scene); + gameScreenImageProducer.initDrawingArea(); + outgoing.writeOpcode(PacketConstants.IDLE); + int k3 = MapRegion.maximumPlane; + if (k3 > plane) + k3 = plane; + if (k3 < plane - 1) + k3 = plane - 1; + if (lowMemory) + scene.method275(MapRegion.maximumPlane); + else + scene.method275(0); + for (int i5 = 0; i5 < 104; i5++) { + for (int i7 = 0; i7 < 104; i7++) + updateGroundItems(i5, i7); + + } + + anInt1051++; + if (anInt1051 > 98) { + anInt1051 = 0; + // TODO anticheat? + outgoing.writeOpcode(150); + } + method63(); + } catch (Exception exception) { + } + ObjectDefinition.baseModels.clear(); + if (botFrame != null) { + // TODO region change? region id as payload? + outgoing.writeOpcode(PacketConstants.ENTER_REGION); + outgoing.writeInt(0x3f008edd); + } + if (lowMemory && SignLink.cache_dat != null) { + int j = resourceProvider.getVersionCount(0); + for (int i1 = 0; i1 < j; i1++) { + int l1 = resourceProvider.getModelIndex(i1); + if ((l1 & 0x79) == 0) + Model.method461(i1); + } + + } + System.gc(); + Rasterizer3D.initiateRequestBuffers(); + resourceProvider.clearExtras(); + int k = (this.regionX - 6) / 8 - 1; + int j1 = (this.regionX + 6) / 8 + 1; + int i2 = (this.regionY - 6) / 8 - 1; + int l2 = (this.regionY + 6) / 8 + 1; + if (inPlayerOwnedHouse) { + k = 49; + j1 = 50; + i2 = 49; + l2 = 50; + } + for (int l3 = k; l3 <= j1; l3++) { + for (int j5 = i2; j5 <= l2; j5++) + if (l3 == k || l3 == j1 || j5 == i2 || j5 == l2) { + int j7 = resourceProvider.resolve(0, j5, l3); + if (j7 != -1) + resourceProvider.loadExtra(j7, 3); + int k8 = resourceProvider.resolve(1, j5, l3); + if (k8 != -1) + resourceProvider.loadExtra(k8, 3); + } + + } + + } + + private void unlinkCaches() { + ObjectDefinition.baseModels.clear(); + ObjectDefinition.models.clear(); + NpcDefinition.modelCache.clear(); + ItemDefinition.models.clear(); + ItemDefinition.sprites.clear(); + Player.models.clear(); + Graphic.models.clear(); + } + + private void renderMapScene(int plane) { + int[] pixels = minimapImage.getMyPixels(); + int length = pixels.length; + + for (int pixel = 0; pixel < length; pixel++) { + pixels[pixel] = 0; + } + + for (int y = 1; y < 103; y++) { + int i1 = 24628 + (103 - y) * 512 * 4; + for (int x = 1; x < 103; x++) { + if ((tileFlags[plane][x][y] & 0x18) == 0) + scene.drawTileOnMinimapSprite(pixels, i1, plane, x, y); + if (plane < 3 && (tileFlags[plane + 1][x][y] & 8) != 0) + scene.drawTileOnMinimapSprite(pixels, i1, plane + 1, x, y); + i1 += 4; + } + + } + + int j1 = 0xFFFFFF; + int l1 = 0xEE0000; + minimapImage.init(); + + for (int y = 1; y < 103; y++) { + for (int x = 1; x < 103; x++) { + if ((tileFlags[plane][x][y] & 0x18) == 0) + drawMapScenes(y, j1, x, l1, plane); + if (plane < 3 && (tileFlags[plane + 1][x][y] & 8) != 0) + drawMapScenes(y, j1, x, l1, plane + 1); + } + + } + + gameScreenImageProducer.initDrawingArea(); + anInt1071 = 0; + + for (int x = 0; x < 104; x++) { + for (int y = 0; y < 104; y++) { + int id = scene.getGroundDecorationUid(plane, x, y); + if (id != 0) { + id = id >> 14 & 0x7fff; + + int function = ObjectDefinition.lookup(id).minimapFunction; + + if (function >= 0) { + + int viewportX = x; + int viewportY = y; + if (function >= 15 && function <= 67) { + function -= 2; + } else if (function >= 68 && function <= 84) { + function -= 1; + } + minimapHint[anInt1071] = mapFunctions[function]; + minimapHintX[anInt1071] = viewportX; + minimapHintY[anInt1071] = viewportY; + anInt1071++; + + } + } + } + + } + + if (Configuration.dumpMapRegions) { + + File directory = new File("MapImageDumps/"); + if (!directory.exists()) { + directory.mkdir(); + } + BufferedImage bufferedimage = new BufferedImage(minimapImage.getMyWidth(), minimapImage.getMyHeight(), 1); + bufferedimage.setRGB(0, 0, minimapImage.getMyWidth(), minimapImage.getMyHeight(), + minimapImage.getMyPixels(), 0, minimapImage.getMyWidth()); + Graphics2D graphics2d = bufferedimage.createGraphics(); + graphics2d.dispose(); + try { + File file1 = new File("MapImageDumps/" + (directory.listFiles().length + 1) + ".png"); + ImageIO.write(bufferedimage, "png", file1); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + } + + private void updateGroundItems(int i, int j) { + Deque class19 = groundItems[plane][i][j]; + if (class19 == null) { + scene.removeGroundItemTile(plane, i, j); + return; + } + int k = 0xfa0a1f01; + Object obj = null; + for (Item item = (Item) class19.reverseGetFirst(); item != null; item = (Item) class19.reverseGetNext()) { + ItemDefinition itemDef = ItemDefinition.lookup(item.ID); + int l = itemDef.value; + if (itemDef.stackable) + l *= item.itemCount + 1; + // notifyItemSpawn(item, i + baseX, j + baseY); + + if (l > k) { + k = l; + obj = item; + } + } + + class19.insertTail(((Linkable) (obj))); + Object obj1 = null; + Object obj2 = null; + for (Item class30_sub2_sub4_sub2_1 = (Item) class19 + .reverseGetFirst(); class30_sub2_sub4_sub2_1 != null; class30_sub2_sub4_sub2_1 = (Item) class19 + .reverseGetNext()) { + if (class30_sub2_sub4_sub2_1.ID != ((Item) (obj)).ID && obj1 == null) + obj1 = class30_sub2_sub4_sub2_1; + if (class30_sub2_sub4_sub2_1.ID != ((Item) (obj)).ID && class30_sub2_sub4_sub2_1.ID != ((Item) (obj1)).ID + && obj2 == null) + obj2 = class30_sub2_sub4_sub2_1; + } + + int i1 = i + (j << 7) + 0x60000000; + scene.addGroundItemTile(i, i1, ((Renderable) (obj1)), getCenterHeight(plane, j * 128 + 64, i * 128 + 64), + ((Renderable) (obj2)), ((Renderable) (obj)), plane, j); + } + + private void showNPCs(boolean flag) { + for (int j = 0; j < npcCount; j++) { + Npc npc = npcs[npcIndices[j]]; + int k = 0x20000000 + (npcIndices[j] << 14); + if (npc == null || !npc.isVisible() || npc.desc.priorityRender != flag) + continue; + int l = npc.x >> 7; + int i1 = npc.y >> 7; + if (l < 0 || l >= 104 || i1 < 0 || i1 >= 104) + continue; + if (npc.size == 1 && (npc.x & 0x7f) == 64 && (npc.y & 0x7f) == 64) { + if (anIntArrayArray929[l][i1] == anInt1265) + continue; + anIntArrayArray929[l][i1] = anInt1265; + } + if (!npc.desc.clickable) + k += 0x80000000; + scene.addAnimableA(plane, npc.orientation, getCenterHeight(plane, npc.y, npc.x), k, npc.y, + (npc.size - 1) * 64 + 60, npc.x, npc, npc.animationStretches); + } + } + + public void drawHoverBox(int xPos, int yPos, String text) { + String[] results = text.split("\n"); + int height = (results.length * 16) + 6; + int width; + width = smallText.getTextWidth(results[0]) + 6; + for (int i = 1; i < results.length; i++) + if (width <= smallText.getTextWidth(results[i]) + 6) + width = smallText.getTextWidth(results[i]) + 6; + Rasterizer2D.drawBox(xPos, yPos, width, height, 0xFFFFA0); + Rasterizer2D.drawBoxOutline(xPos, yPos, width, height, 0); + yPos += 14; + for (int i = 0; i < results.length; i++) { + smallText.drawTextWithPotentialShadow(false, xPos + 3, 0, results[i], yPos); + yPos += 16; + } + } + + private void buildInterfaceMenu(int i, Widget widget, int k, int l, int i1, int j1) { + if (widget == null) + widget = Widget.interfaceCache[21356]; // newer prayer + if (widget.type != 0 || widget.children == null || widget.invisible) + return; + if (k < i || i1 < l || k > i + widget.width || i1 > l + widget.height) + return; + int size = widget.children.length; + for (int l1 = 0; l1 < size; l1++) { + int i2 = widget.childX[l1] + i; + int j2 = (widget.childY[l1] + l) - j1; + Widget childInterface = Widget.interfaceCache[widget.children[l1]]; + i2 += childInterface.x; + j2 += childInterface.anInt265; + if ((childInterface.hoverType >= 0 || childInterface.defaultHoverColor != 0) && k >= i2 && i1 >= j2 + && k < i2 + childInterface.width && i1 < j2 + childInterface.height) + if (childInterface.hoverType >= 0) + anInt886 = childInterface.hoverType; + else + anInt886 = childInterface.id; + if (childInterface.type == 8 && k >= i2 && i1 >= j2 && k < i2 + childInterface.width + && i1 < j2 + childInterface.height) { + anInt1315 = childInterface.id; + } + if (childInterface.type == Widget.TYPE_CONTAINER) { + buildInterfaceMenu(i2, childInterface, k, j2, i1, childInterface.scrollPosition); + if (childInterface.scrollMax > childInterface.height) + method65(i2 + childInterface.width, childInterface.height, k, i1, childInterface, j2, true, + childInterface.scrollMax); + } else { + if (childInterface.optionType == Widget.OPTION_OK && k >= i2 && i1 >= j2 + && k < i2 + childInterface.width && i1 < j2 + childInterface.height) { + boolean flag = false; + if (childInterface.contentType != 0) + flag = buildFriendsListMenu(childInterface); + if (!flag) { + menuActionText[menuActionRow] = childInterface.tooltip; + menuActionTypes[menuActionRow] = 315; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + } + if (childInterface.optionType == Widget.OPTION_USABLE && spellSelected == 0 && k >= i2 && i1 >= j2 + && k < i2 + childInterface.width && i1 < j2 + childInterface.height) { + String s = childInterface.selectedActionName; + if (s.indexOf(" ") != -1) + s = s.substring(0, s.indexOf(" ")); + if (childInterface.spellName.endsWith("Rush") || childInterface.spellName.endsWith("Burst") + || childInterface.spellName.endsWith("Blitz") + || childInterface.spellName.endsWith("Barrage") + || childInterface.spellName.endsWith("strike") || childInterface.spellName.endsWith("bolt") + || childInterface.spellName.equals("Crumble undead") + || childInterface.spellName.endsWith("blast") || childInterface.spellName.endsWith("wave") + || childInterface.spellName.equals("Claws of Guthix") + || childInterface.spellName.equals("Flames of Zamorak") + || childInterface.spellName.equals("Magic Dart")) { + menuActionText[menuActionRow] = "Autocast @gre@" + childInterface.spellName; + menuActionTypes[menuActionRow] = 104; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + menuActionText[menuActionRow] = s + " @gre@" + childInterface.spellName; + menuActionTypes[menuActionRow] = 626; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + if (childInterface.optionType == Widget.OPTION_CLOSE && k >= i2 && i1 >= j2 + && k < i2 + childInterface.width && i1 < j2 + childInterface.height) { + menuActionText[menuActionRow] = "Close"; + menuActionTypes[menuActionRow] = 200; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + if (childInterface.optionType == Widget.OPTION_TOGGLE_SETTING && k >= i2 && i1 >= j2 + && k < i2 + childInterface.width && i1 < j2 + childInterface.height) { + menuActionText[menuActionRow] = childInterface.tooltip; + menuActionTypes[menuActionRow] = 169; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + + if (childInterface.optionType == Widget.OPTION_RESET_SETTING && k >= i2 && i1 >= j2 + && k < i2 + childInterface.width && i1 < j2 + childInterface.height) { + menuActionText[menuActionRow] = childInterface.tooltip; + menuActionTypes[menuActionRow] = 646; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + + if (childInterface.optionType == Widget.OPTION_CONTINUE && !continuedDialogue && k >= i2 && i1 >= j2 + && k < i2 + childInterface.width && i1 < j2 + childInterface.height) { + menuActionText[menuActionRow] = childInterface.tooltip; + menuActionTypes[menuActionRow] = 679; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + + if (k >= i2 && i1 >= j2 && k < i2 + (childInterface.type == 4 ? 100 : childInterface.width) + && i1 < j2 + childInterface.height) { + if (childInterface.actions != null) { + if ((childInterface.type == 4 && childInterface.defaultText.length() > 0) + || childInterface.type == 5) { + for (int action = childInterface.actions.length - 1; action >= 0; action--) { + if (childInterface.actions[action] != null) { + menuActionText[menuActionRow] = childInterface.actions[action] + + (childInterface.type == 4 ? " " + childInterface.defaultText : ""); + menuActionTypes[menuActionRow] = 647; + firstMenuAction[menuActionRow] = action; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + } + } + } + } + + if (childInterface.type == Widget.TYPE_INVENTORY) { + int k2 = 0; + for (int l2 = 0; l2 < childInterface.height; l2++) { + for (int i3 = 0; i3 < childInterface.width; i3++) { + int j3 = i2 + i3 * (32 + childInterface.spritePaddingX); + int k3 = j2 + l2 * (32 + childInterface.spritePaddingY); + if (k2 < 20) { + j3 += childInterface.spritesX[k2]; + k3 += childInterface.spritesY[k2]; + } + if (k >= j3 && i1 >= k3 && k < j3 + 32 && i1 < k3 + 32) { + mouseInvInterfaceIndex = k2; + lastActiveInvInterface = childInterface.id; + if (childInterface.inventoryItemId[k2] > 0) { + ItemDefinition itemDef = ItemDefinition + .lookup(childInterface.inventoryItemId[k2] - 1); + if (itemSelected == 1 && childInterface.hasActions) { + if (childInterface.id != anInt1284 || k2 != anInt1283) { + menuActionText[menuActionRow] = "Use " + selectedItemName + " with @lre@" + + itemDef.name; + menuActionTypes[menuActionRow] = 870; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + } else if (spellSelected == 1 && childInterface.hasActions) { + if ((spellUsableOn & 0x10) == 16) { + menuActionText[menuActionRow] = spellTooltip + " @lre@" + itemDef.name; + menuActionTypes[menuActionRow] = 543; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + } else { + if (childInterface.hasActions) { + for (int l3 = 4; l3 >= 3; l3--) + if (itemDef.actions != null && itemDef.actions[l3] != null) { + menuActionText[menuActionRow] = itemDef.actions[l3] + " @lre@" + + itemDef.name; + if (l3 == 3) + menuActionTypes[menuActionRow] = 493; + if (l3 == 4) + menuActionTypes[menuActionRow] = 847; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } else if (l3 == 4) { + menuActionText[menuActionRow] = "Drop @lre@" + itemDef.name; + menuActionTypes[menuActionRow] = 847; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + } + if (childInterface.usableItems) { + menuActionText[menuActionRow] = "Use @lre@" + itemDef.name; + menuActionTypes[menuActionRow] = 447; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + if (childInterface.hasActions && itemDef.actions != null) { + for (int i4 = 2; i4 >= 0; i4--) + if (itemDef.actions[i4] != null) { + menuActionText[menuActionRow] = itemDef.actions[i4] + " @lre@" + + itemDef.name; + if (i4 == 0) + menuActionTypes[menuActionRow] = 74; + if (i4 == 1) + menuActionTypes[menuActionRow] = 454; + if (i4 == 2) + menuActionTypes[menuActionRow] = 539; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + + } + if (childInterface.actions != null) { + for (int type = 4; type >= 0; type--) + if (childInterface.actions[type] != null) { + menuActionText[menuActionRow] = childInterface.actions[type] + + " @lre@" + itemDef.name; + if (type == 0) + menuActionTypes[menuActionRow] = 632; + if (type == 1) + menuActionTypes[menuActionRow] = 78; + if (type == 2) + menuActionTypes[menuActionRow] = 867; + if (type == 3) + menuActionTypes[menuActionRow] = 431; + if (type == 4) + menuActionTypes[menuActionRow] = 53; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + + } + if (Configuration.enableIds && (myPrivilege >= 2 && myPrivilege <= 3)) { + menuActionText[menuActionRow] = "Examine @lre@" + itemDef.name + + " @gre@(@whi@" + (childInterface.inventoryItemId[k2] - 1) + + "@gre@)"; + } else { + menuActionText[menuActionRow] = "Examine @lre@" + itemDef.name; + } + menuActionTypes[menuActionRow] = 1125; + selectedMenuActions[menuActionRow] = itemDef.id; + firstMenuAction[menuActionRow] = k2; + secondMenuAction[menuActionRow] = childInterface.id; + menuActionRow++; + } + } + } + k2++; + } + } + } + } + } + } + + public void drawTransparentScrollBar(int x, int y, int height, int maxScroll, int pos) { + SpriteCache.lookup(29).drawARGBSprite(x, y, 120); + SpriteCache.lookup(30).drawARGBSprite(x, y + height - 16, 120); + Rasterizer2D.drawTransparentVerticalLine(x, y + 16, height - 32, 0xffffff, 64); + Rasterizer2D.drawTransparentVerticalLine(x + 15, y + 16, height - 32, 0xffffff, 64); + int barHeight = (height - 32) * height / maxScroll; + if (barHeight < 10) { + barHeight = 10; + } + int barPos = 0; + if (maxScroll != height) { + barPos = (height - 32 - barHeight) * pos / (maxScroll - height); + } + Rasterizer2D.drawTransparentBoxOutline(x, y + 16 + barPos, 16, + 5 + y + 16 + barPos + barHeight - 5 - (y + 16 + barPos), 0xffffff, 32); + } + + public void drawScrollbar(int height, int pos, int y, int x, int maxScroll, boolean transparent) { + if (transparent) { + drawTransparentScrollBar(x, y, height, maxScroll, pos); + } else { + scrollBar1.drawSprite(x, y); + scrollBar2.drawSprite(x, (y + height) - 16); + Rasterizer2D.drawBox(x, y + 16, 16, height - 32, 0x000001); + Rasterizer2D.drawBox(x, y + 16, 15, height - 32, 0x3d3426); + Rasterizer2D.drawBox(x, y + 16, 13, height - 32, 0x342d21); + Rasterizer2D.drawBox(x, y + 16, 11, height - 32, 0x2e281d); + Rasterizer2D.drawBox(x, y + 16, 10, height - 32, 0x29241b); + Rasterizer2D.drawBox(x, y + 16, 9, height - 32, 0x252019); + Rasterizer2D.drawBox(x, y + 16, 1, height - 32, 0x000001); + int k1 = ((height - 32) * height) / maxScroll; + if (k1 < 8) { + k1 = 8; + } + int l1 = ((height - 32 - k1) * pos) / (maxScroll - height); + Rasterizer2D.drawBox(x, y + 16 + l1, 16, k1, barFillColor); + Rasterizer2D.drawVerticalLine(x, y + 16 + l1, k1, 0x000001); + Rasterizer2D.drawVerticalLine(x + 1, y + 16 + l1, k1, 0x817051); + Rasterizer2D.drawVerticalLine(x + 2, y + 16 + l1, k1, 0x73654a); + Rasterizer2D.drawVerticalLine(x + 3, y + 16 + l1, k1, 0x6a5c43); + Rasterizer2D.drawVerticalLine(x + 4, y + 16 + l1, k1, 0x6a5c43); + Rasterizer2D.drawVerticalLine(x + 5, y + 16 + l1, k1, 0x655841); + Rasterizer2D.drawVerticalLine(x + 6, y + 16 + l1, k1, 0x655841); + Rasterizer2D.drawVerticalLine(x + 7, y + 16 + l1, k1, 0x61553e); + Rasterizer2D.drawVerticalLine(x + 8, y + 16 + l1, k1, 0x61553e); + Rasterizer2D.drawVerticalLine(x + 9, y + 16 + l1, k1, 0x5d513c); + Rasterizer2D.drawVerticalLine(x + 10, y + 16 + l1, k1, 0x5d513c); + Rasterizer2D.drawVerticalLine(x + 11, y + 16 + l1, k1, 0x594e3a); + Rasterizer2D.drawVerticalLine(x + 12, y + 16 + l1, k1, 0x594e3a); + Rasterizer2D.drawVerticalLine(x + 13, y + 16 + l1, k1, 0x514635); + Rasterizer2D.drawVerticalLine(x + 14, y + 16 + l1, k1, 0x4b4131); + Rasterizer2D.drawHorizontalLine(x, y + 16 + l1, 15, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 15, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 14, 0x655841); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 13, 0x6a5c43); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 11, 0x6d5f48); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 10, 0x73654a); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 7, 0x76684b); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 5, 0x7b6a4d); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 4, 0x7e6e50); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 3, 0x817051); + Rasterizer2D.drawHorizontalLine(x, y + 17 + l1, 2, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 16, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 15, 0x564b38); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 14, 0x5d513c); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 11, 0x625640); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 10, 0x655841); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 7, 0x6a5c43); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 5, 0x6e6046); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 4, 0x716247); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 3, 0x7b6a4d); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 2, 0x817051); + Rasterizer2D.drawHorizontalLine(x, y + 18 + l1, 1, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 16, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 15, 0x514635); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 14, 0x564b38); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 11, 0x5d513c); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 9, 0x61553e); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 7, 0x655841); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 5, 0x6a5c43); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 4, 0x6e6046); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 3, 0x73654a); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 2, 0x817051); + Rasterizer2D.drawHorizontalLine(x, y + 19 + l1, 1, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 16, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 15, 0x4b4131); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 14, 0x544936); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 13, 0x594e3a); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 10, 0x5d513c); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 8, 0x61553e); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 6, 0x655841); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 4, 0x6a5c43); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 3, 0x73654a); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 2, 0x817051); + Rasterizer2D.drawHorizontalLine(x, y + 20 + l1, 1, 0x000001); + Rasterizer2D.drawVerticalLine(x + 15, y + 16 + l1, k1, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 15 + l1 + k1, 16, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 15, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 14, 0x3f372a); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 10, 0x443c2d); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 9, 0x483e2f); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 7, 0x4a402f); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 4, 0x4b4131); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 3, 0x564b38); + Rasterizer2D.drawHorizontalLine(x, y + 14 + l1 + k1, 2, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 16, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 15, 0x443c2d); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 11, 0x4b4131); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 9, 0x514635); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 7, 0x544936); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 6, 0x564b38); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 4, 0x594e3a); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 3, 0x625640); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 2, 0x6a5c43); + Rasterizer2D.drawHorizontalLine(x, y + 13 + l1 + k1, 1, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 16, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 15, 0x443c2d); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 14, 0x4b4131); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 12, 0x544936); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 11, 0x564b38); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 10, 0x594e3a); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 7, 0x5d513c); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 4, 0x61553e); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 3, 0x6e6046); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 2, 0x7b6a4d); + Rasterizer2D.drawHorizontalLine(x, y + 12 + l1 + k1, 1, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 16, 0x000001); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 15, 0x4b4131); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 14, 0x514635); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 13, 0x564b38); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 11, 0x594e3a); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 9, 0x5d513c); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 7, 0x61553e); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 5, 0x655841); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 4, 0x6a5c43); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 3, 0x73654a); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 2, 0x7b6a4d); + Rasterizer2D.drawHorizontalLine(x, y + 11 + l1 + k1, 1, 0x000001); + } + } + + private void updateNPCs(Buffer stream, int i) { + removedMobCount = 0; + mobsAwaitingUpdateCount = 0; + method139(stream); + updateNPCMovement(i, stream); + npcUpdateMask(stream); + for (int k = 0; k < removedMobCount; k++) { + int l = removedMobs[k]; + if (npcs[l].time != tick) { + npcs[l].desc = null; + npcs[l] = null; + } + } + + if (stream.currentPosition != i) { + SignLink.reporterror( + myUsername + " size mismatch in getnpcpos - pos:" + stream.currentPosition + " psize:" + i); + throw new RuntimeException("eek"); + } + for (int i1 = 0; i1 < npcCount; i1++) + if (npcs[npcIndices[i1]] == null) { + SignLink.reporterror(myUsername + " null entry in npc list - pos:" + i1 + " size:" + npcCount); + throw new RuntimeException("eek"); + } + + } + + public void processChatModeClick() { + final int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 503; + if (super.mouseX >= 5 && super.mouseX <= 61 && super.mouseY >= yOffset + 482 && super.mouseY <= yOffset + 503) { + cButtonHPos = 0; + updateChatbox = true; + } else if (super.mouseX >= 71 && super.mouseX <= 127 && super.mouseY >= yOffset + 482 + && super.mouseY <= yOffset + 503) { + cButtonHPos = 1; + updateChatbox = true; + } else if (super.mouseX >= 137 && super.mouseX <= 193 && super.mouseY >= yOffset + 482 + && super.mouseY <= yOffset + 503) { + cButtonHPos = 2; + updateChatbox = true; + } else if (super.mouseX >= 203 && super.mouseX <= 259 && super.mouseY >= yOffset + 482 + && super.mouseY <= yOffset + 503) { + cButtonHPos = 3; + updateChatbox = true; + } else if (super.mouseX >= 269 && super.mouseX <= 325 && super.mouseY >= yOffset + 482 + && super.mouseY <= yOffset + 503) { + cButtonHPos = 4; + updateChatbox = true; + } else if (super.mouseX >= 335 && super.mouseX <= 391 && super.mouseY >= yOffset + 482 + && super.mouseY <= yOffset + 503) { + cButtonHPos = 5; + updateChatbox = true; + } else if (super.mouseX >= 404 && super.mouseX <= 515 && super.mouseY >= yOffset + 482 + && super.mouseY <= yOffset + 503) { + cButtonHPos = 6; + updateChatbox = true; + } else { + cButtonHPos = -1; + updateChatbox = true; + } + if (super.clickMode3 == 1) { + if (super.saveClickX >= 5 && super.saveClickX <= 61 && super.saveClickY >= yOffset + 482 + && super.saveClickY <= yOffset + 505) { + if (frameMode != ScreenMode.FIXED) { + if (setChannel != 0) { + cButtonCPos = 0; + chatTypeView = 0; + updateChatbox = true; + setChannel = 0; + } else { + showChatComponents = !showChatComponents; + } + } else { + cButtonCPos = 0; + chatTypeView = 0; + updateChatbox = true; + setChannel = 0; + } + } else if (super.saveClickX >= 71 && super.saveClickX <= 127 && super.saveClickY >= yOffset + 482 + && super.saveClickY <= yOffset + 505) { + if (frameMode != ScreenMode.FIXED) { + if (setChannel != 1 && frameMode != ScreenMode.FIXED) { + cButtonCPos = 1; + chatTypeView = 5; + updateChatbox = true; + setChannel = 1; + } else { + showChatComponents = !showChatComponents; + } + } else { + cButtonCPos = 1; + chatTypeView = 5; + updateChatbox = true; + setChannel = 1; + } + } else if (super.saveClickX >= 137 && super.saveClickX <= 193 && super.saveClickY >= yOffset + 482 + && super.saveClickY <= yOffset + 505) { + if (frameMode != ScreenMode.FIXED) { + if (setChannel != 2 && frameMode != ScreenMode.FIXED) { + cButtonCPos = 2; + chatTypeView = 1; + updateChatbox = true; + setChannel = 2; + } else { + showChatComponents = !showChatComponents; + } + } else { + cButtonCPos = 2; + chatTypeView = 1; + updateChatbox = true; + setChannel = 2; + } + } else if (super.saveClickX >= 203 && super.saveClickX <= 259 && super.saveClickY >= yOffset + 482 + && super.saveClickY <= yOffset + 505) { + if (frameMode != ScreenMode.FIXED) { + if (setChannel != 3 && frameMode != ScreenMode.FIXED) { + cButtonCPos = 3; + chatTypeView = 2; + updateChatbox = true; + setChannel = 3; + } else { + showChatComponents = !showChatComponents; + } + } else { + cButtonCPos = 3; + chatTypeView = 2; + updateChatbox = true; + setChannel = 3; + } + } else if (super.saveClickX >= 269 && super.saveClickX <= 325 && super.saveClickY >= yOffset + 482 + && super.saveClickY <= yOffset + 505) { + if (frameMode != ScreenMode.FIXED) { + if (setChannel != 4 && frameMode != ScreenMode.FIXED) { + cButtonCPos = 4; + chatTypeView = 11; + updateChatbox = true; + setChannel = 4; + } else { + showChatComponents = !showChatComponents; + } + } else { + cButtonCPos = 4; + chatTypeView = 11; + updateChatbox = true; + setChannel = 4; + } + } else if (super.saveClickX >= 335 && super.saveClickX <= 391 && super.saveClickY >= yOffset + 482 + && super.saveClickY <= yOffset + 505) { + if (frameMode != ScreenMode.FIXED) { + if (setChannel != 5 && frameMode != ScreenMode.FIXED) { + cButtonCPos = 5; + chatTypeView = 3; + updateChatbox = true; + setChannel = 5; + } else { + showChatComponents = !showChatComponents; + } + } else { + cButtonCPos = 5; + chatTypeView = 3; + updateChatbox = true; + setChannel = 5; + } + } else if (super.saveClickX >= 404 && super.saveClickX <= 515 && super.saveClickY >= yOffset + 482 + && super.saveClickY <= yOffset + 505) { + if (openInterfaceId == -1) { + clearTopInterfaces(); + reportAbuseInput = ""; + canMute = false; + for (int i = 0; i < Widget.interfaceCache.length; i++) { + if (Widget.interfaceCache[i] == null || Widget.interfaceCache[i].contentType != 600) { + continue; + } + reportAbuseInterfaceID = openInterfaceId = Widget.interfaceCache[i].parent; + break; + } + } else { + sendMessage("Please close the interface you have open before using 'report abuse'", 0, ""); + } + } + } + } + + private void updateVarp(int id) { + + + int parameter = Varp.variables[id].getActionId(); + if (parameter == 0) { + return; + } + + int state = settings[id]; + System.out.println("Updating varp: " + id + " - " + Varp.variables[id].actionId + " State: " + state); + if (parameter == 1) { + + if (state == 1) { + Rasterizer3D.setBrightness(0.9); + } + + if (state == 2) { + Rasterizer3D.setBrightness(0.8); + } + + if (state == 3) { + Rasterizer3D.setBrightness(0.7); + } + + if (state == 4) { + Rasterizer3D.setBrightness(0.6); + } + + ItemDefinition.sprites.clear(); + welcomeScreenRaised = true; + } + + if (parameter == 3) { + + boolean previousPlayingMusic = Configuration.enableMusic; + + if (state == 0) { + + if (SignLink.music != null) { + adjustVolume(Configuration.enableMusic, 500); + } + + Configuration.enableMusic = true; + } + if (state == 1) { + + if (SignLink.music != null) { + adjustVolume(Configuration.enableMusic, 300); + } + + Configuration.enableMusic = true; + } + if (state == 2) { + + if (SignLink.music != null) { + adjustVolume(Configuration.enableMusic, 100); + } + + Configuration.enableMusic = true; + } + if (state == 3) { + + if (SignLink.music != null) { + adjustVolume(Configuration.enableMusic, 0); + } + + Configuration.enableMusic = true; + } + if (state == 4) + Configuration.enableMusic = false; + if (Configuration.enableMusic != previousPlayingMusic && !lowMemory) { + if (Configuration.enableMusic) { + nextSong = currentSong; + fadeMusic = true; + resourceProvider.provide(2, nextSong); + } else { + stopMidi(); + } + prevSong = 0; + } + } + + if (parameter == 4) { + SoundPlayer.setVolume(state); + if (state == 0) { + aBoolean848 = true; + setWaveVolume(0); + } + if (state == 1) { + aBoolean848 = true; + setWaveVolume(-400); + } + if (state == 2) { + aBoolean848 = true; + setWaveVolume(-800); + } + if (state == 3) { + aBoolean848 = true; + setWaveVolume(-1200); + } + if (state == 4) + aBoolean848 = false; + } + + if (parameter == 5) { + anInt1253 = state; + } + + if (parameter == 6) { + anInt1249 = state; + } + + if (parameter == 8) { + splitPrivateChat = state; + updateChatbox = true; + } + + if (parameter == 9) { + anInt913 = state; + } + + } + + public void updateEntities() { + try { + int messageLength = 0; + for (int j = -1; j < playerCount + npcCount; j++) { + Object obj; + if (j == -1) + obj = localPlayer; + else if (j < playerCount) + obj = players[playerList[j]]; + else + obj = npcs[npcIndices[j - playerCount]]; + if (obj == null || !((Mob) (obj)).isVisible()) + continue; + if (obj instanceof Npc) { + NpcDefinition entityDef = ((Npc) obj).desc; + if (Configuration.namesAboveHeads) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height + 15); + smallText.drawText(0x0099FF, entityDef.name, spriteDrawY - 5, spriteDrawX); // -15 + // from + // original + } + if (entityDef.childrenIDs != null) + entityDef = entityDef.morph(); + if (entityDef == null) + continue; + } + if (j < playerCount) { + int l = 30; + Player player = (Player) obj; + if (player.headIcon >= 0) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height + 15); + if (spriteDrawX > -1) { + if (player.skullIcon < 2) { + skullIcons[player.skullIcon].drawSprite(spriteDrawX - 12, spriteDrawY - l); + l += 25; + } + if (player.headIcon < 13) { + headIcons[player.headIcon].drawSprite(spriteDrawX - 12, spriteDrawY - l); + l += 18; + } + } + } + if (j >= 0 && hintIconDrawType == 10 && hintIconPlayerId == playerList[j]) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height + 15); + if (spriteDrawX > -1) + headIconsHint[player.hintIcon].drawSprite(spriteDrawX - 12, spriteDrawY - l); + } + if (Configuration.hpAboveHeads && Configuration.namesAboveHeads) { + newSmallFont.drawCenteredString( + (new StringBuilder()).append(((Mob) obj).currentHealth).append("/") + .append(((Mob) obj).maxHealth).toString(), + spriteDrawX, spriteDrawY - 29, 0x3399ff, 100); + } // draws HP above head + else if (Configuration.hpAboveHeads && !Configuration.namesAboveHeads) { + newSmallFont.drawCenteredString( + (new StringBuilder()).append(((Mob) obj).currentHealth).append("/") + .append(((Mob) obj).maxHealth).toString(), + spriteDrawX, spriteDrawY - 5, 0x3399ff, 100); + } + if (Configuration.namesAboveHeads) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height + 15); + int col = 0x0000ff; + if (player.clanName == localPlayer.clanName) + col = 0x00ff00; + smallText.drawText(col, player.name, spriteDrawY - 15, spriteDrawX); + if (player.clanName != "") + smallText.drawText(col, "<" + player.clanName + ">", spriteDrawY - 5, spriteDrawX); + } + } else { + NpcDefinition entityDef_1 = ((Npc) obj).desc; + if (entityDef_1.headIcon >= 0 && entityDef_1.headIcon < headIcons.length) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height + 15); + if (spriteDrawX > -1) + headIcons[entityDef_1.headIcon].drawSprite(spriteDrawX - 12, spriteDrawY - 30); + } + if (hintIconDrawType == 1 && hintIconNpcId == npcIndices[j - playerCount] && tick % 20 < 10) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height + 15); + if (spriteDrawX > -1) + headIconsHint[0].drawSprite(spriteDrawX - 12, spriteDrawY - 28); + } + } + if (((Mob) (obj)).spokenText != null && (j >= playerCount || publicChatMode == 0 || publicChatMode == 3 + || publicChatMode == 1 && isFriendOrSelf(((Player) obj).name))) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height); + if (spriteDrawX > -1 && messageLength < anInt975) { + anIntArray979[messageLength] = boldText.method384(((Mob) (obj)).spokenText) / 2; + anIntArray978[messageLength] = boldText.verticalSpace; + anIntArray976[messageLength] = spriteDrawX; + anIntArray977[messageLength] = spriteDrawY; + textColourEffect[messageLength] = ((Mob) (obj)).textColour; + anIntArray981[messageLength] = ((Mob) (obj)).textEffect; + anIntArray982[messageLength] = ((Mob) (obj)).textCycle; + aStringArray983[messageLength++] = ((Mob) (obj)).spokenText; + if (anInt1249 == 0 && ((Mob) (obj)).textEffect >= 1 && ((Mob) (obj)).textEffect <= 3) { + anIntArray978[messageLength] += 10; + anIntArray977[messageLength] += 5; + } + if (anInt1249 == 0 && ((Mob) (obj)).textEffect == 4) + anIntArray979[messageLength] = 60; + if (anInt1249 == 0 && ((Mob) (obj)).textEffect == 5) + anIntArray978[messageLength] += 5; + } + } + if (((Mob) (obj)).loopCycleStatus > tick) { + try { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height + 15); + if (spriteDrawX > -1) { + int i1 = (((Mob) (obj)).currentHealth * 30) / ((Mob) (obj)).maxHealth; + + if (i1 > 30) { + i1 = 30; + } + int hpPercent = (((Mob) (obj)).currentHealth * 56) / ((Mob) (obj)).maxHealth; + + if (hpPercent > 56) { + hpPercent = 56; + } + if (!Configuration.hpBar554) { + Rasterizer2D.drawBox(spriteDrawX - 15, spriteDrawY - 3, i1, 5, 65280); + Rasterizer2D.drawBox((spriteDrawX - 15) + i1, spriteDrawY - 3, 30 - i1, 5, 0xff0000); + } else { + SpriteCache.lookup(41).drawSprite(spriteDrawX - 28, spriteDrawY - 3); + SpriteCache.set(40, new Sprite(SpriteCache.lookup(40), hpPercent, 7)); + SpriteCache.lookup(40).drawSprite(spriteDrawX - 28, spriteDrawY - 3); + } + } + } catch (Exception e) { + } + } + if (!Configuration.hitmarks554) { + for (int j1 = 0; j1 < 4; j1++) { + if (((Mob) (obj)).hitsLoopCycle[j1] > tick) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height / 2); + if (spriteDrawX > -1) { + if (j1 == 1) + spriteDrawY -= 20; + if (j1 == 2) { + spriteDrawX -= 15; + spriteDrawY -= 10; + } + if (j1 == 3) { + spriteDrawX += 15; + spriteDrawY -= 10; + } + hitMarks[((Mob) (obj)).hitMarkTypes[j1]].drawSprite(spriteDrawX - 12, spriteDrawY - 12); + + smallText.drawText(0, + Configuration.tenXHp ? String.valueOf(((Mob) (obj)).hitDamages[j1] * 10) + : String.valueOf(((Mob) (obj)).hitDamages[j1] * 1), + spriteDrawY + 4, spriteDrawX); + + smallText.drawText(0xffffff, + Configuration.tenXHp ? String.valueOf(((Mob) (obj)).hitDamages[j1] * 10) + : String.valueOf(((Mob) (obj)).hitDamages[j1] * 1), + spriteDrawY + 3, spriteDrawX - 1); + } + } + } + } else { + for (int j2 = 0; j2 < 4; j2++) { + if (((Mob) (obj)).hitsLoopCycle[j2] > tick) { + npcScreenPos(((Mob) (obj)), ((Mob) (obj)).height / 2); + if (spriteDrawX > -1) { + if (j2 == 0 && ((Mob) (obj)).hitDamages[j2] > 99) + ((Mob) (obj)).hitMarkTypes[j2] = 3; + else if (j2 == 1 && ((Mob) (obj)).hitDamages[j2] > 99) + ((Mob) (obj)).hitMarkTypes[j2] = 3; + else if (j2 == 2 && ((Mob) (obj)).hitDamages[j2] > 99) + ((Mob) (obj)).hitMarkTypes[j2] = 3; + else if (j2 == 3 && ((Mob) (obj)).hitDamages[j2] > 99) + ((Mob) (obj)).hitMarkTypes[j2] = 3; + if (j2 == 1) { + spriteDrawY -= 20; + } + if (j2 == 2) { + spriteDrawX -= (((Mob) (obj)).hitDamages[j2] > 99 ? 30 : 20); + spriteDrawY -= 10; + } + if (j2 == 3) { + spriteDrawX += (((Mob) (obj)).hitDamages[j2] > 99 ? 30 : 20); + spriteDrawY -= 10; + } + if (((Mob) (obj)).hitMarkTypes[j2] == 3) { + spriteDrawX -= 8; + } + SpriteCache.lookup(hitmarks562[((Mob) (obj)).hitMarkTypes[j2]]) + .draw24BitSprite(spriteDrawX - 12, spriteDrawY - 12); + smallText.drawText(0xffffff, String.valueOf(((Mob) (obj)).hitDamages[j2]), + spriteDrawY + 3, + (((Mob) (obj)).hitMarkTypes[j2] == 3 ? spriteDrawX + 7 : spriteDrawX - 1)); + } + } + } + } + } + for (int defaultText = 0; defaultText < messageLength; defaultText++) { + int k1 = anIntArray976[defaultText]; + int l1 = anIntArray977[defaultText]; + int j2 = anIntArray979[defaultText]; + int k2 = anIntArray978[defaultText]; + boolean flag = true; + while (flag) { + flag = false; + for (int l2 = 0; l2 < defaultText; l2++) + if (l1 + 2 > anIntArray977[l2] - anIntArray978[l2] && l1 - k2 < anIntArray977[l2] + 2 + && k1 - j2 < anIntArray976[l2] + anIntArray979[l2] + && k1 + j2 > anIntArray976[l2] - anIntArray979[l2] + && anIntArray977[l2] - anIntArray978[l2] < l1) { + l1 = anIntArray977[l2] - anIntArray978[l2]; + flag = true; + } + + } + spriteDrawX = anIntArray976[defaultText]; + spriteDrawY = anIntArray977[defaultText] = l1; + String s = aStringArray983[defaultText]; + if (anInt1249 == 0) { + int i3 = 0xffff00; + if (textColourEffect[defaultText] < 6) + i3 = anIntArray965[textColourEffect[defaultText]]; + if (textColourEffect[defaultText] == 6) + i3 = anInt1265 % 20 >= 10 ? 0xffff00 : 0xff0000; + if (textColourEffect[defaultText] == 7) + i3 = anInt1265 % 20 >= 10 ? 65535 : 255; + if (textColourEffect[defaultText] == 8) + i3 = anInt1265 % 20 >= 10 ? 0x80ff80 : 45056; + if (textColourEffect[defaultText] == 9) { + int j3 = 150 - anIntArray982[defaultText]; + if (j3 < 50) + i3 = 0xff0000 + 1280 * j3; + else if (j3 < 100) + i3 = 0xffff00 - 0x50000 * (j3 - 50); + else if (j3 < 150) + i3 = 65280 + 5 * (j3 - 100); + } + if (textColourEffect[defaultText] == 10) { + int k3 = 150 - anIntArray982[defaultText]; + if (k3 < 50) + i3 = 0xff0000 + 5 * k3; + else if (k3 < 100) + i3 = 0xff00ff - 0x50000 * (k3 - 50); + else if (k3 < 150) + i3 = (255 + 0x50000 * (k3 - 100)) - 5 * (k3 - 100); + } + if (textColourEffect[defaultText] == 11) { + int l3 = 150 - anIntArray982[defaultText]; + if (l3 < 50) + i3 = 0xffffff - 0x50005 * l3; + else if (l3 < 100) + i3 = 65280 + 0x50005 * (l3 - 50); + else if (l3 < 150) + i3 = 0xffffff - 0x50000 * (l3 - 100); + } + if (anIntArray981[defaultText] == 0) { + boldText.drawText(0, s, spriteDrawY + 1, spriteDrawX); + boldText.drawText(i3, s, spriteDrawY, spriteDrawX); + } + if (anIntArray981[defaultText] == 1) { + boldText.wave(0, s, spriteDrawX, anInt1265, spriteDrawY + 1); + boldText.wave(i3, s, spriteDrawX, anInt1265, spriteDrawY); + } + if (anIntArray981[defaultText] == 2) { + boldText.wave2(spriteDrawX, s, anInt1265, spriteDrawY + 1, 0); + boldText.wave2(spriteDrawX, s, anInt1265, spriteDrawY, i3); + } + if (anIntArray981[defaultText] == 3) { + boldText.shake(150 - anIntArray982[defaultText], s, anInt1265, spriteDrawY + 1, spriteDrawX, 0); + boldText.shake(150 - anIntArray982[defaultText], s, anInt1265, spriteDrawY, spriteDrawX, i3); + } + if (anIntArray981[defaultText] == 4) { + int i4 = boldText.method384(s); + int k4 = ((150 - anIntArray982[defaultText]) * (i4 + 100)) / 150; + Rasterizer2D.setDrawingArea(334, spriteDrawX - 50, spriteDrawX + 50, 0); + boldText.render(0, s, spriteDrawY + 1, (spriteDrawX + 50) - k4); + boldText.render(i3, s, spriteDrawY, (spriteDrawX + 50) - k4); + Rasterizer2D.defaultDrawingAreaSize(); + } + if (anIntArray981[defaultText] == 5) { + int j4 = 150 - anIntArray982[defaultText]; + int l4 = 0; + if (j4 < 25) + l4 = j4 - 25; + else if (j4 > 125) + l4 = j4 - 125; + Rasterizer2D.setDrawingArea(spriteDrawY + 5, 0, 512, spriteDrawY - boldText.verticalSpace - 1); + boldText.drawText(0, s, spriteDrawY + 1 + l4, spriteDrawX); + boldText.drawText(i3, s, spriteDrawY + l4, spriteDrawX); + Rasterizer2D.defaultDrawingAreaSize(); + } + } else { + boldText.drawText(0, s, spriteDrawY + 1, spriteDrawX); + boldText.drawText(0xffff00, s, spriteDrawY, spriteDrawX); + } + } + } catch (Exception e) { + } + } + + public void drawSideIcons() { + + // local variables will not stay in memory which will help with + // performance. + final int[] sideIconsX = {17, 49, 83, 114, 146, 180, 214, 16, 49, 82, 116, 148, 184, 216}, + sideIconsY = {9, 7, 7, 5, 2, 3, 7, 303, 306, 306, 302, 305, 303, 303, 303}, + sideIconsId = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, + sideIconsTab = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; + + int xOffset = frameMode == ScreenMode.FIXED ? 0 : frameWidth - 247; + int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 336; + if (frameMode == ScreenMode.FIXED || frameMode != ScreenMode.FIXED && !changeTabArea) { + for (int i = 0; i < sideIconsTab.length; i++) { + if (tabInterfaceIDs[sideIconsTab[i]] != -1) { + if (sideIconsId[i] != -1) { + sideIcons[sideIconsId[i]].drawSprite(sideIconsX[i] + xOffset, sideIconsY[i] + yOffset); + } + } + } + } else if (changeTabArea && frameWidth < 1000) { + int[] iconId = {0, 1, 2, 3, 4, 5, 6, -1, 8, 9, 7, 11, 12, 13}; + int[] iconX = {219, 189, 156, 126, 93, 62, 30, 219, 189, 156, 124, 92, 59, 28}; + int[] iconY = {67, 69, 67, 69, 72, 72, 69, 32, 29, 29, 32, 30, 33, 31, 32}; + for (int i = 0; i < sideIconsTab.length; i++) { + if (tabInterfaceIDs[sideIconsTab[i]] != -1) { + if (iconId[i] != -1) { + sideIcons[iconId[i]].drawSprite(frameWidth - iconX[i], frameHeight - iconY[i]); + } + } + } + } else if (changeTabArea && frameWidth >= 1000) { + int[] iconId = {0, 1, 2, 3, 4, 5, 6, -1, 8, 9, 7, 11, 12, 13}; + int[] iconX = {50, 80, 114, 143, 176, 208, 240, 242, 273, 306, 338, 370, 404, 433}; + int[] iconY = {30, 32, 30, 32, 34, 34, 32, 32, 29, 29, 32, 31, 32, 32, 32}; + for (int i = 0; i < sideIconsTab.length; i++) { + if (tabInterfaceIDs[sideIconsTab[i]] != -1) { + if (iconId[i] != -1) { + sideIcons[iconId[i]].drawSprite(frameWidth - 461 + iconX[i], frameHeight - iconY[i]); + } + } + } + } + } + + private void drawRedStones() { + + final int[] redStonesX = {6, 44, 77, 110, 143, 176, 209, 6, 44, 77, 110, 143, 176, 209}, + redStonesY = {0, 0, 0, 0, 0, 0, 0, 298, 298, 298, 298, 298, 298, 298}, + redStonesId = {35, 39, 39, 39, 39, 39, 36, 37, 39, 39, 39, 39, 39, 38}; + + int xOffset = frameMode == ScreenMode.FIXED ? 0 : frameWidth - 247; + int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 336; + if (frameMode == ScreenMode.FIXED || frameMode != ScreenMode.FIXED && !changeTabArea) { + if (tabInterfaceIDs[tabId] != -1 && tabId != 15) { + SpriteCache.lookup(redStonesId[tabId]).drawSprite(redStonesX[tabId] + xOffset, + redStonesY[tabId] + yOffset); + } + } else if (changeTabArea && frameWidth < 1000) { + int[] stoneX = {226, 194, 162, 130, 99, 65, 34, 219, 195, 161, 130, 98, 65, 33}; + int[] stoneY = {73, 73, 73, 73, 73, 73, 73, -1, 37, 37, 37, 37, 37, 37, 37}; + if (tabInterfaceIDs[tabId] != -1 && tabId != 10 && showTabComponents) { + if (tabId == 7) { + SpriteCache.lookup(39).drawSprite(frameWidth - 130, frameHeight - 37); + } + SpriteCache.lookup(39).drawSprite(frameWidth - stoneX[tabId], frameHeight - stoneY[tabId]); + } + } else if (changeTabArea && frameWidth >= 1000) { + int[] stoneX = {417, 385, 353, 321, 289, 256, 224, 129, 193, 161, 130, 98, 65, 33}; + if (tabInterfaceIDs[tabId] != -1 && tabId != 10 && showTabComponents) { + SpriteCache.lookup(39).drawSprite(frameWidth - stoneX[tabId], frameHeight - 37); + } + } + } + + private void drawTabArea() { + final int xOffset = frameMode == ScreenMode.FIXED ? 0 : frameWidth - 241; + final int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 336; + if (frameMode == ScreenMode.FIXED) { + tabImageProducer.initDrawingArea(); + } + Rasterizer3D.scanOffsets = anIntArray1181; + if (frameMode == ScreenMode.FIXED) { + SpriteCache.lookup(21).drawSprite(0, 0); + } else if (frameMode != ScreenMode.FIXED && !changeTabArea) { + Rasterizer2D.drawTransparentBox(frameWidth - 217, frameHeight - 304, 195, 270, 0x3E3529, + transparentTabArea ? 80 : 256); + SpriteCache.lookup(47).drawSprite(xOffset, yOffset); + } else { + if (frameWidth >= 1000) { + if (showTabComponents) { + Rasterizer2D.drawTransparentBox(frameWidth - 197, frameHeight - 304, 197, 265, 0x3E3529, + transparentTabArea ? 80 : 256); + SpriteCache.lookup(50).drawSprite(frameWidth - 204, frameHeight - 311); + } + for (int x = frameWidth - 417, y = frameHeight - 37, index = 0; x <= frameWidth - 30 + && index < 13; x += 32, index++) { + SpriteCache.lookup(46).drawSprite(x, y); + } + } else if (frameWidth < 1000) { + if (showTabComponents) { + Rasterizer2D.drawTransparentBox(frameWidth - 197, frameHeight - 341, 195, 265, 0x3E3529, + transparentTabArea ? 80 : 256); + SpriteCache.lookup(50).drawSprite(frameWidth - 204, frameHeight - 348); + } + for (int x = frameWidth - 226, y = frameHeight - 73, index = 0; x <= frameWidth - 32 + && index < 7; x += 32, index++) { + SpriteCache.lookup(46).drawSprite(x, y); + } + for (int x = frameWidth - 226, y = frameHeight - 37, index = 0; x <= frameWidth - 32 + && index < 7; x += 32, index++) { + SpriteCache.lookup(46).drawSprite(x, y); + } + } + } + if (overlayInterfaceId == -1) { + drawRedStones(); + drawSideIcons(); + } + if (showTabComponents) { + int x = frameMode == ScreenMode.FIXED ? 31 : frameWidth - 215; + int y = frameMode == ScreenMode.FIXED ? 37 : frameHeight - 299; + if (changeTabArea) { + x = frameWidth - 197; + y = frameWidth >= 1000 ? frameHeight - 303 : frameHeight - 340; + } + try { + if (overlayInterfaceId != -1) { + drawInterface(0, x, Widget.interfaceCache[overlayInterfaceId], y); + } else if (tabInterfaceIDs[tabId] != -1) { + drawInterface(0, x, Widget.interfaceCache[tabInterfaceIDs[tabId]], y); + } + } catch (Exception ex) { + + } + } + if (menuOpen) { + drawMenu(frameMode == ScreenMode.FIXED ? 516 : 0, frameMode == ScreenMode.FIXED ? 168 : 0); + } + if (frameMode == ScreenMode.FIXED) { + tabImageProducer.drawGraphics(168, super.graphics, 516); + gameScreenImageProducer.initDrawingArea(); + } + Rasterizer3D.scanOffsets = anIntArray1182; + } + + private void writeBackgroundTexture(int j) { + if (!lowMemory) { + if (Rasterizer3D.textureLastUsed[17] >= j) { + IndexedImage background = Rasterizer3D.textures[17]; + int k = background.width * background.height - 1; + int j1 = background.width * tickDelta * 2; + byte[] raster = background.palettePixels; + byte[] abyte3 = aByteArray912; + for (int i2 = 0; i2 <= k; i2++) + abyte3[i2] = raster[i2 - j1 & k]; + + background.palettePixels = abyte3; + aByteArray912 = raster; + Rasterizer3D.requestTextureUpdate(17); + anInt854++; + if (anInt854 > 1235) { + anInt854 = 0; + // TODO anticheat? + outgoing.writeOpcode(226); + outgoing.writeByte(0); + int l2 = outgoing.currentPosition; + outgoing.writeShort(58722); + outgoing.writeByte(240); + outgoing.writeShort((int) (Math.random() * 65536D)); + outgoing.writeByte((int) (Math.random() * 256D)); + if ((int) (Math.random() * 2D) == 0) + outgoing.writeShort(51825); + outgoing.writeByte((int) (Math.random() * 256D)); + outgoing.writeShort((int) (Math.random() * 65536D)); + outgoing.writeShort(7130); + outgoing.writeShort((int) (Math.random() * 65536D)); + outgoing.writeShort(61657); + outgoing.writeBytes(outgoing.currentPosition - l2); + } + } + if (Rasterizer3D.textureLastUsed[24] >= j) { + IndexedImage background_1 = Rasterizer3D.textures[24]; + int l = background_1.width * background_1.height - 1; + int k1 = background_1.width * tickDelta * 2; + byte[] abyte1 = background_1.palettePixels; + byte[] abyte4 = aByteArray912; + for (int j2 = 0; j2 <= l; j2++) + abyte4[j2] = abyte1[j2 - k1 & l]; + + background_1.palettePixels = abyte4; + aByteArray912 = abyte1; + Rasterizer3D.requestTextureUpdate(24); + } + if (Rasterizer3D.textureLastUsed[34] >= j) { + IndexedImage background_2 = Rasterizer3D.textures[34]; + int i1 = background_2.width * background_2.height - 1; + int l1 = background_2.width * tickDelta * 2; + byte[] abyte2 = background_2.palettePixels; + byte[] abyte5 = aByteArray912; + for (int k2 = 0; k2 <= i1; k2++) + abyte5[k2] = abyte2[k2 - l1 & i1]; + + background_2.palettePixels = abyte5; + aByteArray912 = abyte2; + Rasterizer3D.requestTextureUpdate(34); + } + if (Rasterizer3D.textureLastUsed[40] >= j) { + IndexedImage background_2 = Rasterizer3D.textures[40]; + int i1 = background_2.width * background_2.height - 1; + int l1 = background_2.width * tickDelta * 2; + byte[] abyte2 = background_2.palettePixels; + byte[] abyte5 = aByteArray912; + for (int k2 = 0; k2 <= i1; k2++) + abyte5[k2] = abyte2[k2 - l1 & i1]; + + background_2.palettePixels = abyte5; + aByteArray912 = abyte2; + Rasterizer3D.requestTextureUpdate(40); + } + } + } + + private void processMobChatText() { + for (int i = -1; i < playerCount; i++) { + int j; + if (i == -1) + j = internalLocalPlayerIndex; + else + j = playerList[i]; + Player player = players[j]; + if (player != null && player.textCycle > 0) { + player.textCycle--; + if (player.textCycle == 0) + player.spokenText = null; + } + } + for (int k = 0; k < npcCount; k++) { + int l = npcIndices[k]; + Npc npc = npcs[l]; + if (npc != null && npc.textCycle > 0) { + npc.textCycle--; + if (npc.textCycle == 0) + npc.spokenText = null; + } + } + } + + private void calculateCameraPosition() { + int i = x * 128 + 64; + int j = y * 128 + 64; + int k = getCenterHeight(plane, j, i) - height; + if (xCameraPos < i) { + xCameraPos += speed + ((i - xCameraPos) * angle) / 1000; + if (xCameraPos > i) + xCameraPos = i; + } + if (xCameraPos > i) { + xCameraPos -= speed + ((xCameraPos - i) * angle) / 1000; + if (xCameraPos < i) + xCameraPos = i; + } + if (zCameraPos < k) { + zCameraPos += speed + ((k - zCameraPos) * angle) / 1000; + if (zCameraPos > k) + zCameraPos = k; + } + if (zCameraPos > k) { + zCameraPos -= speed + ((zCameraPos - k) * angle) / 1000; + if (zCameraPos < k) + zCameraPos = k; + } + if (yCameraPos < j) { + yCameraPos += speed + ((j - yCameraPos) * angle) / 1000; + if (yCameraPos > j) + yCameraPos = j; + } + if (yCameraPos > j) { + yCameraPos -= speed + ((yCameraPos - j) * angle) / 1000; + if (yCameraPos < j) + yCameraPos = j; + } + i = cinematicCamXViewpointLoc * 128 + 64; + j = cinematicCamYViewpointLoc * 128 + 64; + k = getCenterHeight(plane, j, i) - cinematicCamZViewpointLoc; + int l = i - xCameraPos; + int i1 = k - zCameraPos; + int j1 = j - yCameraPos; + int k1 = (int) Math.sqrt(l * l + j1 * j1); + int l1 = (int) (Math.atan2(i1, k1) * 325.94900000000001D) & 0x7ff; + int i2 = (int) (Math.atan2(l, j1) * -325.94900000000001D) & 0x7ff; + if (l1 < 128) + l1 = 128; + if (l1 > 383) + l1 = 383; + if (yCameraCurve < l1) { + yCameraCurve += constCinematicCamRotationSpeed + + ((l1 - yCameraCurve) * varCinematicCamRotationSpeedPromille) / 1000; + if (yCameraCurve > l1) + yCameraCurve = l1; + } + if (yCameraCurve > l1) { + yCameraCurve -= constCinematicCamRotationSpeed + + ((yCameraCurve - l1) * varCinematicCamRotationSpeedPromille) / 1000; + if (yCameraCurve < l1) + yCameraCurve = l1; + } + int j2 = i2 - xCameraCurve; + if (j2 > 1024) + j2 -= 2048; + if (j2 < -1024) + j2 += 2048; + if (j2 > 0) { + xCameraCurve += constCinematicCamRotationSpeed + (j2 * varCinematicCamRotationSpeedPromille) / 1000; + xCameraCurve &= 0x7ff; + } + if (j2 < 0) { + xCameraCurve -= constCinematicCamRotationSpeed + (-j2 * varCinematicCamRotationSpeedPromille) / 1000; + xCameraCurve &= 0x7ff; + } + int k2 = i2 - xCameraCurve; + if (k2 > 1024) + k2 -= 2048; + if (k2 < -1024) + k2 += 2048; + if (k2 < 0 && j2 > 0 || k2 > 0 && j2 < 0) + xCameraCurve = i2; + } + + public void drawMenu(int x, int y) { + int xPos = menuOffsetX - (x - 4); + int yPos = (-y + 4) + menuOffsetY; + int w = menuWidth; + int h = menuHeight + 1; + updateChatbox = true; + tabAreaAltered = true; + int menuColor = 0x5d5447; + Rasterizer2D.drawBox(xPos, yPos, w, h, menuColor); + Rasterizer2D.drawBox(xPos + 1, yPos + 1, w - 2, 16, 0); + Rasterizer2D.drawBoxOutline(xPos + 1, yPos + 18, w - 2, h - 19, 0); + boldText.render(menuColor, "Choose Option", yPos + 14, xPos + 3); + int mouseX = super.mouseX - (x); + int mouseY = (-y) + super.mouseY; + for (int i = 0; i < menuActionRow; i++) { + int textY = yPos + 31 + (menuActionRow - 1 - i) * 15; + int textColor = 0xffffff; + if (mouseX > xPos && mouseX < xPos + w && mouseY > textY - 13 && mouseY < textY + 3) { + Rasterizer2D.drawBox(xPos + 3, textY - 11, menuWidth - 6, 15, 0x6f695d); + textColor = 0xffff00; + } + boldText.drawTextWithPotentialShadow(true, xPos + 3, textColor, menuActionText[i], textY); + } + } + + private void addFriend(long nameHash) { + try { + if (nameHash == 0L) + return; + if (friendsCount >= 100 && member != 1) { + sendMessage("Your friendlist is full. Max of 100 for free users, and 200 for members", 0, ""); + return; + } + if (friendsCount >= 200) { + sendMessage("Your friendlist is full. Max of 100 for free users, and 200 for members", 0, ""); + return; + } + String s = StringUtils.formatUsername(StringUtils.decodeBase37(nameHash)); + for (int i = 0; i < friendsCount; i++) + if (friendsListAsLongs[i] == nameHash) { + sendMessage(s + " is already on your friend list", 0, ""); + return; + } + for (int j = 0; j < ignoreCount; j++) + if (ignoreListAsLongs[j] == nameHash) { + sendMessage("Please remove " + s + " from your ignore list first", 0, ""); + return; + } + + if (s.equals(localPlayer.name)) { + return; + } else { + friendsList[friendsCount] = s; + friendsListAsLongs[friendsCount] = nameHash; + friendsNodeIDs[friendsCount] = 0; + friendsCount++; + outgoing.writeOpcode(PacketConstants.ADD_FRIEND); + outgoing.writeLong(nameHash); + return; + } + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("15283, " + (byte) 68 + ", " + nameHash + ", " + runtimeexception.toString()); + } + throw new RuntimeException(); + } + + private int getCenterHeight(int z, int y, int x) { + int worldX = x >> 7; + int worldY = y >> 7; + if (worldX < 0 || worldY < 0 || worldX > 103 || worldY > 103) + return 0; + int plane = z; + if (plane < 3 && (tileFlags[1][worldX][worldY] & 2) == 2) + plane++; + int sizeX = x & 0x7f; + int sizeY = y & 0x7f; + int i2 = tileHeights[plane][worldX][worldY] * (128 - sizeX) + + tileHeights[plane][worldX + 1][worldY] * sizeX >> 7; + int j2 = tileHeights[plane][worldX][worldY + 1] * (128 - sizeX) + + tileHeights[plane][worldX + 1][worldY + 1] * sizeX >> 7; + return i2 * (128 - sizeY) + j2 * sizeY >> 7; + } + + private void resetLogout() { + try { + if (socketStream != null) + socketStream.close(); + } catch (Exception _ex) { + } + socketStream = null; + loggedIn = false; + loginScreenState = 0; + myUsername = "packet"; + myPassword = ""; + unlinkCaches(); + scene.initToNull(); + for (int i = 0; i < 4; i++) + collisionMaps[i].initialize(); + Arrays.fill(chatMessages, null); + System.gc(); + stopMidi(); + currentSong = -1; + nextSong = -1; + prevSong = 0; + frameMode(ScreenMode.FIXED); + } + + private void changeCharacterGender() { + aBoolean1031 = true; + for (int j = 0; j < 7; j++) { + anIntArray1065[j] = -1; + for (int k = 0; k < IdentityKit.length; k++) { + if (IdentityKit.kits[k].validStyle || IdentityKit.kits[k].bodyPartId != j + (maleCharacter ? 0 : 7)) + continue; + anIntArray1065[j] = k; + break; + } + } + } + + private void updateNPCMovement(int i, Buffer stream) { + while (stream.bitPosition + 21 < i * 8) { + int k = stream.readBits(14); + if (k == 16383) + break; + if (npcs[k] == null) + npcs[k] = new Npc(); + Npc npc = npcs[k]; + npcIndices[npcCount++] = k; + npc.time = tick; + int l = stream.readBits(5); + if (l > 15) + l -= 32; + int i1 = stream.readBits(5); + if (i1 > 15) + i1 -= 32; + int j1 = stream.readBits(1); + npc.desc = NpcDefinition.lookup(stream.readBits(Configuration.npcBits)); + int k1 = stream.readBits(1); + if (k1 == 1) + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = k; + npc.size = npc.desc.size; + npc.degreesToTurn = npc.desc.degreesToTurn; + npc.walkAnimIndex = npc.desc.walkAnim; + npc.turn180AnimIndex = npc.desc.turn180AnimIndex; + npc.turn90CWAnimIndex = npc.desc.turn90CWAnimIndex; + npc.turn90CCWAnimIndex = npc.desc.turn90CCWAnimIndex; + npc.idleAnimation = npc.desc.standAnim; + npc.setPos(localPlayer.pathX[0] + i1, localPlayer.pathY[0] + l, j1 == 1); + } + stream.disableBitAccess(); + } + + public void processGameLoop() { + if (rsAlreadyLoaded || loadingError || genericLoadingError) + return; + tick++; + if (!loggedIn) { + processLoginScreenInput(); + } else { + mainGameProcessor(); + } + processOnDemandQueue(); + } + + private void showOtherPlayers(boolean flag) { + if (localPlayer.x >> 7 == destinationX && localPlayer.y >> 7 == destY) + destinationX = 0; + int j = playerCount; + if (flag) + j = 1; + for (int l = 0; l < j; l++) { + Player player; + int i1; + if (flag) { + player = localPlayer; + i1 = internalLocalPlayerIndex << 14; + } else { + player = players[playerList[l]]; + i1 = playerList[l] << 14; + } + if (player == null || !player.isVisible()) + continue; + player.aBoolean1699 = (lowMemory && playerCount > 50 || playerCount > 200) && !flag + && player.movementAnimation == player.idleAnimation; + int j1 = player.x >> 7; + int k1 = player.y >> 7; + if (j1 < 0 || j1 >= 104 || k1 < 0 || k1 >= 104) + continue; + if (player.playerModel != null && tick >= player.objectModelStart && tick < player.objectModelStop) { + player.aBoolean1699 = false; + player.anInt1709 = getCenterHeight(plane, player.y, player.x); + scene.addToScenePlayerAsObject(plane, player.y, player, player.orientation, + player.objectAnInt1722GreaterYLoc, player.x, player.anInt1709, player.objectAnInt1719LesserXLoc, + player.objectAnInt1721GreaterXLoc, i1, player.objectAnInt1720LesserYLoc); + continue; + } + if ((player.x & 0x7f) == 64 && (player.y & 0x7f) == 64) { + if (anIntArrayArray929[j1][k1] == anInt1265) + continue; + anIntArrayArray929[j1][k1] = anInt1265; + } + player.anInt1709 = getCenterHeight(plane, player.y, player.x); + scene.addAnimableA(plane, player.orientation, player.anInt1709, i1, player.y, 60, player.x, player, + player.animationStretches); + } + } + + private boolean promptUserForInput(Widget widget) { + int contentType = widget.contentType; + if (friendServerStatus == 2) { + if (contentType == 201) { + updateChatbox = true; + inputDialogState = 0; + messagePromptRaised = true; + promptInput = ""; + friendsListAction = 1; + aString1121 = "Enter name of friend to add to list"; + } + if (contentType == 202) { + updateChatbox = true; + inputDialogState = 0; + messagePromptRaised = true; + promptInput = ""; + friendsListAction = 2; + aString1121 = "Enter name of friend to delete from list"; + } + } + if (contentType == 205) { + anInt1011 = 250; + return true; + } + if (contentType == 501) { + updateChatbox = true; + inputDialogState = 0; + messagePromptRaised = true; + promptInput = ""; + friendsListAction = 4; + aString1121 = "Enter name of player to add to list"; + } + if (contentType == 502) { + updateChatbox = true; + inputDialogState = 0; + messagePromptRaised = true; + promptInput = ""; + friendsListAction = 5; + aString1121 = "Enter name of player to delete from list"; + } + if (contentType == 550) { + updateChatbox = true; + inputDialogState = 0; + messagePromptRaised = true; + promptInput = ""; + friendsListAction = 6; + aString1121 = "Enter the name of the chat you wish to join"; + } + if (contentType >= 300 && contentType <= 313) { + int k = (contentType - 300) / 2; + int j1 = contentType & 1; + int i2 = anIntArray1065[k]; + if (i2 != -1) { + do { + if (j1 == 0 && --i2 < 0) + i2 = IdentityKit.length - 1; + if (j1 == 1 && ++i2 >= IdentityKit.length) + i2 = 0; + } while (IdentityKit.kits[i2].validStyle || IdentityKit.kits[i2].bodyPartId != k + (maleCharacter ? 0 : 7)); + anIntArray1065[k] = i2; + aBoolean1031 = true; + } + } + if (contentType >= 314 && contentType <= 323) { + int l = (contentType - 314) / 2; + int k1 = contentType & 1; + int j2 = characterDesignColours[l]; + if (k1 == 0 && --j2 < 0) + j2 = PLAYER_BODY_RECOLOURS[l].length - 1; + if (k1 == 1 && ++j2 >= PLAYER_BODY_RECOLOURS[l].length) + j2 = 0; + characterDesignColours[l] = j2; + aBoolean1031 = true; + } + if (contentType == 324 && !maleCharacter) { + maleCharacter = true; + changeCharacterGender(); + } + if (contentType == 325 && maleCharacter) { + maleCharacter = false; + changeCharacterGender(); + } + if (contentType == 326) { + outgoing.writeOpcode(PacketConstants.DESIGN_SCREEN); + outgoing.writeByte(maleCharacter ? 0 : 1); + for (int i1 = 0; i1 < 7; i1++) + outgoing.writeByte(anIntArray1065[i1]); + + for (int l1 = 0; l1 < 5; l1++) + outgoing.writeByte(characterDesignColours[l1]); + + return true; + } + + if (contentType == 613) { + canMute = !canMute; + } + + if (contentType >= 601 && contentType <= 612) { + clearTopInterfaces(); + if (reportAbuseInput.length() > 0) { + outgoing.writeOpcode(PacketConstants.REPORT_PLAYER); + outgoing.writeLong(StringUtils.encodeBase37(reportAbuseInput)); + outgoing.writeByte(contentType - 601); + outgoing.writeByte(canMute ? 1 : 0); + } + } + return false; + } + + private void parsePlayerSynchronizationMask(Buffer stream) { + for (int count = 0; count < mobsAwaitingUpdateCount; count++) { + int index = mobsAwaitingUpdate[count]; + Player player = players[index]; + + int mask = stream.readUnsignedByte(); + + if ((mask & 0x40) != 0) { + mask += stream.readUnsignedByte() << 8; + } + + appendPlayerUpdateMask(mask, index, stream, player); + } + } + + private void drawMapScenes(int i, int k, int l, int i1, int j1) { + int k1 = scene.getWallObjectUid(j1, l, i); + if (k1 != 0) { + int l1 = scene.getMask(j1, l, i, k1); + int k2 = l1 >> 6 & 3; + int i3 = l1 & 0x1f; + int k3 = k; + if (k1 > 0) + k3 = i1; + int[] ai = minimapImage.getMyPixels(); + int k4 = 24624 + l * 4 + (103 - i) * 512 * 4; + int i5 = k1 >> 14 & 0x7fff; + ObjectDefinition def = ObjectDefinition.lookup(i5); + if (def.mapscene != -1) { + IndexedImage background_2 = mapScenes[def.mapscene]; + if (background_2 != null) { + int i6 = (def.objectSizeX * 4 - background_2.width) / 2; + int j6 = (def.objectSizeY * 4 - background_2.height) / 2; + background_2.draw(48 + l * 4 + i6, 48 + (104 - i - def.objectSizeY) * 4 + j6); + } + } else { + if (i3 == 0 || i3 == 2) + if (k2 == 0) { + ai[k4] = k3; + ai[k4 + 512] = k3; + ai[k4 + 1024] = k3; + ai[k4 + 1536] = k3; + } else if (k2 == 1) { + ai[k4] = k3; + ai[k4 + 1] = k3; + ai[k4 + 2] = k3; + ai[k4 + 3] = k3; + } else if (k2 == 2) { + ai[k4 + 3] = k3; + ai[k4 + 3 + 512] = k3; + ai[k4 + 3 + 1024] = k3; + ai[k4 + 3 + 1536] = k3; + } else if (k2 == 3) { + ai[k4 + 1536] = k3; + ai[k4 + 1536 + 1] = k3; + ai[k4 + 1536 + 2] = k3; + ai[k4 + 1536 + 3] = k3; + } + if (i3 == 3) + if (k2 == 0) + ai[k4] = k3; + else if (k2 == 1) + ai[k4 + 3] = k3; + else if (k2 == 2) + ai[k4 + 3 + 1536] = k3; + else if (k2 == 3) + ai[k4 + 1536] = k3; + if (i3 == 2) + if (k2 == 3) { + ai[k4] = k3; + ai[k4 + 512] = k3; + ai[k4 + 1024] = k3; + ai[k4 + 1536] = k3; + } else if (k2 == 0) { + ai[k4] = k3; + ai[k4 + 1] = k3; + ai[k4 + 2] = k3; + ai[k4 + 3] = k3; + } else if (k2 == 1) { + ai[k4 + 3] = k3; + ai[k4 + 3 + 512] = k3; + ai[k4 + 3 + 1024] = k3; + ai[k4 + 3 + 1536] = k3; + } else if (k2 == 2) { + ai[k4 + 1536] = k3; + ai[k4 + 1536 + 1] = k3; + ai[k4 + 1536 + 2] = k3; + ai[k4 + 1536 + 3] = k3; + } + } + } + k1 = scene.getGameObjectUid(j1, l, i); + if (k1 != 0) { + int i2 = scene.getMask(j1, l, i, k1); + int l2 = i2 >> 6 & 3; + int j3 = i2 & 0x1f; + int l3 = k1 >> 14 & 0x7fff; + ObjectDefinition class46_1 = ObjectDefinition.lookup(l3); + if (class46_1.mapscene != -1) { + IndexedImage background_1 = mapScenes[class46_1.mapscene]; + if (background_1 != null) { + int j5 = (class46_1.objectSizeX * 4 - background_1.width) / 2; + int k5 = (class46_1.objectSizeY * 4 - background_1.height) / 2; + background_1.draw(48 + l * 4 + j5, 48 + (104 - i - class46_1.objectSizeY) * 4 + k5); + } + } else if (j3 == 9) { + int l4 = 0xeeeeee; + if (k1 > 0) + l4 = 0xee0000; + int[] ai1 = minimapImage.getMyPixels(); + int l5 = 24624 + l * 4 + (103 - i) * 512 * 4; + if (l2 == 0 || l2 == 2) { + ai1[l5 + 1536] = l4; + ai1[l5 + 1024 + 1] = l4; + ai1[l5 + 512 + 2] = l4; + ai1[l5 + 3] = l4; + } else { + ai1[l5] = l4; + ai1[l5 + 512 + 1] = l4; + ai1[l5 + 1024 + 2] = l4; + ai1[l5 + 1536 + 3] = l4; + } + } + } + k1 = scene.getGroundDecorationUid(j1, l, i); + if (k1 != 0) { + int j2 = k1 >> 14 & 0x7fff; + ObjectDefinition class46 = ObjectDefinition.lookup(j2); + if (class46.mapscene != -1) { + IndexedImage background = mapScenes[class46.mapscene]; + if (background != null) { + int i4 = (class46.objectSizeX * 4 - background.width) / 2; + int j4 = (class46.objectSizeY * 4 - background.height) / 2; + background.draw(48 + l * 4 + i4, 48 + (104 - i - class46.objectSizeY) * 4 + j4); + } + } + } + } + + private void loadTitleScreen() { + titleBoxIndexedImage = new IndexedImage(titleArchive, "titlebox", 0); + titleButtonIndexedImage = new IndexedImage(titleArchive, "titlebutton", 0); + + titleIndexedImages = new IndexedImage[12]; + int icon = 0; + try { + icon = Integer.parseInt(getParameter("fl_icon")); + } catch (Exception ex) { + + } + if (icon == 0) { + for (int index = 0; index < 12; index++) { + titleIndexedImages[index] = new IndexedImage(titleArchive, "runes", index); + } + + } else { + for (int index = 0; index < 12; index++) { + titleIndexedImages[index] = new IndexedImage(titleArchive, "runes", 12 + (index & 3)); + } + + } + flameLeftSprite = new Sprite(128, 265); + flameRightSprite = new Sprite(128, 265); + + System.arraycopy(flameLeftBackground.canvasRaster, 0, flameLeftSprite.getMyPixels(), 0, 33920); + + System.arraycopy(flameRightBackground.canvasRaster, 0, flameRightSprite.getMyPixels(), 0, 33920); + + anIntArray851 = new int[256]; + + for (int k1 = 0; k1 < 64; k1++) + anIntArray851[k1] = k1 * 0x40000; + + for (int l1 = 0; l1 < 64; l1++) + anIntArray851[l1 + 64] = 0xff0000 + 1024 * l1; + + for (int i2 = 0; i2 < 64; i2++) + anIntArray851[i2 + 128] = 0xffff00 + 4 * i2; + + for (int j2 = 0; j2 < 64; j2++) + anIntArray851[j2 + 192] = 0xffffff; + + anIntArray852 = new int[256]; + for (int k2 = 0; k2 < 64; k2++) + anIntArray852[k2] = k2 * 1024; + + for (int l2 = 0; l2 < 64; l2++) + anIntArray852[l2 + 64] = 65280 + 4 * l2; + + for (int i3 = 0; i3 < 64; i3++) + anIntArray852[i3 + 128] = 65535 + 0x40000 * i3; + + for (int j3 = 0; j3 < 64; j3++) + anIntArray852[j3 + 192] = 0xffffff; + + anIntArray853 = new int[256]; + for (int k3 = 0; k3 < 64; k3++) + anIntArray853[k3] = k3 * 4; + + for (int l3 = 0; l3 < 64; l3++) + anIntArray853[l3 + 64] = 255 + 0x40000 * l3; + + for (int i4 = 0; i4 < 64; i4++) + anIntArray853[i4 + 128] = 0xff00ff + 1024 * i4; + + for (int j4 = 0; j4 < 64; j4++) + anIntArray853[j4 + 192] = 0xffffff; + + anIntArray850 = new int[256]; + anIntArray1190 = new int[32768]; + anIntArray1191 = new int[32768]; + randomizeBackground(null); + anIntArray828 = new int[32768]; + anIntArray829 = new int[32768]; + drawLoadingText(10, "Connecting to fileserver"); + if (!aBoolean831) { + drawFlames = true; + aBoolean831 = true; + startRunnable(this, 2); + } + } + + private void loadingStages() { + if (lowMemory && loadingStage == 2 && MapRegion.anInt131 != plane) { + gameScreenImageProducer.initDrawingArea(); + drawLoadingMessages(1, "Loading - please wait.", null); + gameScreenImageProducer.drawGraphics(frameMode == ScreenMode.FIXED ? 4 : 0, super.graphics, + frameMode == ScreenMode.FIXED ? 4 : 0); + loadingStage = 1; + loadingStartTime = System.currentTimeMillis(); + } + if (loadingStage == 1) { + int j = method54(); + if (j != 0 && System.currentTimeMillis() - loadingStartTime > 0x57e40L) { + SignLink.reporterror(myUsername + " glcfb " + serverSeed + "," + j + "," + lowMemory + "," + indices[0] + + "," + resourceProvider.remaining() + "," + plane + "," + this.regionX + "," + this.regionY); + loadingStartTime = System.currentTimeMillis(); + } + } + if (loadingStage == 2 && plane != anInt985) { + anInt985 = plane; + renderMapScene(plane); + } + } + + private int method54() { + for (int i = 0; i < localRegionMapData.length; i++) { + if (localRegionMapData[i] == null && localRegionMapIds[i] != -1) + return -1; + if (localRegionLandscapeData[i] == null && localRegionLandscapeIds[i] != -1) + return -2; + } + boolean flag = true; + for (int j = 0; j < localRegionMapData.length; j++) { + byte[] abyte0 = localRegionLandscapeData[j]; + if (abyte0 != null) { + int k = (localRegionIds[j] >> 8) * 64 - regionBaseX; + int l = (localRegionIds[j] & 0xff) * 64 - regionBaseY; + if (constructedViewport) { + k = 10; + l = 10; + } + flag &= MapRegion.method189(k, abyte0, l); + } + } + if (!flag) + return -3; + if (validLocalMap) { + return -4; + } else { + loadingStage = 2; + MapRegion.anInt131 = plane; + updateWorldObjects(); + outgoing.writeOpcode(PacketConstants.LOADED_REGION); + return 0; + } + } + + private void createProjectiles() { + for (Projectile class30_sub2_sub4_sub4 = (Projectile) projectiles + .reverseGetFirst(); class30_sub2_sub4_sub4 != null; class30_sub2_sub4_sub4 = (Projectile) projectiles + .reverseGetNext()) + if (class30_sub2_sub4_sub4.projectileZ != plane || tick > class30_sub2_sub4_sub4.stopCycle) + class30_sub2_sub4_sub4.unlink(); + else if (tick >= class30_sub2_sub4_sub4.startCycle) { + if (class30_sub2_sub4_sub4.target > 0) { + Npc npc = npcs[class30_sub2_sub4_sub4.target - 1]; + if (npc != null && npc.x >= 0 && npc.x < 13312 && npc.y >= 0 && npc.y < 13312) + class30_sub2_sub4_sub4.calculateIncrements(tick, npc.y, + getCenterHeight(class30_sub2_sub4_sub4.projectileZ, npc.y, npc.x) + - class30_sub2_sub4_sub4.endHeight, + npc.x); + } + if (class30_sub2_sub4_sub4.target < 0) { + int j = -class30_sub2_sub4_sub4.target - 1; + Player player; + if (j == localPlayerIndex) + player = localPlayer; + else + player = players[j]; + if (player != null && player.x >= 0 && player.x < 13312 && player.y >= 0 && player.y < 13312) + class30_sub2_sub4_sub4.calculateIncrements(tick, player.y, + getCenterHeight(class30_sub2_sub4_sub4.projectileZ, player.y, player.x) + - class30_sub2_sub4_sub4.endHeight, + player.x); + } + class30_sub2_sub4_sub4.progressCycles(tickDelta); + scene.addAnimableA(plane, class30_sub2_sub4_sub4.turnValue, (int) class30_sub2_sub4_sub4.cnterHeight, + -1, (int) class30_sub2_sub4_sub4.yPos, 60, (int) class30_sub2_sub4_sub4.xPos, + class30_sub2_sub4_sub4, false); + } + + } + + public AppletContext getAppletContext() { + if (SignLink.mainapp != null) + return SignLink.mainapp.getAppletContext(); + else + return super.getAppletContext(); + } + + private void drawLogo() { + byte[] sprites = titleArchive.readFile("title.dat"); + Sprite sprite = new Sprite(sprites, this); + flameLeftBackground.initDrawingArea(); + sprite.method346(0, 0); + flameRightBackground.initDrawingArea(); + sprite.method346(-637, 0); + topLeft1BackgroundTile.initDrawingArea(); + sprite.method346(-128, 0); + bottomLeft1BackgroundTile.initDrawingArea(); + sprite.method346(-202, -371); + loginBoxImageProducer.initDrawingArea(); + sprite.method346(-202, -171); + loginScreenAccessories.initDrawingArea(); + sprite.method346(0, -400); + bottomLeft0BackgroundTile.initDrawingArea(); + sprite.method346(0, -265); + bottomRightImageProducer.initDrawingArea(); + sprite.method346(-562, -265); + loginMusicImageProducer.initDrawingArea(); + sprite.method346(-562, -265); + middleLeft1BackgroundTile.initDrawingArea(); + sprite.method346(-128, -171); + aRSImageProducer_1115.initDrawingArea(); + sprite.method346(-562, -171); + int[] ai = new int[sprite.getMyWidth()]; + for (int j = 0; j < sprite.getMyHeight(); j++) { + for (int k = 0; k < sprite.getMyWidth(); k++) + ai[k] = sprite.getMyPixels()[(sprite.getMyWidth() - k - 1) + sprite.getMyWidth() * j]; + + System.arraycopy(ai, 0, sprite.getMyPixels(), sprite.getMyWidth() * j, sprite.getMyWidth()); + } + flameLeftBackground.initDrawingArea(); + sprite.method346(382, 0); + flameRightBackground.initDrawingArea(); + sprite.method346(-255, 0); + topLeft1BackgroundTile.initDrawingArea(); + sprite.method346(254, 0); + bottomLeft1BackgroundTile.initDrawingArea(); + sprite.method346(180, -371); + loginBoxImageProducer.initDrawingArea(); + sprite.method346(180, -171); + bottomLeft0BackgroundTile.initDrawingArea(); + sprite.method346(382, -265); + bottomRightImageProducer.initDrawingArea(); + sprite.method346(-180, -265); + loginMusicImageProducer.initDrawingArea(); + sprite.method346(-180, -265); + middleLeft1BackgroundTile.initDrawingArea(); + sprite.method346(254, -171); + aRSImageProducer_1115.initDrawingArea(); + sprite.method346(-180, -171); + sprite = new Sprite(titleArchive, "logo", 0); + topLeft1BackgroundTile.initDrawingArea(); + sprite.drawSprite(382 - sprite.getMyWidth() / 2 - 128, 18); + sprite = null; + System.gc(); + } + + private void processOnDemandQueue() { + do { + Resource resource; + do { + resource = resourceProvider.next(); + if (resource == null) + return; + if (resource.dataType == 0) { + Model.method460(resource.buffer, resource.ID); + if (backDialogueId != -1) + updateChatbox = true; + } + if (resource.dataType == 1) { + Frame.load(resource.ID, resource.buffer); + } + if (resource.dataType == 2 && resource.ID == nextSong && resource.buffer != null) + saveMidi(fadeMusic, resource.buffer); + if (resource.dataType == 3 && loadingStage == 1) { + for (int i = 0; i < localRegionMapData.length; i++) { + if (localRegionMapIds[i] == resource.ID) { + localRegionMapData[i] = resource.buffer; + if (resource.buffer == null) + localRegionMapIds[i] = -1; + break; + } + if (localRegionLandscapeIds[i] != resource.ID) + continue; + localRegionLandscapeData[i] = resource.buffer; + if (resource.buffer == null) + localRegionLandscapeIds[i] = -1; + break; + } + + } + } while (resource.dataType != 93 || !resourceProvider.landscapePresent(resource.ID)); + MapRegion.passiveRequestGameObjectModels(new Buffer(resource.buffer), resourceProvider); + } while (true); + } + + private void calcFlamesPosition() { + char c = '\u0100'; + for (int j = 10; j < 117; j++) { + int k = (int) (Math.random() * 100D); + if (k < 50) + anIntArray828[j + (c - 2 << 7)] = 255; + } + for (int l = 0; l < 100; l++) { + int i1 = (int) (Math.random() * 124D) + 2; + int k1 = (int) (Math.random() * 128D) + 128; + int k2 = i1 + (k1 << 7); + anIntArray828[k2] = 192; + } + + for (int j1 = 1; j1 < c - 1; j1++) { + for (int l1 = 1; l1 < 127; l1++) { + int l2 = l1 + (j1 << 7); + anIntArray829[l2] = (anIntArray828[l2 - 1] + anIntArray828[l2 + 1] + anIntArray828[l2 - 128] + + anIntArray828[l2 + 128]) / 4; + } + + } + + anInt1275 += 128; + if (anInt1275 > anIntArray1190.length) { + anInt1275 -= anIntArray1190.length; + int i2 = (int) (Math.random() * 12D); + randomizeBackground(titleIndexedImages[i2]); + } + for (int j2 = 1; j2 < c - 1; j2++) { + for (int i3 = 1; i3 < 127; i3++) { + int k3 = i3 + (j2 << 7); + int i4 = anIntArray829[k3 + 128] - anIntArray1190[k3 + anInt1275 & anIntArray1190.length - 1] / 5; + if (i4 < 0) + i4 = 0; + anIntArray828[k3] = i4; + } + + } + + System.arraycopy(anIntArray969, 1, anIntArray969, 0, c - 1); + + anIntArray969[c - 1] = (int) (Math.sin((double) tick / 14D) * 16D + Math.sin((double) tick / 15D) * 14D + + Math.sin((double) tick / 16D) * 12D); + if (anInt1040 > 0) + anInt1040 -= 4; + if (anInt1041 > 0) + anInt1041 -= 4; + if (anInt1040 == 0 && anInt1041 == 0) { + int l3 = (int) (Math.random() * 2000D); + if (l3 == 0) + anInt1040 = 1024; + if (l3 == 1) + anInt1041 = 1024; + } + } + + private void resetAnimation(int i) { + Widget class9 = Widget.interfaceCache[i]; + for (int j = 0; j < class9.children.length; j++) { + if (class9.children[j] == -1) + break; + Widget class9_1 = Widget.interfaceCache[class9.children[j]]; + if (class9_1.type == 1) + resetAnimation(class9_1.id); + class9_1.currentFrame = 0; + class9_1.lastFrameTime = 0; + } + } + + private void drawHeadIcon() { + if (hintIconDrawType != 2) + return; + calcEntityScreenPos((hintIconX - regionBaseX << 7) + hintIconLocationArrowRelX, hintIconLocationArrowHeight * 2, + (hintIconY - regionBaseY << 7) + hintIconLocationArrowRelY); + if (spriteDrawX > -1 && tick % 20 < 10) + headIconsHint[0].drawSprite(spriteDrawX - 12, spriteDrawY - 28); + } + + private void mainGameProcessor() { + refreshFrameSize(); + if (systemUpdateTime > 1) { + systemUpdateTime--; + } + if (anInt1011 > 0) { + anInt1011--; + } + for (int j = 0; j < 5; j++) { + if (!readPacket()) { + break; + } + } + + if (!loggedIn) { + return; + } + + synchronized (mouseDetection.syncObject) { + if (flagged) { + if (super.clickMode3 != 0 || mouseDetection.coordsIndex >= 40) { + // botting + outgoing.writeOpcode(PacketConstants.FLAG_ACCOUNT); + outgoing.writeByte(0); + int j2 = outgoing.currentPosition; + int j3 = 0; + for (int j4 = 0; j4 < mouseDetection.coordsIndex; j4++) { + if (j2 - outgoing.currentPosition >= 240) + break; + j3++; + int l4 = mouseDetection.coordsY[j4]; + if (l4 < 0) + l4 = 0; + else if (l4 > 502) + l4 = 502; + int k5 = mouseDetection.coordsX[j4]; + if (k5 < 0) + k5 = 0; + else if (k5 > 764) + k5 = 764; + int i6 = l4 * 765 + k5; + if (mouseDetection.coordsY[j4] == -1 && mouseDetection.coordsX[j4] == -1) { + k5 = -1; + l4 = -1; + i6 = 0x7ffff; + } + if (k5 == anInt1237 && l4 == anInt1238) { + if (duplicateClickCount < 2047) + duplicateClickCount++; + } else { + int j6 = k5 - anInt1237; + anInt1237 = k5; + int k6 = l4 - anInt1238; + anInt1238 = l4; + if (duplicateClickCount < 8 && j6 >= -32 && j6 <= 31 && k6 >= -32 && k6 <= 31) { + j6 += 32; + k6 += 32; + outgoing.writeShort((duplicateClickCount << 12) + (j6 << 6) + k6); + duplicateClickCount = 0; + } else if (duplicateClickCount < 8) { + outgoing.writeTriByte(0x800000 + (duplicateClickCount << 19) + i6); + duplicateClickCount = 0; + } else { + outgoing.writeInt(0xc0000000 + (duplicateClickCount << 19) + i6); + duplicateClickCount = 0; + } + } + } + + outgoing.writeBytes(outgoing.currentPosition - j2); + if (j3 >= mouseDetection.coordsIndex) { + mouseDetection.coordsIndex = 0; + } else { + mouseDetection.coordsIndex -= j3; + for (int i5 = 0; i5 < mouseDetection.coordsIndex; i5++) { + mouseDetection.coordsX[i5] = mouseDetection.coordsX[i5 + j3]; + mouseDetection.coordsY[i5] = mouseDetection.coordsY[i5 + j3]; + } + + } + } + } else { + mouseDetection.coordsIndex = 0; + } + } + if (super.clickMode3 != 0) { + long l = (super.aLong29 - aLong1220) / 50L; + if (l > 4095L) + l = 4095L; + aLong1220 = super.aLong29; + int k2 = super.saveClickY; + if (k2 < 0) + k2 = 0; + else if (k2 > 502) + k2 = 502; + int k3 = super.saveClickX; + if (k3 < 0) + k3 = 0; + else if (k3 > 764) + k3 = 764; + int k4 = k2 * 765 + k3; + int j5 = 0; + if (super.clickMode3 == 2) + j5 = 1; + int l5 = (int) l; + outgoing.writeOpcode(PacketConstants.MOUSE_CLICK); + outgoing.writeInt((l5 << 20) + (j5 << 19) + k4); + } + + if (anInt1016 > 0) { + anInt1016--; + } + + if (super.keyArray[1] == 1 || super.keyArray[2] == 1 || super.keyArray[3] == 1 || super.keyArray[4] == 1) + aBoolean1017 = true; + if (aBoolean1017 && anInt1016 <= 0) { + anInt1016 = 20; + aBoolean1017 = false; + outgoing.writeOpcode(PacketConstants.CAMERA_MOVEMENT); + outgoing.writeShort(anInt1184); + outgoing.writeShortA(cameraHorizontal); + } + if (super.awtFocus && !aBoolean954) { + aBoolean954 = true; + outgoing.writeOpcode(PacketConstants.FOCUS_CHANGE); + outgoing.writeByte(1); + } + if (!super.awtFocus && aBoolean954) { + aBoolean954 = false; + outgoing.writeOpcode(PacketConstants.FOCUS_CHANGE); + outgoing.writeByte(0); + } + loadingStages(); + method115(); + timeoutCounter++; + if (timeoutCounter > 750) + dropClient(); + processPlayerMovement(); + processNpcMovement(); + processTrackUpdates(); + processMobChatText(); + tickDelta++; + if (crossType != 0) { + crossIndex += 20; + if (crossIndex >= 400) + crossType = 0; + } + if (atInventoryInterfaceType != 0) { + atInventoryLoopCycle++; + if (atInventoryLoopCycle >= 15) { + if (atInventoryInterfaceType == 2) { + } + if (atInventoryInterfaceType == 3) + updateChatbox = true; + atInventoryInterfaceType = 0; + } + } + if (activeInterfaceType != 0) { + anInt989++; + if (super.mouseX > anInt1087 + 5 || super.mouseX < anInt1087 - 5 || super.mouseY > anInt1088 + 5 + || super.mouseY < anInt1088 - 5) + aBoolean1242 = true; + if (super.clickMode2 == 0) { + if (activeInterfaceType == 2) { + } + if (activeInterfaceType == 3) + updateChatbox = true; + activeInterfaceType = 0; + if (aBoolean1242 && anInt989 >= 15) { + lastActiveInvInterface = -1; + processRightClick(); + if (lastActiveInvInterface == anInt1084 && mouseInvInterfaceIndex != anInt1085) { + Widget childInterface = Widget.interfaceCache[anInt1084]; + int j1 = 0; + if (anInt913 == 1 && childInterface.contentType == 206) + j1 = 1; + if (childInterface.inventoryItemId[mouseInvInterfaceIndex] <= 0) + j1 = 0; + if (childInterface.replaceItems) { + int l2 = anInt1085; + int l3 = mouseInvInterfaceIndex; + childInterface.inventoryItemId[l3] = childInterface.inventoryItemId[l2]; + childInterface.inventoryAmounts[l3] = childInterface.inventoryAmounts[l2]; + childInterface.inventoryItemId[l2] = -1; + childInterface.inventoryAmounts[l2] = 0; + } else if (j1 == 1) { + int i3 = anInt1085; + for (int i4 = mouseInvInterfaceIndex; i3 != i4; ) + if (i3 > i4) { + childInterface.swapInventoryItems(i3, i3 - 1); + i3--; + } else if (i3 < i4) { + childInterface.swapInventoryItems(i3, i3 + 1); + i3++; + } + + } else { + childInterface.swapInventoryItems(anInt1085, mouseInvInterfaceIndex); + } + outgoing.writeOpcode(PacketConstants.MOVE_ITEM); + outgoing.writeLEShortA(anInt1084); + outgoing.writeNegatedByte(j1); + outgoing.writeLEShortA(anInt1085); + outgoing.writeLEShort(mouseInvInterfaceIndex); + } + } else if ((anInt1253 == 1 || menuHasAddFriend(menuActionRow - 1)) && menuActionRow > 2) + determineMenuSize(); + else if (menuActionRow > 0) + processMenuActions(menuActionRow - 1); + atInventoryLoopCycle = 10; + super.clickMode3 = 0; + } + } + if (SceneGraph.clickedTileX != -1) { + int k = SceneGraph.clickedTileX; + int k1 = SceneGraph.clickedTileY; + boolean flag = doWalkTo(0, 0, 0, 0, localPlayer.pathY[0], 0, 0, k1, localPlayer.pathX[0], true, k); + SceneGraph.clickedTileX = -1; + if (flag) { + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 1; + crossIndex = 0; + } + } + if (super.clickMode3 == 1 && clickToContinueString != null) { + clickToContinueString = null; + updateChatbox = true; + super.clickMode3 = 0; + } + processMenuClick(); + if (super.clickMode2 == 1 || super.clickMode3 == 1) + anInt1213++; + if (anInt1500 != 0 || anInt1044 != 0 || anInt1129 != 0) { + if (anInt1501 < 0 && !menuOpen) { + anInt1501++; + if (anInt1501 == 0) { + if (anInt1500 != 0) { + updateChatbox = true; + } + if (anInt1044 != 0) { + } + } + } + } else if (anInt1501 > 0) { + anInt1501--; + } + if (loadingStage == 2) + checkForGameUsages(); + if (loadingStage == 2 && oriented) + calculateCameraPosition(); + for (int i1 = 0; i1 < 5; i1++) + quakeTimes[i1]++; + + manageTextInputs(); + anInt1010++; + if (anInt1010 > 50) + outgoing.writeOpcode(PacketConstants.IDLE); + try { + if (socketStream != null && outgoing.currentPosition > 0) { + socketStream.queueBytes(outgoing.currentPosition, outgoing.payload); + outgoing.currentPosition = 0; + anInt1010 = 0; + } + } catch (IOException _ex) { + dropClient(); + } catch (Exception exception) { + resetLogout(); + } + } + + private void method63() { + SpawnedObject spawnedObject = (SpawnedObject) spawns.reverseGetFirst(); + for (; spawnedObject != null; spawnedObject = (SpawnedObject) spawns.reverseGetNext()) + if (spawnedObject.getLongetivity == -1) { + spawnedObject.delay = 0; + method89(spawnedObject); + } else { + spawnedObject.unlink(); + } + + } + + private void setupLoginScreen() { + if (topLeft1BackgroundTile != null) + return; + super.fullGameScreen = null; + chatboxImageProducer = null; + minimapImageProducer = null; + tabImageProducer = null; + gameScreenImageProducer = null; + chatSettingImageProducer = null; + flameLeftBackground = new ProducingGraphicsBuffer(128, 265); + Rasterizer2D.clear(); + flameRightBackground = new ProducingGraphicsBuffer(128, 265); + Rasterizer2D.clear(); + topLeft1BackgroundTile = new ProducingGraphicsBuffer(509, 171); + Rasterizer2D.clear(); + bottomLeft1BackgroundTile = new ProducingGraphicsBuffer(360, 132); + Rasterizer2D.clear(); + loginBoxImageProducer = new ProducingGraphicsBuffer(360, 200); + Rasterizer2D.clear(); + loginScreenAccessories = new ProducingGraphicsBuffer(300, 800); + Rasterizer2D.clear(); + bottomLeft0BackgroundTile = new ProducingGraphicsBuffer(202, 238); + Rasterizer2D.clear(); + bottomRightImageProducer = new ProducingGraphicsBuffer(203, 238); + Rasterizer2D.clear(); + loginMusicImageProducer = new ProducingGraphicsBuffer(203, 238); + Rasterizer2D.clear(); + middleLeft1BackgroundTile = new ProducingGraphicsBuffer(74, 94); + Rasterizer2D.clear(); + aRSImageProducer_1115 = new ProducingGraphicsBuffer(75, 94); + Rasterizer2D.clear(); + if (titleArchive != null) { + drawLogo(); + loadTitleScreen(); + } + welcomeScreenRaised = true; + } + + void drawLoadingText(int i, String s) { + anInt1079 = i; + aString1049 = s; + setupLoginScreen(); + if (titleArchive == null) { + super.drawLoadingText(i, s); + return; + } + loginBoxImageProducer.initDrawingArea(); + char c = '\u0168'; + char c1 = '\310'; + byte byte1 = 20; + boldText.drawText(0xffffff, Configuration.CLIENT_NAME + " is loading - please wait...", c1 / 2 - 26 - byte1, + c / 2); + int j = c1 / 2 - 18 - byte1; + Rasterizer2D.drawBoxOutline(c / 2 - 152, j, 304, 34, 0x8c1111); + Rasterizer2D.drawBoxOutline(c / 2 - 151, j + 1, 302, 32, 0); + Rasterizer2D.drawBox(c / 2 - 150, j + 2, i * 3, 30, 0x8c1111); + Rasterizer2D.drawBox((c / 2 - 150) + i * 3, j + 2, 300 - i * 3, 30, 0); + boldText.drawText(0xffffff, s, (c1 / 2 + 5) - byte1, c / 2); + loginBoxImageProducer.drawGraphics(171, super.graphics, 202); + if (welcomeScreenRaised) { + welcomeScreenRaised = false; + if (!aBoolean831) { + flameLeftBackground.drawGraphics(0, super.graphics, 0); + flameRightBackground.drawGraphics(0, super.graphics, 637); + } + topLeft1BackgroundTile.drawGraphics(0, super.graphics, 128); + bottomLeft1BackgroundTile.drawGraphics(371, super.graphics, 202); + bottomLeft0BackgroundTile.drawGraphics(265, super.graphics, 0); + bottomRightImageProducer.drawGraphics(265, super.graphics, 562); + loginMusicImageProducer.drawGraphics(265, super.graphics, 562); + middleLeft1BackgroundTile.drawGraphics(171, super.graphics, 128); + aRSImageProducer_1115.drawGraphics(171, super.graphics, 562); + } + } + + private void method65(int i, int j, int k, int l, Widget class9, int i1, boolean flag, int j1) { + int anInt992; + if (aBoolean972) + anInt992 = 32; + else + anInt992 = 0; + aBoolean972 = false; + if (k >= i && k < i + 16 && l >= i1 && l < i1 + 16) { + class9.scrollPosition -= anInt1213 * 4; + if (flag) { + } + } else if (k >= i && k < i + 16 && l >= (i1 + j) - 16 && l < i1 + j) { + class9.scrollPosition += anInt1213 * 4; + if (flag) { + } + } else if (k >= i - anInt992 && k < i + 16 + anInt992 && l >= i1 + 16 && l < (i1 + j) - 16 && anInt1213 > 0) { + int l1 = ((j - 32) * j) / j1; + if (l1 < 8) + l1 = 8; + int i2 = l - i1 - 16 - l1 / 2; + int j2 = j - 32 - l1; + class9.scrollPosition = ((j1 - j) * i2) / j2; + if (flag) { + } + aBoolean972 = true; + } + } + + private boolean clickObject(int i, int j, int k) { + int i1 = i >> 14 & 0x7fff; + int j1 = scene.getMask(plane, k, j, i); + if (j1 == -1) + return false; + int k1 = j1 & 0x1f; + int l1 = j1 >> 6 & 3; + if (k1 == 10 || k1 == 11 || k1 == 22) { + ObjectDefinition class46 = ObjectDefinition.lookup(i1); + int i2; + int j2; + if (l1 == 0 || l1 == 2) { + i2 = class46.objectSizeX; + j2 = class46.objectSizeY; + } else { + i2 = class46.objectSizeY; + j2 = class46.objectSizeX; + } + int k2 = class46.surroundings; + if (l1 != 0) + k2 = (k2 << l1 & 0xf) + (k2 >> 4 - l1); + doWalkTo(2, 0, j2, 0, localPlayer.pathY[0], i2, k2, j, localPlayer.pathX[0], false, k); + } else { + doWalkTo(2, l1, 0, k1 + 1, localPlayer.pathY[0], 0, 0, j, localPlayer.pathX[0], false, k); + } + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + return true; + } + + public void playSong(int id) { + if (id != currentSong && Configuration.enableMusic && !lowMemory && prevSong == 0) { + nextSong = id; + fadeMusic = true; + resourceProvider.provide(2, nextSong); + currentSong = id; + } + } + + public void stopMidi() { + if (SignLink.music != null) { + SignLink.music.stop(); + } + SignLink.fadeMidi = 0; + SignLink.midi = "stop"; + } + + private void adjustVolume(boolean updateMidi, int volume) { + SignLink.setVolume(volume); + if (updateMidi) { + SignLink.midi = "voladjust"; + } + } + + private boolean saveWave(byte[] data, int id) { + return data == null || SignLink.wavesave(data, id); + } + + private void processTrackUpdates() { + for (int count = 0; count < trackCount; count++) { + boolean replay = false; + try { + Buffer stream = Track.data(trackLoops[count], tracks[count]); + new SoundPlayer(new ByteArrayInputStream(stream.payload, 0, stream.currentPosition), + soundVolume[count], soundDelay[count]); + if (System.currentTimeMillis() + (long) (stream.currentPosition / 22) > trackTimer + + (long) (currentTrackTime / 22)) { + currentTrackTime = stream.currentPosition; + trackTimer = System.currentTimeMillis(); + if (saveWave(stream.payload, stream.currentPosition)) { + currentTrackPlaying = tracks[count]; + currentTrackLoop = trackLoops[count]; + } else { + replay = true; + } + } + } catch (Exception exception) { + } + if (!replay || soundDelay[count] == -5) { + trackCount--; + for (int index = count; index < trackCount; index++) { + tracks[index] = tracks[index + 1]; + trackLoops[index] = trackLoops[index + 1]; + soundDelay[index] = soundDelay[index + 1]; + soundVolume[index] = soundVolume[index + 1]; + } + count--; + } else { + soundDelay[count] = -5; + } + } + + if (prevSong > 0) { + prevSong -= 20; + if (prevSong < 0) + prevSong = 0; + if (prevSong == 0 && Configuration.enableMusic && !lowMemory) { + nextSong = currentSong; + fadeMusic = true; + resourceProvider.provide(2, nextSong); + } + } + } + + private FileArchive createArchive(int file, String displayedName, String name, int expectedCRC, int x) { + byte[] archiveBuffer = null; + int reconnectionDelay = 5; + try { + if (indices[0] != null) + archiveBuffer = indices[0].decompress(file); + } catch (Exception _ex) { + } + if (archiveBuffer != null && Configuration.useJaggrab) { + indexCrc.reset(); + indexCrc.update(archiveBuffer); + int crc = (int) indexCrc.getValue(); + if (crc != expectedCRC) { + archiveBuffer = null; + } + } + if (archiveBuffer != null) { + FileArchive streamLoader = new FileArchive(archiveBuffer); + return streamLoader; + } + int errors = 0; + while (archiveBuffer == null) { + String message = "Unknown error"; + drawLoadingText(x, "Requesting " + displayedName); + try { + int k1 = 0; + DataInputStream datainputstream = requestCacheIndex(name + expectedCRC); + byte[] abyte1 = new byte[6]; + datainputstream.readFully(abyte1, 0, 6); + Buffer stream = new Buffer(abyte1); + stream.currentPosition = 3; + int i2 = stream.readTriByte() + 6; + int j2 = 6; + archiveBuffer = new byte[i2]; + System.arraycopy(abyte1, 0, archiveBuffer, 0, 6); + + while (j2 < i2) { + int l2 = i2 - j2; + if (l2 > 1000) + l2 = 1000; + int j3 = datainputstream.read(archiveBuffer, j2, l2); + if (j3 < 0) { + message = "Length error: " + j2 + "/" + i2; + throw new IOException("EOF"); + } + j2 += j3; + int k3 = (j2 * 100) / i2; + if (k3 != k1) + drawLoadingText(x, "Loading " + displayedName + " - " + k3 + "%"); + k1 = k3; + } + datainputstream.close(); + try { + if (indices[0] != null) + indices[0].writeFile(archiveBuffer.length, archiveBuffer, file); + } catch (Exception _ex) { + indices[0] = null; + } + indexCrc.reset(); + indexCrc.update(archiveBuffer); + int crc = (int) indexCrc.getValue(); + if (crc != expectedCRC && Configuration.useJaggrab) { + archiveBuffer = null; + errors++; + message = "Checksum error: " + crc; + } + } catch (IOException ioexception) { + if (message.equals("Unknown error")) + message = "Connection error"; + archiveBuffer = null; + } catch (NullPointerException _ex) { + message = "Null error"; + archiveBuffer = null; + if (!SignLink.reporterror) + return null; + } catch (ArrayIndexOutOfBoundsException _ex) { + message = "Bounds error"; + archiveBuffer = null; + if (!SignLink.reporterror) + return null; + } catch (Exception _ex) { + message = "Unexpected error"; + archiveBuffer = null; + if (!SignLink.reporterror) + return null; + } + if (archiveBuffer == null) { + for (int l1 = reconnectionDelay; l1 > 0; l1--) { + if (errors >= 3) { + drawLoadingText(x, "Game updated - please reload page"); + l1 = 10; + } else { + drawLoadingText(x, message + " - Retrying in " + l1); + } + try { + Thread.sleep(1000L); + } catch (Exception _ex) { + } + } + + reconnectionDelay *= 2; + if (reconnectionDelay > 60) + reconnectionDelay = 60; + Configuration.useJaggrab = !Configuration.useJaggrab; + } + + } + + FileArchive streamLoader_1 = new FileArchive(archiveBuffer); + return streamLoader_1; + } + + private void dropClient() { + if (anInt1011 > 0) { + resetLogout(); + return; + } + Rasterizer2D.drawBoxOutline(2, 2, 229, 39, 0xffffff); // white box + // around + Rasterizer2D.drawBox(3, 3, 227, 37, 0); // black fill + regularText.drawText(0, "Connection lost.", 19, 120); + regularText.drawText(0xffffff, "Connection lost.", 18, 119); + regularText.drawText(0, "Please wait - attempting to reestablish.", 34, 117); + regularText.drawText(0xffffff, "Please wait - attempting to reestablish.", 34, 116); + gameScreenImageProducer.drawGraphics(frameMode == ScreenMode.FIXED ? 4 : 0, super.graphics, + frameMode == ScreenMode.FIXED ? 4 : 0); + minimapState = 0; + destinationX = 0; + BufferedConnection rsSocket = socketStream; + loggedIn = false; + loginFailures = 0; + login(myUsername, myPassword, true); + if (!loggedIn) + resetLogout(); + try { + rsSocket.close(); + } catch (Exception _ex) { + } + } + + public void setNorth() { + cameraX = 0; + cameraY = 0; + cameraRotation = 0; + cameraHorizontal = 0; + minimapRotation = 0; + minimapZoom = 0; + } + + private void showInterface(int interfaceId) { + + resetAnimation(interfaceId); + + if (overlayInterfaceId != -1) { + overlayInterfaceId = -1; + tabAreaAltered = true; + } + + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + } + + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + + openInterfaceId = interfaceId; + continuedDialogue = false; + } + + // TODO menu actions + private void processMenuActions(int id) { + if (id < 0) { + return; + } + + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + + int first = firstMenuAction[id]; + int button = secondMenuAction[id]; + int action = menuActionTypes[id]; + int clicked = selectedMenuActions[id]; + + if (action >= 2000) { + action -= 2000; + } + + // TODO unknown + if (action == 851) { + outgoing.writeOpcode(PacketConstants.BUTTON_CLICK); + outgoing.writeShort(155); + } + + // click logout tab + if (action == 700) { + if (tabInterfaceIDs[10] != -1) { + if (tabId == 10) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 10; + tabAreaAltered = true; + } + } + + // custom + if (action == 475 && Configuration.enableOrbs) { + xpCounter = 0; + } + + // reset compass to north + if (action == 696) { + setNorth(); + } + + // custom + if (action == 1506 && Configuration.enableOrbs) { // Select quick + // prayers + outgoing.writeOpcode(185); + outgoing.writeShort(5001); + } + + // custom + if (action == 1500 && Configuration.enableOrbs) { // Toggle quick + // prayers + prayClicked = !prayClicked; + outgoing.writeOpcode(185); + outgoing.writeShort(5000); + } + + // System.out.println(String.format("action: %d first: %d second: %d + // clicked: %d", action, first, button, clicked)); + + // button clicks + switch (action) { + + case 1315: + case 1316: + case 1317: + case 1318: + case 1319: + case 1320: + case 1321: + case 879: + case 850: + case 475: + case 1050: + if (settings[173] == 1) { + Configuration.runEnergy = false; + outgoing.writeOpcode(185); + outgoing.writeShort(152); + } else { + Configuration.runEnergy = true; + outgoing.writeOpcode(185); + outgoing.writeShort(153); + } + break; + + } + + // custom + if (action == 1508 && Configuration.enableOrbs) { // Toggle HP above + // heads + Configuration.hpAboveHeads = !Configuration.hpAboveHeads; + } + + // click autocast + if (action == 104) { + Widget widget = Widget.interfaceCache[button]; + spellId = widget.id; + if (!autocast) { + autocast = true; + autoCastId = widget.id; + outgoing.writeOpcode(185); + outgoing.writeShort(widget.id); + } else if (autoCastId == widget.id) { + autocast = false; + autoCastId = 0; + outgoing.writeOpcode(185); + outgoing.writeShort(widget.id); + } else if (autoCastId != widget.id) { + autocast = true; + autoCastId = widget.id; + outgoing.writeOpcode(185); + outgoing.writeShort(widget.id); + } + } + + // item on npc + if (action == 582) { + Npc npc = npcs[clicked]; + if (npc != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, npc.pathY[0], localPlayer.pathX[0], false, + npc.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + outgoing.writeOpcode(PacketConstants.ITEM_ON_NPC); + outgoing.writeShortA(anInt1285); + outgoing.writeShortA(clicked); + outgoing.writeLEShort(anInt1283); + outgoing.writeShortA(anInt1284); + } + } + + // picking up ground item + if (action == 234) { + boolean flag1 = doWalkTo(2, 0, 0, 0, localPlayer.pathY[0], 0, 0, button, localPlayer.pathX[0], false, + first); + if (!flag1) + flag1 = doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, button, localPlayer.pathX[0], false, first); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // pickup ground item + outgoing.writeOpcode(236); + outgoing.writeLEShort(button + regionBaseY); + outgoing.writeShort(clicked); + outgoing.writeLEShort(first + regionBaseX); + } + + // using item on object + if (action == 62 && clickObject(clicked, button, first)) { + + outgoing.writeOpcode(192); + outgoing.writeShort(anInt1284); + outgoing.writeLEShort(clicked >> 14 & 0x7fff); + outgoing.writeLEShortA(button + regionBaseY); + outgoing.writeLEShort(anInt1283); + outgoing.writeLEShortA(first + regionBaseX); + outgoing.writeShort(anInt1285); + } + + // using item on ground item + if (action == 511) { + boolean flag2 = doWalkTo(2, 0, 0, 0, localPlayer.pathY[0], 0, 0, button, localPlayer.pathX[0], false, + first); + if (!flag2) + flag2 = doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, button, localPlayer.pathX[0], false, first); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // item on ground item + outgoing.writeOpcode(25); + outgoing.writeLEShort(anInt1284); + outgoing.writeShortA(anInt1285); + outgoing.writeShort(clicked); + outgoing.writeShortA(button + regionBaseY); + outgoing.writeLEShortA(anInt1283); + outgoing.writeShort(first + regionBaseX); + } + + // item option 1 + if (action == 74) { + outgoing.writeOpcode(122); + outgoing.writeLEShortA(button); + outgoing.writeShortA(first); + outgoing.writeLEShort(clicked); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) { + atInventoryInterfaceType = 1; + } + if (Widget.interfaceCache[button].parent == backDialogueId) { + atInventoryInterfaceType = 3; + } + } + + // widget action + if (action == 315) { + Widget widget = Widget.interfaceCache[button]; + boolean flag8 = true; + if (widget.contentType > 0) + flag8 = promptUserForInput(widget); + if (flag8) { + + switch (button) { + + case 19144: + inventoryOverlay(15106, 3213); + resetAnimation(15106); + updateChatbox = true; + break; + + case 27653: + showInterface(15106); + break; + + default: + outgoing.writeOpcode(185); + outgoing.writeShort(button); + break; + + } + } + } + + // player option + if (action == 561) { + Player player = players[clicked]; + if (player != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + anInt1188 += clicked; + if (anInt1188 >= 90) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(136); + anInt1188 = 0; + } + // challenge + outgoing.writeOpcode(128); + outgoing.writeShort(clicked); + } + } + + // npc option 1 + if (action == 20) { + Npc npc = npcs[clicked]; + if (npc != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, npc.pathY[0], localPlayer.pathX[0], false, + npc.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // npc action 1 + outgoing.writeOpcode(155); + outgoing.writeLEShort(clicked); + } + } + + // player option 21 + if (action == 779) { + Player player = players[clicked]; + if (player != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // player option 2 + outgoing.writeOpcode(153); + outgoing.writeLEShort(clicked); + } + } + + // clicking tiles + if (action == 519) { + if (!menuOpen) { + scene.clickTile(super.saveClickY - 4, super.saveClickX - 4); + } else { + scene.clickTile(button - 4, first - 4); + } + } + + // object option 5 + if (action == 1062) { + anInt924 += regionBaseX; + if (anInt924 >= 113) { + // validates clicking object option 4 + outgoing.writeOpcode(183); + outgoing.writeTriByte(0xe63271); + anInt924 = 0; + } + clickObject(clicked, button, first); + int objid = clicked >> 14 & 0x7fff; + System.out.println("Object option 5: " + objid + " - " + clicked + " - " + first + regionBaseX + ":" + button + regionBaseY); + // object option 5 + outgoing.writeOpcode(228); + outgoing.writeShortA(clicked >> 14 & 0x7fff); + outgoing.writeShortA(button + regionBaseY); + outgoing.writeShort(first + regionBaseX); + } + + // continue dialogue + if (action == 679 && !continuedDialogue) { + outgoing.writeOpcode(40); + outgoing.writeShort(button); + continuedDialogue = true; + } + + // using bank all option of the bank interface + if (action == 431) { + outgoing.writeOpcode(129); + outgoing.writeShortA(first); + outgoing.writeShort(button); + outgoing.writeShortA(clicked); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) { + atInventoryInterfaceType = 1; + } + if (Widget.interfaceCache[button].parent == backDialogueId) { + atInventoryInterfaceType = 3; + } + } + + if (action == 337 || action == 42 || action == 792 || action == 322) { + String string = menuActionText[id]; + int indexOf = string.indexOf("@whi@"); + if (indexOf != -1) { + long usernameHash = StringUtils.encodeBase37(string.substring(indexOf + 5).trim()); + if (action == 337) { + addFriend(usernameHash); + } + if (action == 42) { + addIgnore(usernameHash); + } + if (action == 792) { + removeFriend(usernameHash); + } + if (action == 322) { + removeIgnore(usernameHash); + } + } + } + // using the bank x option on the bank interface + if (action == 53) { + // bank x + outgoing.writeOpcode(135); + outgoing.writeLEShort(first); + outgoing.writeShortA(button); + outgoing.writeLEShort(clicked); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + // using the second option of an item + if (action == 539) { + // item option 2 + outgoing.writeOpcode(16); + outgoing.writeShortA(clicked); + outgoing.writeLEShortA(first); + outgoing.writeLEShortA(button); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) { + atInventoryInterfaceType = 1; + } + if (Widget.interfaceCache[button].parent == backDialogueId) { + atInventoryInterfaceType = 3; + } + } + if (action == 484 || action == 6) { + String string = menuActionText[id]; + int indexOf = string.indexOf("@whi@"); + if (indexOf != -1) { + string = string.substring(indexOf + 5).trim(); + String username = StringUtils + .formatUsername(StringUtils.decodeBase37(StringUtils.encodeBase37(string))); + boolean flag9 = false; + for (int count = 0; count < playerCount; count++) { + Player player = players[playerList[count]]; + if (player == null || player.name == null || !player.name.equalsIgnoreCase(username)) { + continue; + } + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + + // accepting trade + if (action == 484) { + outgoing.writeOpcode(139); + outgoing.writeLEShort(playerList[count]); + } + + // accepting a challenge + if (action == 6) { + anInt1188 += clicked; + if (anInt1188 >= 90) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(136); + anInt1188 = 0; + } + outgoing.writeOpcode(128); + outgoing.writeShort(playerList[count]); + } + flag9 = true; + break; + } + + if (!flag9) + sendMessage("Unable to find " + username, 0, ""); + } + } + + // Using an item on another item + if (action == 870) { + // item on item + outgoing.writeOpcode(53); + outgoing.writeShort(first); + outgoing.writeShortA(anInt1283); + outgoing.writeLEShortA(clicked); + outgoing.writeShort(anInt1284); + outgoing.writeLEShort(anInt1285); + outgoing.writeShort(button); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + // Using the drop option of an item + if (action == 847) { + // drop item + outgoing.writeOpcode(87); + outgoing.writeShortA(clicked); + outgoing.writeShort(button); + outgoing.writeShortA(first); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + // useable spells + if (action == 626) { + Widget widget = Widget.interfaceCache[button]; + spellSelected = 1; + spellId = widget.id; + anInt1137 = button; + spellUsableOn = widget.spellUsableOn; + itemSelected = 0; + String actionName = widget.selectedActionName; + if (actionName.indexOf(" ") != -1) + actionName = actionName.substring(0, actionName.indexOf(" ")); + String s8 = widget.selectedActionName; + if (s8.indexOf(" ") != -1) + s8 = s8.substring(s8.indexOf(" ") + 1); + spellTooltip = actionName + " " + widget.spellName + " " + s8; + // class9_1.sprite1.drawSprite(class9_1.x, class9_1.anInt265, + // 0xffffff); + // class9_1.sprite1.drawSprite(200,200); + if (Configuration.client_debug) + System.out.println("spellId: " + spellId + " - spellSelected: " + spellSelected); + System.out.println(button + " " + widget.selectedActionName + " " + anInt1137); + if (spellUsableOn == 16) { + tabId = 3; + tabAreaAltered = true; + } + return; + } + + // Using the bank 5 option on a bank widget + if (action == 78) { + // bank 5 + outgoing.writeOpcode(117); + outgoing.writeLEShortA(button); + outgoing.writeLEShortA(clicked); + outgoing.writeLEShort(first); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + // player option 2 + if (action == 27) { + Player player = players[clicked]; + if (player != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + anInt986 += clicked; + if (anInt986 >= 54) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(189); + outgoing.writeByte(234); + anInt986 = 0; + } + // attack player + outgoing.writeOpcode(73); + outgoing.writeLEShort(clicked); + } + } + + // Used for lighting logs + if (action == 213) { + boolean flag3 = doWalkTo(2, 0, 0, 0, localPlayer.pathY[0], 0, 0, button, localPlayer.pathX[0], false, + first); + if (!flag3) + flag3 = doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, button, localPlayer.pathX[0], false, first); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // light item + outgoing.writeOpcode(79); + outgoing.writeLEShort(button + regionBaseY); + outgoing.writeShort(clicked); + outgoing.writeShortA(first + regionBaseX); + } + + // Using the unequip option on the equipment tab interface + if (action == 632) { + // unequip item + outgoing.writeOpcode(145); + outgoing.writeShortA(button); + outgoing.writeShortA(first); + outgoing.writeShortA(clicked); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + if (action == 1004) { + if (tabInterfaceIDs[10] != -1) { + tabId = 10; + tabAreaAltered = true; + } + } + if (action == 1003) { + clanChatMode = 2; + updateChatbox = true; + } + if (action == 1002) { + clanChatMode = 1; + updateChatbox = true; + } + if (action == 1001) { + clanChatMode = 0; + updateChatbox = true; + } + if (action == 1000) { + cButtonCPos = 4; + chatTypeView = 11; + updateChatbox = true; + } + + if (action == 999) { + cButtonCPos = 0; + chatTypeView = 0; + updateChatbox = true; + } + if (action == 998) { + cButtonCPos = 1; + chatTypeView = 5; + updateChatbox = true; + } + + // public chat "hide" option + if (action == 997) { + publicChatMode = 3; + updateChatbox = true; + } + + // public chat "off" option + if (action == 996) { + publicChatMode = 2; + updateChatbox = true; + } + + // public chat "friends" option + if (action == 995) { + publicChatMode = 1; + updateChatbox = true; + } + + // public chat "on" option + if (action == 994) { + publicChatMode = 0; + updateChatbox = true; + } + + // public chat main click + if (action == 993) { + cButtonCPos = 2; + chatTypeView = 1; + updateChatbox = true; + } + + // private chat "off" option + if (action == 992) { + privateChatMode = 2; + updateChatbox = true; + } + + // private chat "friends" option + if (action == 991) { + privateChatMode = 1; + updateChatbox = true; + } + + // private chat "on" option + if (action == 990) { + privateChatMode = 0; + updateChatbox = true; + } + + // private chat main click + if (action == 989) { + cButtonCPos = 3; + chatTypeView = 2; + updateChatbox = true; + } + + // trade message privacy option "off" option + if (action == 987) { + tradeMode = 2; + updateChatbox = true; + } + + // trade message privacy option "friends" option + if (action == 986) { + tradeMode = 1; + updateChatbox = true; + } + + // trade message privacy option "on" option + if (action == 985) { + tradeMode = 0; + updateChatbox = true; + } + + // trade message privacy option main click + if (action == 984) { + cButtonCPos = 5; + chatTypeView = 3; + updateChatbox = true; + } + + if (action == 980) { + cButtonCPos = 6; + chatTypeView = 4; + updateChatbox = true; + } + + // Using 3rd option of an item + if (action == 493) { + // item option 3 + outgoing.writeOpcode(75); + outgoing.writeLEShortA(button); + outgoing.writeLEShort(first); + outgoing.writeShortA(clicked); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + // clicking some sort of tile + if (action == 652) { + boolean flag4 = doWalkTo(2, 0, 0, 0, localPlayer.pathY[0], 0, 0, button, localPlayer.pathX[0], false, + first); + if (!flag4) + flag4 = doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, button, localPlayer.pathX[0], false, first); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // TODO unknown (non-anti bot) + outgoing.writeOpcode(156); + outgoing.writeShortA(first + regionBaseX); + outgoing.writeLEShort(button + regionBaseY); + outgoing.writeLEShortA(clicked); + } + + // Using a spell on a ground item + if (action == 94) { + boolean flag5 = doWalkTo(2, 0, 0, 0, localPlayer.pathY[0], 0, 0, button, localPlayer.pathX[0], false, + first); + if (!flag5) + flag5 = doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, button, localPlayer.pathX[0], false, first); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // magic on ground item + outgoing.writeOpcode(181); + outgoing.writeLEShort(button + regionBaseY); + outgoing.writeShort(clicked); + outgoing.writeLEShort(first + regionBaseX); + outgoing.writeShortA(anInt1137); + } + // clan chat + if (action == 647) { + outgoing.writeOpcode(213); + outgoing.writeShort(button); + outgoing.writeShort(first); + switch (button) { + case 37304: + if (first == 0) { + updateChatbox = true; + inputDialogState = 0; + messagePromptRaised = true; + promptInput = ""; + friendsListAction = 8; + aString1121 = "Enter your new clan name"; + } + break; + } + } + if (action == 646) { + // button click + outgoing.writeOpcode(185); + outgoing.writeShort(button); + Widget widget = Widget.interfaceCache[button]; + if (widget.scripts != null && widget.scripts[0][0] == 5) { + int i2 = widget.scripts[0][1]; + if (settings[i2] != widget.scriptDefaults[0]) { + settings[i2] = widget.scriptDefaults[0]; + updateVarp(i2); + } + } + } + + // Using the 2nd option of an npc + if (action == 225) { + Npc npc = npcs[clicked]; + if (npc != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, npc.pathY[0], localPlayer.pathX[0], false, + npc.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + anInt1226 += clicked; + if (anInt1226 >= 85) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(230); + outgoing.writeByte(239); + anInt1226 = 0; + } + // npc option 2 + outgoing.writeOpcode(17); + outgoing.writeLEShortA(clicked); + } + } + + // Using the 3rd option of an npc + if (action == 965) { + Npc npc = npcs[clicked]; + if (npc != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, npc.pathY[0], localPlayer.pathX[0], false, + npc.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + anInt1134++; + if (anInt1134 >= 96) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(152); + outgoing.writeByte(88); + anInt1134 = 0; + } + // npc option 3 + outgoing.writeOpcode(21); + outgoing.writeShort(clicked); + } + } + + // Using a spell on an npc + if (action == 413) { + Npc npc = npcs[clicked]; + if (npc != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, npc.pathY[0], localPlayer.pathX[0], false, + npc.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // magic on npc + outgoing.writeOpcode(131); + outgoing.writeLEShortA(clicked); + outgoing.writeShortA(anInt1137); + } + } + + // close open interfaces + if (action == 200) { + clearTopInterfaces(); + } + + // Clicking "Examine" option on an npc + if (action == 1025) { + Npc npc = npcs[clicked]; + if (npc != null) { + NpcDefinition entityDef = npc.desc; + if (entityDef.childrenIDs != null) + entityDef = entityDef.morph(); + if (entityDef != null) { + String s9; + if (entityDef.description != null) + s9 = new String(entityDef.description); + else + s9 = "It's a " + entityDef.name + "."; + sendMessage(s9, 0, ""); + } + } + } + + // Using the 2nd option of an object + if (action == 900) { + clickObject(clicked, button, first); + // object option 2 + int objid = clicked >> 14 & 0x7fff; + int x = first + regionBaseX; + int y = button + regionBaseY; + System.out.println("Object option 2: " + objid + " - " + clicked + " - " + x + ":" + y); + outgoing.writeOpcode(252); + outgoing.writeLEShortA(clicked >> 14 & 0x7fff); + outgoing.writeLEShort(button + regionBaseY); + outgoing.writeShortA(first + regionBaseX); + } + + // Using the "Attack" option on a npc + if (action == 412) { + Npc npc = npcs[clicked]; + if (npc != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, npc.pathY[0], localPlayer.pathX[0], false, + npc.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + outgoing.writeOpcode(72); + outgoing.writeShortA(clicked); + } + } + + // Using spells on a player + if (action == 365) { + Player player = players[clicked]; + if (player != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // ? + outgoing.writeOpcode(249); + outgoing.writeShortA(clicked); + outgoing.writeLEShort(anInt1137); + } + } + + // Using the 3rd option of a player + if (action == 729) { + Player player = players[clicked]; + if (player != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // follow + outgoing.writeOpcode(39); + outgoing.writeLEShort(clicked); + } + } + + // Using the 4th option of a player + if (action == 577) { + Player player = players[clicked]; + if (player != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // trade request + outgoing.writeOpcode(139); + outgoing.writeLEShort(clicked); + } + } + + // Using a spell on an item + if (action == 956 && clickObject(clicked, button, first)) { + // magic on item + outgoing.writeOpcode(35); + outgoing.writeLEShort(first + regionBaseX); + outgoing.writeShortA(anInt1137); + outgoing.writeShortA(button + regionBaseY); + outgoing.writeLEShort(clicked >> 14 & 0x7fff); + } + + // Some walking action (packet 23) + if (action == 567) { + boolean flag6 = doWalkTo(2, 0, 0, 0, localPlayer.pathY[0], 0, 0, button, localPlayer.pathX[0], false, + first); + if (!flag6) + flag6 = doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, button, localPlayer.pathX[0], false, first); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // TODO unknown (non-anti-cheat) + outgoing.writeOpcode(23); + outgoing.writeLEShort(button + regionBaseY); + outgoing.writeLEShort(clicked); + outgoing.writeLEShort(first + regionBaseX); + } + + // Using the bank 10 option on the bank interface + if (action == 867) { + + if ((clicked & 3) == 0) { + anInt1175++; + } + + if (anInt1175 >= 59) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(200); + outgoing.writeShort(25501); + anInt1175 = 0; + } + // bank 10 + outgoing.writeOpcode(43); + outgoing.writeLEShort(button); + outgoing.writeShortA(clicked); + outgoing.writeShortA(first); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + // Using a spell on an inventory item + if (action == 543) { + // magic on item + outgoing.writeOpcode(237); + outgoing.writeShort(first); + outgoing.writeShortA(clicked); + outgoing.writeShort(button); + outgoing.writeShortA(anInt1137); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + // Clicking report abuse button + if (action == 606) { + String s2 = menuActionText[id]; + int j2 = s2.indexOf("@whi@"); + if (j2 != -1) + if (openInterfaceId == -1) { + clearTopInterfaces(); + reportAbuseInput = s2.substring(j2 + 5).trim(); + canMute = false; + for (int index = 0; index < Widget.interfaceCache.length; index++) { + if (Widget.interfaceCache[index] == null || Widget.interfaceCache[index].contentType != 600) + continue; + reportAbuseInterfaceID = openInterfaceId = Widget.interfaceCache[index].parent; + break; + } + + } else { + sendMessage("Please close the interface you have open before using 'report abuse'", 0, ""); + } + } + + // Using an inventory item on a player + if (action == 491) { + Player player = players[clicked]; + + if (player != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, player.pathY[0], localPlayer.pathX[0], false, + player.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // TODO item on player + outgoing.writeOpcode(14); + outgoing.writeShortA(anInt1284); + outgoing.writeShort(clicked); + outgoing.writeShort(anInt1285); + outgoing.writeLEShort(anInt1283); + } + } + + // reply to private message + if (action == 639) { + String text = menuActionText[id]; + + int indexOf = text.indexOf("@whi@"); + + if (indexOf != -1) { + long usernameHash = StringUtils.encodeBase37(text.substring(indexOf + 5).trim()); + int resultIndex = -1; + for (int friendIndex = 0; friendIndex < friendsCount; friendIndex++) { + if (friendsListAsLongs[friendIndex] != usernameHash) { + continue; + } + resultIndex = friendIndex; + break; + } + + if (resultIndex != -1 && friendsNodeIDs[resultIndex] > 0) { + updateChatbox = true; + inputDialogState = 0; + messagePromptRaised = true; + promptInput = ""; + friendsListAction = 3; + aLong953 = friendsListAsLongs[resultIndex]; + aString1121 = "Enter defaultText to send to " + friendsList[resultIndex]; + } + } + } + + // Using the equip option of an item in the inventory + if (action == 454) { + // equip item + outgoing.writeOpcode(41); + outgoing.writeShort(clicked); + outgoing.writeShortA(first); + outgoing.writeShortA(button); + atInventoryLoopCycle = 0; + atInventoryInterface = button; + atInventoryIndex = first; + atInventoryInterfaceType = 2; + if (Widget.interfaceCache[button].parent == openInterfaceId) + atInventoryInterfaceType = 1; + if (Widget.interfaceCache[button].parent == backDialogueId) + atInventoryInterfaceType = 3; + } + + // Npc option 4 + if (action == 478) { + Npc npc = npcs[clicked]; + if (npc != null) { + doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, npc.pathY[0], localPlayer.pathX[0], false, + npc.pathX[0]); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + + if ((clicked & 3) == 0) { + anInt1155++; + } + + if (anInt1155 >= 53) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(85); + outgoing.writeByte(66); + anInt1155 = 0; + } + + // npc option 4 + outgoing.writeOpcode(18); + outgoing.writeLEShort(clicked); + } + } + + // Object option 3 + if (action == 113) { + clickObject(clicked, button, first); + // object option 3 + int objid = clicked >> 14 & 0x7fff; + int x = first + regionBaseX; + int y = button + regionBaseY; + System.out.println("Object option 1: " + objid + " - " + clicked + " - " + x + ":" + y); + outgoing.writeOpcode(70); + outgoing.writeLEShort(first + regionBaseX); + outgoing.writeShort(button + regionBaseY); + outgoing.writeLEShortA(clicked >> 14 & 0x7fff); + } + + // Object option 4 + if (action == 872) { + clickObject(clicked, button, first); + int objid = clicked >> 14 & 0x7fff; + int x = first + regionBaseX; + int y = button + regionBaseY; + System.out.println("Object option 1: " + objid + " - " + clicked + " - " + x + ":" + y); + outgoing.writeOpcode(234); + outgoing.writeLEShortA(first + regionBaseX); + outgoing.writeShortA(clicked >> 14 & 0x7fff); + outgoing.writeLEShortA(button + regionBaseY); + } + + // Object option 1 + if (action == 502) { + int objid = clicked >> 14 & 0x7fff; + int x = first + regionBaseX; + int y = button + regionBaseY; + System.out.println("Object option 1: " + objid + " - " + clicked + " - " + x + ":" + y); + clickObject(clicked, button, first); + outgoing.writeOpcode(132); + outgoing.writeLEShortA(first + regionBaseX); + outgoing.writeShort(clicked >> 14 & 0x7fff); + outgoing.writeShortA(button + regionBaseY); + } + if (action == 1125) { + ItemDefinition itemDef = ItemDefinition.lookup(clicked); + Widget widget = Widget.interfaceCache[button]; + String s5; + if (widget != null && widget.inventoryAmounts[first] >= 0x186a0) + s5 = widget.inventoryAmounts[first] + " x " + itemDef.name; + else if (itemDef.description != null) + s5 = itemDef.description; + else + s5 = "It's a " + itemDef.name + "."; + sendMessage(s5, 0, ""); + } + + if (action == 169) { + System.out.println("Button: " + button); + + outgoing.writeOpcode(185); + + if (button == 19158) { + if (settings[173] == 1) { + outgoing.writeShort(152); + } else { + outgoing.writeShort(153); + } + } else { + outgoing.writeShort(button); + } + + Widget widget = Widget.interfaceCache[button]; + + if (widget.scripts != null && widget.scripts[0][0] == 5) { + int setting = widget.scripts[0][1]; + settings[setting] = 1 - settings[setting]; + + updateVarp(setting); + + } + } + + + if (action == 447) { + itemSelected = 1; + anInt1283 = first; + anInt1284 = button; + anInt1285 = clicked; + selectedItemName = ItemDefinition.lookup(clicked).name; + spellSelected = 0; + return; + } + + if (action == 1226) { + int objectId = clicked >> 14 & 0x7fff; + ObjectDefinition definition = ObjectDefinition.lookup(objectId); + String message; + if (definition.description != null) + message = new String(definition.description); + else + message = "It's a " + definition.name + "."; + sendMessage(message, 0, ""); + } + + // Click First Option Ground Item + if (action == 244) { + boolean flag7 = doWalkTo(2, 0, 0, 0, localPlayer.pathY[0], 0, 0, button, localPlayer.pathX[0], false, + first); + if (!flag7) + flag7 = doWalkTo(2, 0, 1, 0, localPlayer.pathY[0], 1, 0, button, localPlayer.pathX[0], false, first); + crossX = super.saveClickX; + crossY = super.saveClickY; + crossType = 2; + crossIndex = 0; + // ground item option + outgoing.writeOpcode(253); + outgoing.writeLEShort(first + regionBaseX); + outgoing.writeLEShortA(button + regionBaseY); + outgoing.writeShortA(clicked); + } + + if (action == 1448) { + ItemDefinition definition = ItemDefinition.lookup(clicked); + String string; + if (definition.description != null) + string = definition.description; + else + string = "It's a " + definition.name + "."; + sendMessage(string, 0, ""); + } + itemSelected = 0; + spellSelected = 0; + + } + + @SuppressWarnings("unused") + private void tutorialIslandAreas() { + onTutorialIsland = 0; + int j = (localPlayer.x >> 7) + regionBaseX; + int k = (localPlayer.y >> 7) + regionBaseY; + if (j >= 3053 && j <= 3156 && k >= 3056 && k <= 3136) + onTutorialIsland = 1; + if (j >= 3072 && j <= 3118 && k >= 9492 && k <= 9535) + onTutorialIsland = 1; + if (onTutorialIsland == 1 && j >= 3139 && j <= 3199 && k >= 3008 && k <= 3062) + onTutorialIsland = 0; + } + + public void run() { + if (drawFlames) { + drawFlames(); + } else { + super.run(); + } + } + + private void createMenu() { + if (openInterfaceId == 15244) { + return; + } + if (itemSelected == 0 && spellSelected == 0) { + menuActionText[menuActionRow] = "Walk here"; + menuActionTypes[menuActionRow] = 519; + firstMenuAction[menuActionRow] = super.mouseX; + secondMenuAction[menuActionRow] = super.mouseY; + menuActionRow++; + } + + int j = -1; + for (int k = 0; k < Model.anInt1687; k++) { + int l = Model.anIntArray1688[k]; + int i1 = l & 0x7f; + int j1 = l >> 7 & 0x7f; + int k1 = l >> 29 & 3; + int l1 = l >> 14 & 0x7fff; + if (l == j) + continue; + j = l; + if (k1 == 2 && scene.getMask(plane, i1, j1, l) >= 0) { + ObjectDefinition objectDef = ObjectDefinition.lookup(l1); + if (objectDef.childrenIDs != null) + objectDef = objectDef.method580(); + if (objectDef == null) + continue; + if (itemSelected == 1) { + menuActionText[menuActionRow] = "Use " + selectedItemName + " with @cya@" + objectDef.name; + menuActionTypes[menuActionRow] = 62; + selectedMenuActions[menuActionRow] = l; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } else if (spellSelected == 1) { + if ((spellUsableOn & 4) == 4) { + menuActionText[menuActionRow] = spellTooltip + " @cya@" + objectDef.name; + menuActionTypes[menuActionRow] = 956; + selectedMenuActions[menuActionRow] = l; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } + } else { + if (objectDef.interactions != null) { + for (int type = 4; type >= 0; type--) + if (objectDef.interactions[type] != null) { + menuActionText[menuActionRow] = objectDef.interactions[type] + " @cya@" + + objectDef.name; + if (type == 0) + menuActionTypes[menuActionRow] = 502; + if (type == 1) + menuActionTypes[menuActionRow] = 900; + if (type == 2) + menuActionTypes[menuActionRow] = 113; + if (type == 3) + menuActionTypes[menuActionRow] = 872; + if (type == 4) + menuActionTypes[menuActionRow] = 1062; + selectedMenuActions[menuActionRow] = l; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } + + } + if (Configuration.enableIds && (myPrivilege >= 2 || myPrivilege <= 3)) { + menuActionText[menuActionRow] = "Examine @cya@" + objectDef.name + " @gre@(@whi@" + l1 + + "@gre@) (@whi@" + (i1 + regionBaseX) + "," + (j1 + regionBaseY) + "@gre@)"; + } else { + menuActionText[menuActionRow] = "Examine @cya@" + objectDef.name; + } + menuActionTypes[menuActionRow] = 1226; + selectedMenuActions[menuActionRow] = objectDef.type << 14; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } + } + if (k1 == 1) { + Npc npc = npcs[l1]; + try { + if (npc.desc.size == 1 && (npc.x & 0x7f) == 64 && (npc.y & 0x7f) == 64) { + for (int j2 = 0; j2 < npcCount; j2++) { + Npc npc2 = npcs[npcIndices[j2]]; + if (npc2 != null && npc2 != npc && npc2.desc.size == 1 && npc2.x == npc.x + && npc2.y == npc.y) + buildAtNPCMenu(npc2.desc, npcIndices[j2], j1, i1); + } + for (int l2 = 0; l2 < playerCount; l2++) { + Player player = players[playerList[l2]]; + if (player != null && player.x == npc.x && player.y == npc.y) + buildAtPlayerMenu(i1, playerList[l2], player, j1); + } + } + buildAtNPCMenu(npc.desc, l1, j1, i1); + } catch (Exception e) { + } + } + if (k1 == 0) { + Player player = players[l1]; + if ((player.x & 0x7f) == 64 && (player.y & 0x7f) == 64) { + for (int k2 = 0; k2 < npcCount; k2++) { + Npc class30_sub2_sub4_sub1_sub1_2 = npcs[npcIndices[k2]]; + if (class30_sub2_sub4_sub1_sub1_2 != null && class30_sub2_sub4_sub1_sub1_2.desc.size == 1 + && class30_sub2_sub4_sub1_sub1_2.x == player.x + && class30_sub2_sub4_sub1_sub1_2.y == player.y) + buildAtNPCMenu(class30_sub2_sub4_sub1_sub1_2.desc, npcIndices[k2], j1, i1); + } + + for (int i3 = 0; i3 < playerCount; i3++) { + Player class30_sub2_sub4_sub1_sub2_2 = players[playerList[i3]]; + if (class30_sub2_sub4_sub1_sub2_2 != null && class30_sub2_sub4_sub1_sub2_2 != player + && class30_sub2_sub4_sub1_sub2_2.x == player.x + && class30_sub2_sub4_sub1_sub2_2.y == player.y) + buildAtPlayerMenu(i1, playerList[i3], class30_sub2_sub4_sub1_sub2_2, j1); + } + + } + buildAtPlayerMenu(i1, l1, player, j1); + } + if (k1 == 3) { + Deque class19 = groundItems[plane][i1][j1]; + if (class19 != null) { + for (Item item = (Item) class19.getFirst(); item != null; item = (Item) class19.getNext()) { + ItemDefinition itemDef = ItemDefinition.lookup(item.ID); + if (itemSelected == 1) { + menuActionText[menuActionRow] = "Use " + selectedItemName + " with @lre@" + itemDef.name; + menuActionTypes[menuActionRow] = 511; + selectedMenuActions[menuActionRow] = item.ID; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } else if (spellSelected == 1) { + if ((spellUsableOn & 1) == 1) { + menuActionText[menuActionRow] = spellTooltip + " @lre@" + itemDef.name; + menuActionTypes[menuActionRow] = 94; + selectedMenuActions[menuActionRow] = item.ID; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } + } else { + for (int j3 = 4; j3 >= 0; j3--) + if (itemDef.groundActions != null && itemDef.groundActions[j3] != null) { + menuActionText[menuActionRow] = itemDef.groundActions[j3] + " @lre@" + itemDef.name; + if (j3 == 0) + menuActionTypes[menuActionRow] = 652; + if (j3 == 1) + menuActionTypes[menuActionRow] = 567; + if (j3 == 2) + menuActionTypes[menuActionRow] = 234; + if (j3 == 3) + menuActionTypes[menuActionRow] = 244; + if (j3 == 4) + menuActionTypes[menuActionRow] = 213; + selectedMenuActions[menuActionRow] = item.ID; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } else if (j3 == 2) { + menuActionText[menuActionRow] = "Take @lre@" + itemDef.name; + } + menuActionTypes[menuActionRow] = 234; + selectedMenuActions[menuActionRow] = item.ID; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } + if (Configuration.enableIds && (myPrivilege >= 2 && myPrivilege <= 3)) { + menuActionText[menuActionRow] = "Examine @lre@" + itemDef.name + " @gre@ (@whi@" + item.ID + + "@gre@)"; + } else { + menuActionText[menuActionRow] = "Examine @lre@" + itemDef.name; + } + menuActionTypes[menuActionRow] = 1448; + selectedMenuActions[menuActionRow] = item.ID; + firstMenuAction[menuActionRow] = i1; + secondMenuAction[menuActionRow] = j1; + menuActionRow++; + } + } + } + } + } + + public void cleanUpForQuit() { + SignLink.reporterror = false; + try { + if (socketStream != null) { + socketStream.close(); + } + } catch (Exception _ex) { + } + socketStream = null; + stopMidi(); + if (mouseDetection != null) + mouseDetection.running = false; + mouseDetection = null; + resourceProvider.disable(); + resourceProvider = null; + chatBuffer = null; + outgoing = null; + login = null; + incoming = null; + localRegionIds = null; + localRegionMapData = null; + localRegionLandscapeData = null; + localRegionMapIds = null; + localRegionLandscapeIds = null; + tileHeights = null; + tileFlags = null; + scene = null; + collisionMaps = null; + anIntArrayArray901 = null; + anIntArrayArray825 = null; + bigX = null; + bigY = null; + aByteArray912 = null; + tabImageProducer = null; + leftFrame = null; + topFrame = null; + minimapImageProducer = null; + gameScreenImageProducer = null; + chatboxImageProducer = null; + chatSettingImageProducer = null; + /* Null pointers for custom sprites */ + mapBack = null; + sideIcons = null; + compass = null; + hitMarks = null; + headIcons = null; + skullIcons = null; + headIconsHint = null; + crosses = null; + mapDotItem = null; + mapDotNPC = null; + mapDotPlayer = null; + mapDotFriend = null; + mapDotTeam = null; + mapScenes = null; + mapFunctions = null; + anIntArrayArray929 = null; + players = null; + playerList = null; + mobsAwaitingUpdate = null; + playerSynchronizationBuffers = null; + removedMobs = null; + npcs = null; + npcIndices = null; + groundItems = null; + spawns = null; + projectiles = null; + incompleteAnimables = null; + firstMenuAction = null; + secondMenuAction = null; + menuActionTypes = null; + selectedMenuActions = null; + menuActionText = null; + settings = null; + minimapHintX = null; + minimapHintY = null; + minimapHint = null; + minimapImage = null; + friendsList = null; + friendsListAsLongs = null; + friendsNodeIDs = null; + flameLeftBackground = null; + flameRightBackground = null; + topLeft1BackgroundTile = null; + bottomLeft1BackgroundTile = null; + loginBoxImageProducer = null; + loginScreenAccessories = null; + bottomLeft0BackgroundTile = null; + bottomRightImageProducer = null; + loginMusicImageProducer = null; + middleLeft1BackgroundTile = null; + aRSImageProducer_1115 = null; + multiOverlay = null; + nullLoader(); + ObjectDefinition.clear(); + NpcDefinition.clear(); + ItemDefinition.clear(); + FloorDefinition.underlays = null; + FloorDefinition.overlays = null; + IdentityKit.kits = null; + Widget.interfaceCache = null; + Animation.animations = null; + Graphic.cache = null; + Graphic.models = null; + Varp.variables = null; + super.fullGameScreen = null; + Player.models = null; + Rasterizer3D.clear(); + SceneGraph.destructor(); + Model.clear(); + Frame.clear(); + System.gc(); + } + + Component getGameComponent() { + if (SignLink.mainapp != null) + return SignLink.mainapp; + return this; + } + + private void manageTextInputs() { + do { + int j = readChar(-796); + if (j == -1) + break; + if (openInterfaceId != -1 && openInterfaceId == reportAbuseInterfaceID) { + if (j == 8 && reportAbuseInput.length() > 0) + reportAbuseInput = reportAbuseInput.substring(0, reportAbuseInput.length() - 1); + if ((j >= 97 && j <= 122 || j >= 65 && j <= 90 || j >= 48 && j <= 57 || j == 32) + && reportAbuseInput.length() < 12) + reportAbuseInput += (char) j; + } else if (messagePromptRaised) { + if (j >= 32 && j <= 122 && promptInput.length() < 80) { + promptInput += (char) j; + updateChatbox = true; + } + if (j == 8 && promptInput.length() > 0) { + promptInput = promptInput.substring(0, promptInput.length() - 1); + updateChatbox = true; + } + if (j == 13 || j == 10) { + messagePromptRaised = false; + updateChatbox = true; + if (friendsListAction == 1) { + long l = StringUtils.encodeBase37(promptInput); + addFriend(l); + } + if (friendsListAction == 2 && friendsCount > 0) { + long l1 = StringUtils.encodeBase37(promptInput); + removeFriend(l1); + } + if (friendsListAction == 3 && promptInput.length() > 0) { + // private message + outgoing.writeOpcode(126); + outgoing.writeByte(0); + int k = outgoing.currentPosition; + outgoing.writeLong(aLong953); + ChatMessageCodec.encode(promptInput, outgoing); + outgoing.writeBytes(outgoing.currentPosition - k); + promptInput = ChatMessageCodec.processText(promptInput); + // promptInput = Censor.doCensor(promptInput); + sendMessage(promptInput, 6, StringUtils.formatUsername(StringUtils.decodeBase37(aLong953))); + if (privateChatMode == 2) { + privateChatMode = 1; + // privacy option + outgoing.writeOpcode(95); + outgoing.writeByte(publicChatMode); + outgoing.writeByte(privateChatMode); + outgoing.writeByte(tradeMode); + } + } + if (friendsListAction == 4 && ignoreCount < 100) { + long l2 = StringUtils.encodeBase37(promptInput); + addIgnore(l2); + } + if (friendsListAction == 5 && ignoreCount > 0) { + long l3 = StringUtils.encodeBase37(promptInput); + removeIgnore(l3); + } + if (friendsListAction == 6) { + long l3 = StringUtils.encodeBase37(promptInput); + chatJoin(l3); + } + } + } else if (inputDialogState == 1) { + if (j >= 48 && j <= 57 && amountOrNameInput.length() < 10) { + amountOrNameInput += (char) j; + updateChatbox = true; + } + if (j == 8 && amountOrNameInput.length() > 0) { + amountOrNameInput = amountOrNameInput.substring(0, amountOrNameInput.length() - 1); + updateChatbox = true; + } + if (j == 13 || j == 10) { + if (amountOrNameInput.length() > 0) { + int i1 = 0; + try { + i1 = Integer.parseInt(amountOrNameInput); + } catch (Exception _ex) { + } + // bank x + outgoing.writeOpcode(208); + outgoing.writeInt(i1); + } + inputDialogState = 0; + updateChatbox = true; + } + } else if (inputDialogState == 2) { + if (j >= 32 && j <= 122 && amountOrNameInput.length() < 12) { + amountOrNameInput += (char) j; + updateChatbox = true; + } + if (j == 8 && amountOrNameInput.length() > 0) { + amountOrNameInput = amountOrNameInput.substring(0, amountOrNameInput.length() - 1); + updateChatbox = true; + } + if (j == 13 || j == 10) { + if (amountOrNameInput.length() > 0) { + // type on interface + outgoing.writeOpcode(60); + outgoing.writeLong(StringUtils.encodeBase37(amountOrNameInput)); + } + inputDialogState = 0; + updateChatbox = true; + } + } else if (backDialogueId == -1) { + if (j >= 32 && j <= 122 && inputString.length() < 80) { + inputString += (char) j; + updateChatbox = true; + } + if (j == 8 && inputString.length() > 0) { + inputString = inputString.substring(0, inputString.length() - 1); + updateChatbox = true; + } + if ((j == 13 || j == 10) && inputString.length() > 0) { + if (myPrivilege == 2 || server.equals("127.0.0.1") || myUsername.equalsIgnoreCase("packet") || myUsername.equalsIgnoreCase("irdb")) { + if (inputString.startsWith("//setspecto")) { + int amt = Integer.parseInt(inputString.substring(12)); + anIntArray1045[300] = amt; + if (settings[300] != amt) { + settings[300] = amt; + updateVarp(300); + if (dialogueId != -1) + updateChatbox = true; + } + } + if (inputString.equals("::fps")) { + fpsOn = !fpsOn; + } + + if (inputString.equals("::dumpitems")) { + File dir = new File("./dump/item_images/"); + + if (!dir.exists()) { + dir.mkdirs(); + } + + for (int itemId = 0; itemId < ItemDefinition.itemCount; itemId++) { + try { + tabAreaAltered = true; + + Widget widget = Widget.interfaceCache[3214]; + for (int value = 0; value < 1; value++) { + widget.inventoryItemId[value] = itemId + 1; + widget.inventoryAmounts[value] = 1; + } + + ItemDefinition item = ItemDefinition.lookup(itemId); + + Sprite sprite = ItemDefinition.getSprite(itemId, 0, 0); + + if (item == null) { + continue; + } + + if ((item.name == "Dwarf Remains" || sprite == null) && itemId != 0) { + continue; + } + + File outputfile = new File(dir, item.id + ".png"); + BufferedImage bufferedImage = new BufferedImage(sprite.getMyWidth(), + sprite.getMyHeight(), BufferedImage.TYPE_INT_RGB); + bufferedImage.setRGB(0, 0, sprite.getMyWidth(), sprite.getMyHeight(), + sprite.getMyPixels(), 0, sprite.getMyWidth()); + + Image image = ImageUtils.makeColorTransparent(bufferedImage, Color.BLACK); + + BufferedImage transparent = ImageUtils.imageToBufferedImage(image); + + ImageIO.write(transparent, "png", outputfile); + + } catch (IOException e) { + } + } + } + + // can open interfaces without it crashing + if (inputString.startsWith("::int")) { + String[] split = inputString.split(" "); + + try { + int interfaceId = Integer.parseInt(split[1]); + + Client.openInterfaceId = interfaceId; + + System.out.println("opening interfaceId: " + interfaceId); + + } catch (Exception ex) { + continue; + } + + } + if(inputString.equalsIgnoreCase("::zoom")) + cameraZoom = cameraZoom-10; + if (inputString.equals("::roofs")) + Configuration.enableRoofs = !Configuration.enableRoofs; + + if (inputString.equals("::ids")) + Configuration.enableIds = !Configuration.enableIds; + + if (inputString.startsWith("::finterface")) { + try { + String[] args = inputString.split(" "); + int id1 = Integer.parseInt(args[1]); + int id2 = Integer.parseInt(args[2]); + fullscreenInterfaceID = id1; + openInterfaceId = id2; + sendMessage("Opened Interface", 0, ""); + } catch (Exception e) { + sendMessage("Interface Failed to load", 0, ""); + } + } + + if (inputString.equals("::music")) + Configuration.enableMusic = !Configuration.enableMusic; + + if (inputString.equals("::10xhp")) { + Configuration.tenXHp = !Configuration.tenXHp; + loadAllOrbs(frameMode == ScreenMode.FIXED ? 0 : frameWidth - 217); + } + + if (inputString.equals("::hp")) + Configuration.hpAboveHeads = !Configuration.hpAboveHeads; + + if (inputString.equals("::names")) + Configuration.namesAboveHeads = !Configuration.namesAboveHeads; + + if (inputString.equals("::orbs")) + Configuration.enableOrbs = !Configuration.enableOrbs; + + if (inputString.equals("::rint")) { + GameFont gameFont = new GameFont(true, "q8_full", titleArchive); + GameFont[] fonts = {smallText, regularText, boldText, gameFont}; + FileArchive interfaces = createArchive(3, "interface", "interface", archiveCRCs[3], 35); + FileArchive graphics = createArchive(4, "2d graphics", "media", archiveCRCs[4], 40); + Widget.load(interfaces, fonts, graphics); + System.out.println("Reloaded interfaces."); + } + + if (inputString.equals("::fog")) + Configuration.enableFog = !Configuration.enableFog; + + if (inputString.equals("::fixed")) { + frameMode(ScreenMode.FIXED); + } + + if (inputString.equals("::resize")) { + frameMode(ScreenMode.RESIZABLE); + } + + if (inputString.equals("::full")) { + frameMode(ScreenMode.FULLSCREEN); + } + + if (inputString.equals("::width")) { + System.out.println(frameWidth); + } + + if (inputString.equals("::chat")) { + if (frameMode != ScreenMode.FIXED) { + changeChatArea = !changeChatArea; + } + } + + if (inputString.equals("::tab")) { + if (frameMode != ScreenMode.FIXED) { + changeTabArea = !changeTabArea; + } + } + + if (inputString.equals("::optab")) { + if (frameMode != ScreenMode.FIXED) { + transparentTabArea = !transparentTabArea; + } + } + + if (inputString.equals("::height")) { + System.out.println(frameHeight); + } + + if (inputString.equals("::data")) { + Configuration.clientData = !Configuration.clientData; + } + + if (inputString.equals("::noclip")) { + for (int plane = 0; plane < 4; plane++) { + for (int x = 1; x < 103; x++) { + for (int y = 1; y < 103; y++) { + collisionMaps[plane].adjacencies[x][y] = 0; + } + } + } + } + } + + if (inputString.startsWith("/")) { + inputString = "::" + inputString; + } + + if (inputString.startsWith("::")) { + // command + outgoing.writeOpcode(103); + outgoing.writeByte(inputString.length() - 1); + outgoing.writeString(inputString.substring(2)); + } else { + String text = inputString.toLowerCase(); + int colorCode = 0; + if (text.startsWith("yellow:")) { + colorCode = 0; + inputString = inputString.substring(7); + } else if (text.startsWith("red:")) { + colorCode = 1; + inputString = inputString.substring(4); + } else if (text.startsWith("green:")) { + colorCode = 2; + inputString = inputString.substring(6); + } else if (text.startsWith("cyan:")) { + colorCode = 3; + inputString = inputString.substring(5); + } else if (text.startsWith("purple:")) { + colorCode = 4; + inputString = inputString.substring(7); + } else if (text.startsWith("white:")) { + colorCode = 5; + inputString = inputString.substring(6); + } else if (text.startsWith("flash1:")) { + colorCode = 6; + inputString = inputString.substring(7); + } else if (text.startsWith("flash2:")) { + colorCode = 7; + inputString = inputString.substring(7); + } else if (text.startsWith("flash3:")) { + colorCode = 8; + inputString = inputString.substring(7); + } else if (text.startsWith("glow1:")) { + colorCode = 9; + inputString = inputString.substring(6); + } else if (text.startsWith("glow2:")) { + colorCode = 10; + inputString = inputString.substring(6); + } else if (text.startsWith("glow3:")) { + colorCode = 11; + inputString = inputString.substring(6); + } + text = inputString.toLowerCase(); + int effectCode = 0; + if (text.startsWith("wave:")) { + effectCode = 1; + inputString = inputString.substring(5); + } else if (text.startsWith("wave2:")) { + effectCode = 2; + inputString = inputString.substring(6); + } else if (text.startsWith("shake:")) { + effectCode = 3; + inputString = inputString.substring(6); + } else if (text.startsWith("scroll:")) { + effectCode = 4; + inputString = inputString.substring(7); + } else if (text.startsWith("slide:")) { + effectCode = 5; + inputString = inputString.substring(6); + } + // chat + outgoing.writeOpcode(4); + outgoing.writeByte(0); + int bufPos = outgoing.currentPosition; + outgoing.writeByteS(effectCode); + outgoing.writeByteS(colorCode); + chatBuffer.currentPosition = 0; + ChatMessageCodec.encode(inputString, chatBuffer); + outgoing.writeReverseDataA(chatBuffer.payload, 0, chatBuffer.currentPosition); + outgoing.writeBytes(outgoing.currentPosition - bufPos); + inputString = ChatMessageCodec.processText(inputString); + // inputString = Censor.doCensor(inputString); + localPlayer.spokenText = inputString; + localPlayer.textColour = colorCode; + localPlayer.textEffect = effectCode; + localPlayer.textCycle = 150; + if (myPrivilege == 2) { + sendMessage(localPlayer.spokenText, 2, "@cr2@" + localPlayer.name); + } else if (myPrivilege == 1) { + sendMessage(localPlayer.spokenText, 2, "@cr1@" + localPlayer.name); + } else { + sendMessage(localPlayer.spokenText, 2, localPlayer.name); + } + if (publicChatMode == 2) { + publicChatMode = 3; + // privacy option + outgoing.writeOpcode(95); + outgoing.writeByte(publicChatMode); + outgoing.writeByte(privateChatMode); + outgoing.writeByte(tradeMode); + } + } + inputString = ""; + updateChatbox = true; + } + } + } while (true); + } + + private void buildPublicChat(int j) { + int l = 0; + for (int message = 0; message < 500; message++) { + + if (chatMessages[message] == null) { + continue; + } + + if (chatTypeView != 1) { + continue; + } + + int privacyOptionType = chatTypes[message]; + + String crownName = chatNames[message]; + + int k1 = (70 - l * 14 + 42) + anInt1089 + 4 + 5; + + if (k1 < -23) { + break; + } + + if (crownName != null && crownName.startsWith("@cr1@")) { + crownName = crownName.substring(5); + } + + if (crownName != null && crownName.startsWith("@cr2@")) { + crownName = crownName.substring(5); + } + + if (crownName != null && crownName.startsWith("@cr3@")) { + crownName = crownName.substring(5); + } + + if ((privacyOptionType == 1 || privacyOptionType == 2) && (privacyOptionType == 1 || publicChatMode == 0 + || publicChatMode == 1 && isFriendOrSelf(crownName))) { + if (j > k1 - 14 && j <= k1 && !crownName.equals(localPlayer.name)) { + if (myPrivilege >= 1) { + menuActionText[menuActionRow] = "Report abuse @whi@" + crownName; + menuActionTypes[menuActionRow] = 606; + menuActionRow++; + } + menuActionText[menuActionRow] = "Add ignore @whi@" + crownName; + menuActionTypes[menuActionRow] = 42; + menuActionRow++; + menuActionText[menuActionRow] = "Add friend @whi@" + crownName; + menuActionTypes[menuActionRow] = 337; + menuActionRow++; + } + l++; + } + } + } + + private void buildFriendChat(int j) { + int l = 0; + for (int i1 = 0; i1 < 500; i1++) { + if (chatMessages[i1] == null) + continue; + if (chatTypeView != 2) + continue; + int j1 = chatTypes[i1]; + String s = chatNames[i1]; + int k1 = (70 - l * 14 + 42) + anInt1089 + 4 + 5; + if (k1 < -23) + break; + if (s != null && s.startsWith("@cr1@")) + s = s.substring(5); + if (s != null && s.startsWith("@cr2@")) + s = s.substring(5); + if (s != null && s.startsWith("@cr3@")) + s = s.substring(5); + if ((j1 == 5 || j1 == 6) && (splitPrivateChat == 0 || chatTypeView == 2) + && (j1 == 6 || privateChatMode == 0 || privateChatMode == 1 && isFriendOrSelf(s))) + l++; + if ((j1 == 3 || j1 == 7) && (splitPrivateChat == 0 || chatTypeView == 2) + && (j1 == 7 || privateChatMode == 0 || privateChatMode == 1 && isFriendOrSelf(s))) { + if (j > k1 - 14 && j <= k1) { + if (myPrivilege >= 1) { + menuActionText[menuActionRow] = "Report abuse @whi@" + s; + menuActionTypes[menuActionRow] = 606; + menuActionRow++; + } + menuActionText[menuActionRow] = "Add ignore @whi@" + s; + menuActionTypes[menuActionRow] = 42; + menuActionRow++; + menuActionText[menuActionRow] = "Add friend @whi@" + s; + menuActionTypes[menuActionRow] = 337; + menuActionRow++; + } + l++; + } + } + } + + private void buildDuelorTrade(int j) { + int l = 0; + for (int i1 = 0; i1 < 500; i1++) { + if (chatMessages[i1] == null) + continue; + if (chatTypeView != 3 && chatTypeView != 4) + continue; + int j1 = chatTypes[i1]; + String s = chatNames[i1]; + int k1 = (70 - l * 14 + 42) + anInt1089 + 4 + 5; + if (k1 < -23) + break; + if (s != null && s.startsWith("@cr1@")) + s = s.substring(5); + if (s != null && s.startsWith("@cr2@")) + s = s.substring(5); + if (s != null && s.startsWith("@cr3@")) + s = s.substring(5); + if (chatTypeView == 3 && j1 == 4 && (tradeMode == 0 || tradeMode == 1 && isFriendOrSelf(s))) { + if (j > k1 - 14 && j <= k1) { + menuActionText[menuActionRow] = "Accept trade @whi@" + s; + menuActionTypes[menuActionRow] = 484; + menuActionRow++; + } + l++; + } + if (chatTypeView == 4 && j1 == 8 && (tradeMode == 0 || tradeMode == 1 && isFriendOrSelf(s))) { + if (j > k1 - 14 && j <= k1) { + menuActionText[menuActionRow] = "Accept challenge @whi@" + s; + menuActionTypes[menuActionRow] = 6; + menuActionRow++; + } + l++; + } + if (j1 == 12) { + if (j > k1 - 14 && j <= k1) { + menuActionText[menuActionRow] = "Go-to @blu@" + s; + menuActionTypes[menuActionRow] = 915; + menuActionRow++; + } + l++; + } + } + } + + private void buildChatAreaMenu(int j) { + int l = 0; + for (int i1 = 0; i1 < 500; i1++) { + if (chatMessages[i1] == null) + continue; + int j1 = chatTypes[i1]; + int k1 = (70 - l * 14 + 42) + anInt1089 + 4 + 5; + String s = chatNames[i1]; + if (chatTypeView == 1) { + buildPublicChat(j); + break; + } + if (chatTypeView == 2) { + buildFriendChat(j); + break; + } + if (chatTypeView == 3 || chatTypeView == 4) { + buildDuelorTrade(j); + break; + } + if (chatTypeView == 5) { + break; + } + if (s != null && s.startsWith("@cr1@")) { + s = s.substring(5); + } + if (s != null && s.startsWith("@cr2@")) { + s = s.substring(5); + } + if (s != null && s.startsWith("@cr3@")) { + s = s.substring(5); + } + if (j1 == 0) + l++; + if ((j1 == 1 || j1 == 2) && (j1 == 1 || publicChatMode == 0 || publicChatMode == 1 && isFriendOrSelf(s))) { + if (j > k1 - 14 && j <= k1 && !s.equals(localPlayer.name)) { + if (myPrivilege >= 1) { + menuActionText[menuActionRow] = "Report abuse @whi@" + s; + menuActionTypes[menuActionRow] = 606; + menuActionRow++; + } + menuActionText[menuActionRow] = "Add ignore @whi@" + s; + menuActionTypes[menuActionRow] = 42; + menuActionRow++; + menuActionText[menuActionRow] = "Add friend @whi@" + s; + menuActionTypes[menuActionRow] = 337; + menuActionRow++; + } + l++; + } + if ((j1 == 3 || j1 == 7) && splitPrivateChat == 0 + && (j1 == 7 || privateChatMode == 0 || privateChatMode == 1 && isFriendOrSelf(s))) { + if (j > k1 - 14 && j <= k1) { + if (myPrivilege >= 1) { + menuActionText[menuActionRow] = "Report abuse @whi@" + s; + menuActionTypes[menuActionRow] = 606; + menuActionRow++; + } + menuActionText[menuActionRow] = "Add ignore @whi@" + s; + menuActionTypes[menuActionRow] = 42; + menuActionRow++; + menuActionText[menuActionRow] = "Add friend @whi@" + s; + menuActionTypes[menuActionRow] = 337; + menuActionRow++; + } + l++; + } + if (j1 == 4 && (tradeMode == 0 || tradeMode == 1 && isFriendOrSelf(s))) { + if (j > k1 - 14 && j <= k1) { + menuActionText[menuActionRow] = "Accept trade @whi@" + s; + menuActionTypes[menuActionRow] = 484; + menuActionRow++; + } + l++; + } + if ((j1 == 5 || j1 == 6) && splitPrivateChat == 0 && privateChatMode < 2) + l++; + if (j1 == 8 && (tradeMode == 0 || tradeMode == 1 && isFriendOrSelf(s))) { + if (j > k1 - 14 && j <= k1) { + menuActionText[menuActionRow] = "Accept challenge @whi@" + s; + menuActionTypes[menuActionRow] = 6; + menuActionRow++; + } + l++; + } + } + } + + public int getXPForLevel(int level) { + int points = 0; + int output = 0; + for (int lvl = 1; lvl <= level; lvl++) { + points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0)); + if (lvl >= level) { + return output; + } + output = (int) Math.floor(points / 4); + } + return 0; + } + + /** + * interface_handle_auto_content + */ + private void drawFriendsListOrWelcomeScreen(Widget widget) { + int index = widget.contentType; + if (index >= 1 && index <= 100 || index >= 701 && index <= 800) { + if (index == 1 && friendServerStatus == 0) { + widget.defaultText = "Loading friend list"; + widget.optionType = 0; + return; + } + if (index == 1 && friendServerStatus == 1) { + widget.defaultText = "Connecting to friendserver"; + widget.optionType = 0; + return; + } + if (index == 2 && friendServerStatus != 2) { + widget.defaultText = "Please wait..."; + widget.optionType = 0; + return; + } + int k = friendsCount; + if (friendServerStatus != 2) + k = 0; + if (index > 700) + index -= 601; + else + index--; + if (index >= k) { + widget.defaultText = ""; + widget.optionType = 0; + return; + } else { + widget.defaultText = friendsList[index]; + widget.optionType = 1; + return; + } + } + if (index >= 101 && index <= 200 || index >= 801 && index <= 900) { + int l = friendsCount; + if (friendServerStatus != 2) + l = 0; + if (index > 800) + index -= 701; + else + index -= 101; + if (index >= l) { + widget.defaultText = ""; + widget.optionType = 0; + return; + } + if (friendsNodeIDs[index] == 0) + widget.defaultText = "@red@Offline"; + else if (friendsNodeIDs[index] == nodeID) + widget.defaultText = "@gre@Online"/* + * + (friendsNodeIDs[j] - 9) + */; + else + widget.defaultText = "@red@Offline"/* + * + (friendsNodeIDs[j] - 9) + */; + widget.optionType = 1; + return; + } + + if (index == 203) { + int i1 = friendsCount; + if (friendServerStatus != 2) + i1 = 0; + widget.scrollMax = i1 * 15 + 20; + if (widget.scrollMax <= widget.height) + widget.scrollMax = widget.height + 1; + return; + } + if (index >= 401 && index <= 500) { + if ((index -= 401) == 0 && friendServerStatus == 0) { + widget.defaultText = "Loading ignore list"; + widget.optionType = 0; + return; + } + if (index == 1 && friendServerStatus == 0) { + widget.defaultText = "Please wait..."; + widget.optionType = 0; + return; + } + int j1 = ignoreCount; + if (friendServerStatus == 0) + j1 = 0; + if (index >= j1) { + widget.defaultText = ""; + widget.optionType = 0; + return; + } else { + widget.defaultText = StringUtils.formatUsername(StringUtils.decodeBase37(ignoreListAsLongs[index])); + widget.optionType = 1; + return; + } + } + if (index == 503) { + widget.scrollMax = ignoreCount * 15 + 20; + if (widget.scrollMax <= widget.height) + widget.scrollMax = widget.height + 1; + return; + } + if (index == 327) { + widget.modelRotation1 = 150; + widget.modelRotation2 = (int) (Math.sin((double) tick / 40D) * 256D) & 0x7ff; + if (aBoolean1031) { + for (int k1 = 0; k1 < 7; k1++) { + int l1 = anIntArray1065[k1]; + if (l1 >= 0 && !IdentityKit.kits[l1].bodyLoaded()) + return; + } + + aBoolean1031 = false; + Model[] aclass30_sub2_sub4_sub6s = new Model[7]; + int i2 = 0; + for (int j2 = 0; j2 < 7; j2++) { + int k2 = anIntArray1065[j2]; + if (k2 >= 0) + aclass30_sub2_sub4_sub6s[i2++] = IdentityKit.kits[k2].bodyModel(); + } + + Model model = new Model(i2, aclass30_sub2_sub4_sub6s); + for (int l2 = 0; l2 < 5; l2++) + if (characterDesignColours[l2] != 0) { + model.recolor(PLAYER_BODY_RECOLOURS[l2][0], + PLAYER_BODY_RECOLOURS[l2][characterDesignColours[l2]]); + if (l2 == 1) + model.recolor(anIntArray1204[0], anIntArray1204[characterDesignColours[l2]]); + } + + model.skin(); + model.applyTransform(Animation.animations[localPlayer.idleAnimation].primaryFrames[0]); + model.light(64, 850, -30, -50, -30, true); + widget.defaultMediaType = 5; + widget.defaultMedia = 0; + Widget.method208(aBoolean994, model); + } + return; + } + if (index == 328) { + Widget rsInterface = widget; + int verticleTilt = 150; + int animationSpeed = (int) (Math.sin((double) tick / 40D) * 256D) & 0x7ff; + rsInterface.modelRotation1 = verticleTilt; + rsInterface.modelRotation2 = animationSpeed; + if (aBoolean1031) { + Model characterDisplay = localPlayer.getAnimatedModel(); + for (int l2 = 0; l2 < 5; l2++) + if (characterDesignColours[l2] != 0) { + characterDisplay.recolor(PLAYER_BODY_RECOLOURS[l2][0], + PLAYER_BODY_RECOLOURS[l2][characterDesignColours[l2]]); + if (l2 == 1) + characterDisplay.recolor(anIntArray1204[0], anIntArray1204[characterDesignColours[l2]]); + } + int staticFrame = localPlayer.idleAnimation; + characterDisplay.skin(); + characterDisplay.applyTransform(Animation.animations[staticFrame].primaryFrames[0]); + // characterDisplay.light(64, 850, -30, -50, -30, true); + rsInterface.defaultMediaType = 5; + rsInterface.defaultMedia = 0; + Widget.method208(aBoolean994, characterDisplay); + } + return; + } + if (index == 324) { + if (aClass30_Sub2_Sub1_Sub1_931 == null) { + aClass30_Sub2_Sub1_Sub1_931 = widget.disabledSprite; + aClass30_Sub2_Sub1_Sub1_932 = widget.enabledSprite; + } + if (maleCharacter) { + widget.disabledSprite = aClass30_Sub2_Sub1_Sub1_932; + return; + } else { + widget.disabledSprite = aClass30_Sub2_Sub1_Sub1_931; + return; + } + } + if (index == 325) { + if (aClass30_Sub2_Sub1_Sub1_931 == null) { + aClass30_Sub2_Sub1_Sub1_931 = widget.disabledSprite; + aClass30_Sub2_Sub1_Sub1_932 = widget.enabledSprite; + } + if (maleCharacter) { + widget.disabledSprite = aClass30_Sub2_Sub1_Sub1_931; + return; + } else { + widget.disabledSprite = aClass30_Sub2_Sub1_Sub1_932; + return; + } + } + if (index == 600) { + widget.defaultText = reportAbuseInput; + if (tick % 20 < 10) { + widget.defaultText += "|"; + return; + } else { + widget.defaultText += " "; + return; + } + } + if (index == 613) + if (myPrivilege >= 1) { + if (canMute) { + widget.textColor = 0xff0000; + widget.defaultText = "Moderator option: Mute player for 48 hours: "; + } else { + widget.textColor = 0xffffff; + widget.defaultText = "Moderator option: Mute player for 48 hours: "; + } + } else { + widget.defaultText = ""; + } + if (index == 650 || index == 655) + if (anInt1193 != 0) { + String s; + if (daysSinceLastLogin == 0) + s = "earlier today"; + else if (daysSinceLastLogin == 1) + s = "yesterday"; + else + s = daysSinceLastLogin + " days ago"; + widget.defaultText = "You last logged in " + s + " from: " + SignLink.dns; + } else { + widget.defaultText = ""; + } + if (index == 651) { + if (unreadMessages == 0) { + widget.defaultText = "0 unread messages"; + widget.textColor = 0xffff00; + } + if (unreadMessages == 1) { + widget.defaultText = "1 unread defaultText"; + widget.textColor = 65280; + } + if (unreadMessages > 1) { + widget.defaultText = unreadMessages + " unread messages"; + widget.textColor = 65280; + } + } + if (index == 652) + if (daysSinceRecovChange == 201) { + if (membersInt == 1) + widget.defaultText = "@yel@This is a non-members world: @whi@Since you are a member we"; + else + widget.defaultText = ""; + } else if (daysSinceRecovChange == 200) { + widget.defaultText = "You have not yet set any password recovery questions."; + } else { + String s1; + if (daysSinceRecovChange == 0) + s1 = "Earlier today"; + else if (daysSinceRecovChange == 1) + s1 = "Yesterday"; + else + s1 = daysSinceRecovChange + " days ago"; + widget.defaultText = s1 + " you changed your recovery questions"; + } + if (index == 653) + if (daysSinceRecovChange == 201) { + if (membersInt == 1) + widget.defaultText = "@whi@recommend you use a members world instead. You may use"; + else + widget.defaultText = ""; + } else if (daysSinceRecovChange == 200) + widget.defaultText = "We strongly recommend you do so now to secure your account."; + else + widget.defaultText = "If you do not remember making this change then cancel it immediately"; + if (index == 654) { + if (daysSinceRecovChange == 201) + if (membersInt == 1) { + widget.defaultText = "@whi@this world but member benefits are unavailable whilst here."; + return; + } else { + widget.defaultText = ""; + return; + } + if (daysSinceRecovChange == 200) { + widget.defaultText = "Do this from the 'account management' area on our front webpage"; + return; + } + widget.defaultText = "Do this from the 'account management' area on our front webpage"; + } + } + + private void drawSplitPrivateChat() { + if (splitPrivateChat == 0) { + return; + } + GameFont textDrawingArea = regularText; + int i = 0; + if (systemUpdateTime != 0) { + i = 1; + } + for (int j = 0; j < 100; j++) { + if (chatMessages[j] != null) { + int k = chatTypes[j]; + String s = chatNames[j]; + byte byte1 = 0; + if (s != null && s.startsWith("@cr1@")) { + s = s.substring(5); + byte1 = 1; + } + if (s != null && s.startsWith("@cr2@")) { + s = s.substring(5); + byte1 = 2; + } + if ((k == 3 || k == 7) + && (k == 7 || privateChatMode == 0 || privateChatMode == 1 && isFriendOrSelf(s))) { + int l = 329 - i * 13; + if (frameMode != ScreenMode.FIXED) { + l = frameHeight - 170 - i * 13; + } + int k1 = 4; + textDrawingArea.render(0, "From", l, k1); + textDrawingArea.render(65535, "From", l - 1, k1); + k1 += textDrawingArea.getTextWidth("From "); + if (byte1 == 1) { + modIcons[0].drawSprite(k1, l - 12); + k1 += 12; + } + if (byte1 == 2) { + modIcons[1].drawSprite(k1, l - 12); + k1 += 12; + } + textDrawingArea.render(0, s + ": " + chatMessages[j], l, k1); + textDrawingArea.render(65535, s + ": " + chatMessages[j], l - 1, k1); + if (++i >= 5) { + return; + } + } + if (k == 5 && privateChatMode < 2) { + int i1 = 329 - i * 13; + if (frameMode != ScreenMode.FIXED) { + i1 = frameHeight - 170 - i * 13; + } + textDrawingArea.render(0, chatMessages[j], i1, 4); + textDrawingArea.render(65535, chatMessages[j], i1 - 1, 4); + if (++i >= 5) { + return; + } + } + if (k == 6 && privateChatMode < 2) { + int j1 = 329 - i * 13; + if (frameMode != ScreenMode.FIXED) { + j1 = frameHeight - 170 - i * 13; + } + textDrawingArea.render(0, "To " + s + ": " + chatMessages[j], j1, 4); + textDrawingArea.render(65535, "To " + s + ": " + chatMessages[j], j1 - 1, 4); + if (++i >= 5) { + return; + } + } + } + } + } + + public void sendMessage(String message, int type, String name) { + + if (type == 0 && dialogueId != -1) { + clickToContinueString = message; + super.clickMode3 = 0; + } + + if (backDialogueId == -1) { + updateChatbox = true; + } + + for (int index = 499; index > 0; index--) { + chatTypes[index] = chatTypes[index - 1]; + chatNames[index] = chatNames[index - 1]; + chatMessages[index] = chatMessages[index - 1]; + chatRights[index] = chatRights[index - 1]; + } + + chatTypes[0] = type; + chatNames[0] = name; + chatMessages[0] = message; + chatRights[0] = rights; + } + + private final void minimapHovers() { + final boolean fixed = frameMode == ScreenMode.FIXED; + hpHover = fixed + ? hpHover = super.mouseX >= 516 && super.mouseX <= 571 && super.mouseY >= 41 && super.mouseY < 72 + : super.mouseX >= frameWidth - 216 && super.mouseX <= 159 && super.mouseY >= 13 && super.mouseY < 47; + prayHover = fixed + ? prayHover = super.mouseX >= 518 && super.mouseX <= 572 && super.mouseY >= 85 && super.mouseY < 117 + : super.mouseX >= frameWidth - 207 && super.mouseX <= frameWidth - 151 && super.mouseY >= 105 + && super.mouseY < 139; + runHover = fixed + ? runHover = super.mouseX >= 540 && super.mouseX <= 593 && super.mouseY >= 123 && super.mouseY < 154 + : super.mouseX >= frameWidth - 174 && super.mouseX <= frameWidth - 120 && super.mouseY >= 132 + && super.mouseY < 165; + worldHover = fixed ? super.mouseX >= 718 && super.mouseX <= 748 && super.mouseY >= 22 && super.mouseY <= 50 + : super.mouseX >= frameWidth - 117 && super.mouseX <= frameWidth - 86 && super.mouseY >= 153 + && super.mouseY <= 186; + specialHover = fixed ? super.mouseX >= 670 && super.mouseX <= 727 && super.mouseY >= 133 && super.mouseY <= 164 + : super.mouseX >= frameWidth - 62 && super.mouseX <= frameWidth - 5 && super.mouseY >= 151 + && super.mouseY <= 184; + } + + private void processTabClick() { + if (super.clickMode3 == 1) { + if (frameMode == ScreenMode.FIXED || frameMode != ScreenMode.FIXED && !changeTabArea) { + int xOffset = frameMode == ScreenMode.FIXED ? 0 : frameWidth - 765; + int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 503; + for (int i = 0; i < tabClickX.length; i++) { + if (super.mouseX >= tabClickStart[i] + xOffset + && super.mouseX <= tabClickStart[i] + tabClickX[i] + xOffset + && super.mouseY >= tabClickY[i] + yOffset && super.mouseY < tabClickY[i] + 37 + yOffset + && tabInterfaceIDs[i] != -1) { + tabId = i; + tabAreaAltered = true; + break; + } + } + } else if (changeTabArea && frameWidth < 1000) { + if (super.saveClickX >= frameWidth - 226 && super.saveClickX <= frameWidth - 195 + && super.saveClickY >= frameHeight - 72 && super.saveClickY < frameHeight - 40 + && tabInterfaceIDs[0] != -1) { + if (tabId == 0) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 0; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 194 && super.saveClickX <= frameWidth - 163 + && super.saveClickY >= frameHeight - 72 && super.saveClickY < frameHeight - 40 + && tabInterfaceIDs[1] != -1) { + if (tabId == 1) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 1; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 162 && super.saveClickX <= frameWidth - 131 + && super.saveClickY >= frameHeight - 72 && super.saveClickY < frameHeight - 40 + && tabInterfaceIDs[2] != -1) { + if (tabId == 2) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 2; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 129 && super.saveClickX <= frameWidth - 98 + && super.saveClickY >= frameHeight - 72 && super.saveClickY < frameHeight - 40 + && tabInterfaceIDs[3] != -1) { + if (tabId == 3) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 3; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 97 && super.saveClickX <= frameWidth - 66 + && super.saveClickY >= frameHeight - 72 && super.saveClickY < frameHeight - 40 + && tabInterfaceIDs[4] != -1) { + if (tabId == 4) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 4; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 65 && super.saveClickX <= frameWidth - 34 + && super.saveClickY >= frameHeight - 72 && super.saveClickY < frameHeight - 40 + && tabInterfaceIDs[5] != -1) { + if (tabId == 5) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 5; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 33 && super.saveClickX <= frameWidth + && super.saveClickY >= frameHeight - 72 && super.saveClickY < frameHeight - 40 + && tabInterfaceIDs[6] != -1) { + if (tabId == 6) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 6; + tabAreaAltered = true; + + } + + if (super.saveClickX >= frameWidth - 194 && super.saveClickX <= frameWidth - 163 + && super.saveClickY >= frameHeight - 37 && super.saveClickY < frameHeight - 0 + && tabInterfaceIDs[8] != -1) { + if (tabId == 8) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 8; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 162 && super.saveClickX <= frameWidth - 131 + && super.saveClickY >= frameHeight - 37 && super.saveClickY < frameHeight - 0 + && tabInterfaceIDs[9] != -1) { + if (tabId == 9) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 9; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 129 && super.saveClickX <= frameWidth - 98 + && super.saveClickY >= frameHeight - 37 && super.saveClickY < frameHeight - 0 + && tabInterfaceIDs[10] != -1) { + if (tabId == 7) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 7; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 97 && super.saveClickX <= frameWidth - 66 + && super.saveClickY >= frameHeight - 37 && super.saveClickY < frameHeight - 0 + && tabInterfaceIDs[11] != -1) { + if (tabId == 11) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 11; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 65 && super.saveClickX <= frameWidth - 34 + && super.saveClickY >= frameHeight - 37 && super.saveClickY < frameHeight - 0 + && tabInterfaceIDs[12] != -1) { + if (tabId == 12) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 12; + tabAreaAltered = true; + + } + if (super.saveClickX >= frameWidth - 33 && super.saveClickX <= frameWidth + && super.saveClickY >= frameHeight - 37 && super.saveClickY < frameHeight - 0 + && tabInterfaceIDs[13] != -1) { + if (tabId == 13) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 13; + tabAreaAltered = true; + + } + } else if (changeTabArea && frameWidth >= 1000) { + if (super.mouseY >= frameHeight - 37 && super.mouseY <= frameHeight) { + if (super.mouseX >= frameWidth - 417 && super.mouseX <= frameWidth - 386) { + if (tabId == 0) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 0; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 385 && super.mouseX <= frameWidth - 354) { + if (tabId == 1) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 1; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 353 && super.mouseX <= frameWidth - 322) { + if (tabId == 2) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 2; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 321 && super.mouseX <= frameWidth - 290) { + if (tabId == 3) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 3; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 289 && super.mouseX <= frameWidth - 258) { + if (tabId == 4) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 4; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 257 && super.mouseX <= frameWidth - 226) { + if (tabId == 5) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 5; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 225 && super.mouseX <= frameWidth - 194) { + if (tabId == 6) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 6; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 193 && super.mouseX <= frameWidth - 163) { + if (tabId == 8) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 8; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 162 && super.mouseX <= frameWidth - 131) { + if (tabId == 9) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 9; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 130 && super.mouseX <= frameWidth - 99) { + if (tabId == 7) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 7; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 98 && super.mouseX <= frameWidth - 67) { + if (tabId == 11) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 11; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 66 && super.mouseX <= frameWidth - 45) { + if (tabId == 12) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 12; + tabAreaAltered = true; + } + if (super.mouseX >= frameWidth - 31 && super.mouseX <= frameWidth) { + if (tabId == 13) { + showTabComponents = !showTabComponents; + } else { + showTabComponents = true; + } + tabId = 13; + tabAreaAltered = true; + } + } + } + } + } + + private void setupGameplayScreen() { + if (chatboxImageProducer != null) { + return; + } + + nullLoader(); + super.fullGameScreen = null; + topLeft1BackgroundTile = null; + bottomLeft1BackgroundTile = null; + loginBoxImageProducer = null; + loginScreenAccessories = null; + flameLeftBackground = null; + flameRightBackground = null; + bottomLeft0BackgroundTile = null; + bottomRightImageProducer = null; + loginMusicImageProducer = null; + middleLeft1BackgroundTile = null; + aRSImageProducer_1115 = null; + chatboxImageProducer = new ProducingGraphicsBuffer(519, 165);// chatback + minimapImageProducer = new ProducingGraphicsBuffer(249, 168);// mapback + Rasterizer2D.clear(); + SpriteCache.lookup(19).drawSprite(0, 0); + tabImageProducer = new ProducingGraphicsBuffer(249, 335);// inventory + gameScreenImageProducer = new ProducingGraphicsBuffer(512, 334);// gamescreen + Rasterizer2D.clear(); + chatSettingImageProducer = new ProducingGraphicsBuffer(249, 45); + welcomeScreenRaised = true; + } + + private void refreshMinimap(Sprite sprite, int j, int k) { + int l = k * k + j * j; + if (l > 4225 && l < 0x15f90) { + int i1 = cameraHorizontal + minimapRotation & 0x7ff; + int j1 = Model.SINE[i1]; + int k1 = Model.COSINE[i1]; + j1 = (j1 * 256) / (minimapZoom + 256); + k1 = (k1 * 256) / (minimapZoom + 256); + } else { + markMinimap(sprite, k, j); + } + } + + public void rightClickChatButtons() { + if (mouseY >= frameHeight - 22 && mouseY <= frameHeight) { + if (super.mouseX >= 5 && super.mouseX <= 61) { + menuActionText[1] = "View All"; + menuActionTypes[1] = 999; + menuActionRow = 2; + } else if (super.mouseX >= 71 && super.mouseX <= 127) { + menuActionText[1] = "View Game"; + menuActionTypes[1] = 998; + menuActionRow = 2; + } else if (super.mouseX >= 137 && super.mouseX <= 193) { + menuActionText[1] = "Hide public"; + menuActionTypes[1] = 997; + menuActionText[2] = "Off public"; + menuActionTypes[2] = 996; + menuActionText[3] = "Friends public"; + menuActionTypes[3] = 995; + menuActionText[4] = "On public"; + menuActionTypes[4] = 994; + menuActionText[5] = "View public"; + menuActionTypes[5] = 993; + menuActionRow = 6; + } else if (super.mouseX >= 203 && super.mouseX <= 259) { + menuActionText[1] = "Off private"; + menuActionTypes[1] = 992; + menuActionText[2] = "Friends private"; + menuActionTypes[2] = 991; + menuActionText[3] = "On private"; + menuActionTypes[3] = 990; + menuActionText[4] = "View private"; + menuActionTypes[4] = 989; + menuActionRow = 5; + } else if (super.mouseX >= 269 && super.mouseX <= 325) { + menuActionText[1] = "Off clan chat"; + menuActionTypes[1] = 1003; + menuActionText[2] = "Friends clan chat"; + menuActionTypes[2] = 1002; + menuActionText[3] = "On clan chat"; + menuActionTypes[3] = 1001; + menuActionText[4] = "View clan chat"; + menuActionTypes[4] = 1000; + menuActionRow = 5; + } else if (super.mouseX >= 335 && super.mouseX <= 391) { + menuActionText[1] = "Off trade"; + menuActionTypes[1] = 987; + menuActionText[2] = "Friends trade"; + menuActionTypes[2] = 986; + menuActionText[3] = "On trade"; + menuActionTypes[3] = 985; + menuActionText[4] = "View trade"; + menuActionTypes[4] = 984; + menuActionRow = 5; + } else if (super.mouseX >= 404 && super.mouseX <= 515) { + menuActionText[1] = "Report Abuse"; + menuActionTypes[1] = 606; + menuActionRow = 2; + } + } + } + + public void processRightClick() { + if (activeInterfaceType != 0) { + return; + } + menuActionText[0] = "Cancel"; + menuActionTypes[0] = 1107; + menuActionRow = 1; + if (showChatComponents) { + buildSplitPrivateChatMenu(); + } + anInt886 = 0; + anInt1315 = 0; + if (frameMode == ScreenMode.FIXED) { + if (super.mouseX > 4 && super.mouseY > 4 && super.mouseX < 516 && super.mouseY < 338) { + if (openInterfaceId != -1) { + buildInterfaceMenu(4, Widget.interfaceCache[openInterfaceId], super.mouseX, 4, super.mouseY, 0); + } else { + createMenu(); + } + } + } else if (frameMode != ScreenMode.FIXED) { + if (getMousePositions()) { + if (super.mouseX > (frameWidth / 2) - 356 && super.mouseY > (frameHeight / 2) - 230 + && super.mouseX < ((frameWidth / 2) + 356) && super.mouseY < (frameHeight / 2) + 230 + && openInterfaceId != -1) { + buildInterfaceMenu((frameWidth / 2) - 356, Widget.interfaceCache[openInterfaceId], super.mouseX, + (frameHeight / 2) - 230, super.mouseY, 0); + } else { + createMenu(); + } + } + } + if (anInt886 != anInt1026) { + anInt1026 = anInt886; + } + if (anInt1315 != anInt1129) { + anInt1129 = anInt1315; + } + anInt886 = 0; + anInt1315 = 0; + if (!changeTabArea) { + final int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 503; + final int xOffset = frameMode == ScreenMode.FIXED ? 0 : frameWidth - 765; + if (super.mouseX > 548 + xOffset && super.mouseX < 740 + xOffset && super.mouseY > 207 + yOffset + && super.mouseY < 468 + yOffset) { + if (overlayInterfaceId != -1) { + buildInterfaceMenu(548 + xOffset, Widget.interfaceCache[overlayInterfaceId], super.mouseX, + 207 + yOffset, super.mouseY, 0); + } else if (tabInterfaceIDs[tabId] != -1) { + buildInterfaceMenu(548 + xOffset, Widget.interfaceCache[tabInterfaceIDs[tabId]], super.mouseX, + 207 + yOffset, super.mouseY, 0); + } + } + } else if (changeTabArea) { + final int yOffset = frameWidth >= 1000 ? 37 : 74; + if (super.mouseX > frameWidth - 197 && super.mouseY > frameHeight - yOffset - 267 + && super.mouseX < frameWidth - 7 && super.mouseY < frameHeight - yOffset - 7 && showTabComponents) { + if (overlayInterfaceId != -1) { + buildInterfaceMenu(frameWidth - 197, Widget.interfaceCache[overlayInterfaceId], super.mouseX, + frameHeight - yOffset - 267, super.mouseY, 0); + } else if (tabInterfaceIDs[tabId] != -1) { + buildInterfaceMenu(frameWidth - 197, Widget.interfaceCache[tabInterfaceIDs[tabId]], super.mouseX, + frameHeight - yOffset - 267, super.mouseY, 0); + } + } + } + if (anInt886 != anInt1048) { + tabAreaAltered = true; + anInt1048 = anInt886; + } + if (anInt1315 != anInt1044) { + tabAreaAltered = true; + anInt1044 = anInt1315; + } + anInt886 = 0; + anInt1315 = 0; + if (super.mouseX > 0 && super.mouseY > (frameMode == ScreenMode.FIXED ? 338 : frameHeight - 165) + && super.mouseX < 490 && super.mouseY < (frameMode == ScreenMode.FIXED ? 463 : frameHeight - 40) + && showChatComponents) { + if (backDialogueId != -1) { + buildInterfaceMenu(20, Widget.interfaceCache[backDialogueId], super.mouseX, + (frameMode == ScreenMode.FIXED ? 358 : frameHeight - 145), super.mouseY, 0); + } else if (super.mouseY < (frameMode == ScreenMode.FIXED ? 463 : frameHeight - 40) && super.mouseX < 490) { + buildChatAreaMenu(super.mouseY - (frameMode == ScreenMode.FIXED ? 338 : frameHeight - 165)); + } + } + if (backDialogueId != -1 && anInt886 != anInt1039) { + updateChatbox = true; + anInt1039 = anInt886; + } + if (backDialogueId != -1 && anInt1315 != anInt1500) { + updateChatbox = true; + anInt1500 = anInt1315; + } + if (super.mouseX > 4 && super.mouseY > 480 && super.mouseX < 516 && super.mouseY < frameHeight) { + rightClickChatButtons(); + } + processMinimapActions(); + boolean flag = false; + while (!flag) { + flag = true; + for (int j = 0; j < menuActionRow - 1; j++) { + if (menuActionTypes[j] < 1000 && menuActionTypes[j + 1] > 1000) { + String s = menuActionText[j]; + menuActionText[j] = menuActionText[j + 1]; + menuActionText[j + 1] = s; + int k = menuActionTypes[j]; + menuActionTypes[j] = menuActionTypes[j + 1]; + menuActionTypes[j + 1] = k; + k = firstMenuAction[j]; + firstMenuAction[j] = firstMenuAction[j + 1]; + firstMenuAction[j + 1] = k; + k = secondMenuAction[j]; + secondMenuAction[j] = secondMenuAction[j + 1]; + secondMenuAction[j + 1] = k; + k = selectedMenuActions[j]; + selectedMenuActions[j] = selectedMenuActions[j + 1]; + selectedMenuActions[j + 1] = k; + flag = false; + } + } + } + } + + private int method83(int i, int j, int k) { + int l = 256 - k; + return ((i & 0xff00ff) * l + (j & 0xff00ff) * k & 0xff00ff00) + + ((i & 0xff00) * l + (j & 0xff00) * k & 0xff0000) >> 8; + } + + /** + * The login method for the 317 protocol. + * + * @param name The name of the user trying to login. + * @param password The password of the user trying to login. + * @param reconnecting The flag for the user indicating to attempt to reconnect. + */ + private void login(String name, String password, boolean reconnecting) { + SignLink.setError(name); + try { + if (!reconnecting) { + firstLoginMessage = ""; + secondLoginMessage = "Connecting to server..."; + drawLoginScreen(true); + } + socketStream = new BufferedConnection(this, openSocket(43594)); + long encoded = StringUtils.encodeBase37(name); + int nameHash = (int) (encoded >> 16 & 31L); + outgoing.currentPosition = 0; + + outgoing.writeByte(14); + outgoing.writeByte(nameHash); + socketStream.queueBytes(2, outgoing.payload); + + for (int j = 0; j < 8; j++) { + socketStream.read(); + } + /* + * Returns numeric values indicated the state of a users login + * session. + */ + int response = socketStream.read(); + int copy = response; + + if (response == 0) { + socketStream.flushInputStream(incoming.payload, 8); + incoming.currentPosition = 0; + serverSeed = incoming.readLong(); // aka server session key + int[] seed = new int[4]; + seed[0] = (int) (Math.random() * 99999999D); + seed[1] = (int) (Math.random() * 99999999D); + seed[2] = (int) (serverSeed >> 32); + seed[3] = (int) serverSeed; + outgoing.currentPosition = 0; + outgoing.writeByte(10); + outgoing.writeInt(seed[0]); + outgoing.writeInt(seed[1]); + outgoing.writeInt(seed[2]); + outgoing.writeInt(seed[3]); + outgoing.writeInt(314268572); + outgoing.writeString(name); + outgoing.writeString(password); + outgoing.encodeRSA(Configuration.RSA_EXPONENT, Configuration.RSA_MODULUS); + login.currentPosition = 0; + login.writeByte( + reconnecting ? ProtocolConstants.RECONNECTION_OPCODE : ProtocolConstants.NEW_CONNECTION_OPCODE); + login.writeByte(outgoing.currentPosition + 36 + 1 + 1 + 2); // size + + login.writeByte(255); + login.writeShort(1); + + login.writeByte(0); // client version + + for (int index = 0; index < 9; index++) { + login.writeInt(archiveCRCs[index]); + } + + login.writeBytes(outgoing.payload, outgoing.currentPosition, 0); + outgoing.encryption = new IsaacCipher(seed); + for (int index = 0; index < 4; index++) + seed[index] += 50; + + encryption = new IsaacCipher(seed); + socketStream.queueBytes(login.currentPosition, login.payload); + response = socketStream.read(); + } + if (response == 1) { + try { + Thread.sleep(2000L); + } catch (Exception _ex) { + } + login(name, password, reconnecting); + return; + } + if (response == 2) { + myPrivilege = socketStream.read(); + flagged = socketStream.read() == 1; + aLong1220 = 0L; + duplicateClickCount = 0; + mouseDetection.coordsIndex = 0; + super.awtFocus = true; + aBoolean954 = true; + loggedIn = true; + outgoing.currentPosition = 0; + incoming.currentPosition = 0; + opcode = -1; + lastOpcode = -1; + secondLastOpcode = -1; + thirdLastOpcode = -1; + packetSize = 0; + timeoutCounter = 0; + systemUpdateTime = 0; + anInt1011 = 0; + hintIconDrawType = 0; + menuActionRow = 0; + menuOpen = false; + super.idleTime = 0; + for (int index = 0; index < 100; index++) + chatMessages[index] = null; + itemSelected = 0; + spellSelected = 0; + loadingStage = 0; + trackCount = 0; + setNorth(); + minimapState = 0; + anInt985 = -1; + destinationX = 0; + destY = 0; + playerCount = 0; + npcCount = 0; + for (int index = 0; index < maxPlayers; index++) { + players[index] = null; + playerSynchronizationBuffers[index] = null; + } + for (int index = 0; index < 16384; index++) + npcs[index] = null; + localPlayer = players[internalLocalPlayerIndex] = new Player(); + projectiles.clear(); + incompleteAnimables.clear(); + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 104; x++) { + for (int y = 0; y < 104; y++) + groundItems[z][x][y] = null; + } + } + spawns = new Deque(); + fullscreenInterfaceID = -1; + friendServerStatus = 0; + friendsCount = 0; + dialogueId = -1; + backDialogueId = -1; + openInterfaceId = -1; + overlayInterfaceId = -1; + openWalkableInterface = -1; + continuedDialogue = false; + tabId = 3; + inputDialogState = 0; + menuOpen = false; + messagePromptRaised = false; + clickToContinueString = null; + multicombat = 0; + flashingSidebarId = -1; + maleCharacter = true; + changeCharacterGender(); + for (int index = 0; index < 5; index++) + characterDesignColours[index] = 0; + for (int index = 0; index < 5; index++) { + playerOptions[index] = null; + playerOptionsHighPriority[index] = false; + } + anInt1175 = 0; + anInt1134 = 0; + anInt986 = 0; + anInt1288 = 0; + anInt924 = 0; + anInt1188 = 0; + anInt1155 = 0; + anInt1226 = 0; + sendConfiguration(429, 1); + this.stopMidi(); + setupGameplayScreen(); + return; + } + if (response == 3) { + firstLoginMessage = ""; + secondLoginMessage = "Invalid username or password."; + return; + } + if (response == 4) { + firstLoginMessage = "Your account has been disabled."; + secondLoginMessage = "Please check your defaultText-center for details."; + return; + } + if (response == 5) { + firstLoginMessage = "Your account is already logged in."; + secondLoginMessage = "Try again in 60 secs..."; + return; + } + if (response == 6) { + firstLoginMessage = Configuration.CLIENT_NAME + " has been updated!"; + secondLoginMessage = "Please reload this page."; + return; + } + if (response == 7) { + firstLoginMessage = "This world is full."; + secondLoginMessage = "Please use a different world."; + return; + } + if (response == 8) { + firstLoginMessage = "Unable to connect."; + secondLoginMessage = "Login server offline."; + return; + } + if (response == 9) { + firstLoginMessage = "Login limit exceeded."; + secondLoginMessage = "Too many connections from your address."; + return; + } + if (response == 10) { + firstLoginMessage = "Unable to connect."; + secondLoginMessage = "Bad session id."; + return; + } + if (response == 11) { + secondLoginMessage = "Login server rejected session."; + secondLoginMessage = "Please try again."; + return; + } + if (response == 12) { + firstLoginMessage = "You need a members account to login to this world."; + secondLoginMessage = "Please subscribe, or use a different world."; + return; + } + if (response == 13) { + firstLoginMessage = "Could not complete login."; + secondLoginMessage = "Please try using a different world."; + return; + } + if (response == 14) { + firstLoginMessage = "The server is being updated."; + secondLoginMessage = "Please wait 1 minute and try again."; + return; + } + if (response == 15) { + loggedIn = true; + outgoing.currentPosition = 0; + incoming.currentPosition = 0; + opcode = -1; + lastOpcode = -1; + secondLastOpcode = -1; + thirdLastOpcode = -1; + packetSize = 0; + timeoutCounter = 0; + systemUpdateTime = 0; + menuActionRow = 0; + menuOpen = false; + loadingStartTime = System.currentTimeMillis(); + return; + } + if (response == 16) { + firstLoginMessage = "Login attempts exceeded."; + secondLoginMessage = "Please wait 1 minute and try again."; + return; + } + if (response == 17) { + firstLoginMessage = "You are standing in a members-only area."; + secondLoginMessage = "To play on this world move to a free area first"; + return; + } + if (response == 20) { + firstLoginMessage = "Invalid loginserver requested"; + secondLoginMessage = "Please try using a different world."; + return; + } + if (response == 21) { + for (int k1 = socketStream.read(); k1 >= 0; k1--) { + firstLoginMessage = "You have only just left another world"; + secondLoginMessage = "Your profile will be transferred in: " + k1 + " seconds"; + drawLoginScreen(true); + try { + Thread.sleep(1000L); + } catch (Exception _ex) { + } + } + login(name, password, reconnecting); + return; + } + if (response == 22) { + firstLoginMessage = "Your computer has been UUID banned."; + secondLoginMessage = "Please appeal on the forums."; + return; + } + if (response == -1) { + if (copy == 0) { + if (loginFailures < 2) { + try { + Thread.sleep(2000L); + } catch (Exception _ex) { + } + loginFailures++; + login(name, password, reconnecting); + return; + } else { + firstLoginMessage = "No response from loginserver"; + secondLoginMessage = "Please wait 1 minute and try again."; + return; + } + } else { + firstLoginMessage = "No response from server"; + secondLoginMessage = "Please try using a different world."; + return; + } + } else { + System.out.println("response:" + response); + firstLoginMessage = "Unexpected server response"; + secondLoginMessage = "Please try using a different world."; + return; + } + } catch (IOException _ex) { + firstLoginMessage = ""; + } catch (Exception e) { + System.out.println("Error while generating uid. Skipping step."); + e.printStackTrace(); + } + secondLoginMessage = "Error connecting to server."; + } + + private boolean doWalkTo(int type, int j, int k, int i1, int j1, int k1, int l1, int i2, int j2, boolean flag, + int k2) { + byte byte0 = 104; + byte byte1 = 104; + for (int l2 = 0; l2 < byte0; l2++) { + for (int i3 = 0; i3 < byte1; i3++) { + anIntArrayArray901[l2][i3] = 0; + anIntArrayArray825[l2][i3] = 0x5f5e0ff; + } + } + int j3 = j2; + int k3 = j1; + anIntArrayArray901[j2][j1] = 99; + anIntArrayArray825[j2][j1] = 0; + int l3 = 0; + int i4 = 0; + bigX[l3] = j2; + bigY[l3++] = j1; + boolean flag1 = false; + int j4 = bigX.length; + int[][] ai = collisionMaps[plane].adjacencies; + while (i4 != l3) { + j3 = bigX[i4]; + k3 = bigY[i4]; + i4 = (i4 + 1) % j4; + if (j3 == k2 && k3 == i2) { + flag1 = true; + break; + } + if (i1 != 0) { + if ((i1 < 5 || i1 == 10) && collisionMaps[plane].method219(k2, j3, k3, j, i1 - 1, i2)) { + flag1 = true; + break; + } + if (i1 < 10 && collisionMaps[plane].method220(k2, i2, k3, i1 - 1, j, j3)) { + flag1 = true; + break; + } + } + if (k1 != 0 && k != 0 && collisionMaps[plane].method221(i2, k2, j3, k, l1, k1, k3)) { + flag1 = true; + break; + } + int l4 = anIntArrayArray825[j3][k3] + 1; + if (j3 > 0 && anIntArrayArray901[j3 - 1][k3] == 0 && (ai[j3 - 1][k3] & 0x1280108) == 0) { + bigX[l3] = j3 - 1; + bigY[l3] = k3; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3 - 1][k3] = 2; + anIntArrayArray825[j3 - 1][k3] = l4; + } + if (j3 < byte0 - 1 && anIntArrayArray901[j3 + 1][k3] == 0 && (ai[j3 + 1][k3] & 0x1280180) == 0) { + bigX[l3] = j3 + 1; + bigY[l3] = k3; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3 + 1][k3] = 8; + anIntArrayArray825[j3 + 1][k3] = l4; + } + if (k3 > 0 && anIntArrayArray901[j3][k3 - 1] == 0 && (ai[j3][k3 - 1] & 0x1280102) == 0) { + bigX[l3] = j3; + bigY[l3] = k3 - 1; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3][k3 - 1] = 1; + anIntArrayArray825[j3][k3 - 1] = l4; + } + if (k3 < byte1 - 1 && anIntArrayArray901[j3][k3 + 1] == 0 && (ai[j3][k3 + 1] & 0x1280120) == 0) { + bigX[l3] = j3; + bigY[l3] = k3 + 1; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3][k3 + 1] = 4; + anIntArrayArray825[j3][k3 + 1] = l4; + } + if (j3 > 0 && k3 > 0 && anIntArrayArray901[j3 - 1][k3 - 1] == 0 && (ai[j3 - 1][k3 - 1] & 0x128010e) == 0 + && (ai[j3 - 1][k3] & 0x1280108) == 0 && (ai[j3][k3 - 1] & 0x1280102) == 0) { + bigX[l3] = j3 - 1; + bigY[l3] = k3 - 1; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3 - 1][k3 - 1] = 3; + anIntArrayArray825[j3 - 1][k3 - 1] = l4; + } + if (j3 < byte0 - 1 && k3 > 0 && anIntArrayArray901[j3 + 1][k3 - 1] == 0 + && (ai[j3 + 1][k3 - 1] & 0x1280183) == 0 && (ai[j3 + 1][k3] & 0x1280180) == 0 + && (ai[j3][k3 - 1] & 0x1280102) == 0) { + bigX[l3] = j3 + 1; + bigY[l3] = k3 - 1; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3 + 1][k3 - 1] = 9; + anIntArrayArray825[j3 + 1][k3 - 1] = l4; + } + if (j3 > 0 && k3 < byte1 - 1 && anIntArrayArray901[j3 - 1][k3 + 1] == 0 + && (ai[j3 - 1][k3 + 1] & 0x1280138) == 0 && (ai[j3 - 1][k3] & 0x1280108) == 0 + && (ai[j3][k3 + 1] & 0x1280120) == 0) { + bigX[l3] = j3 - 1; + bigY[l3] = k3 + 1; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3 - 1][k3 + 1] = 6; + anIntArrayArray825[j3 - 1][k3 + 1] = l4; + } + if (j3 < byte0 - 1 && k3 < byte1 - 1 && anIntArrayArray901[j3 + 1][k3 + 1] == 0 + && (ai[j3 + 1][k3 + 1] & 0x12801e0) == 0 && (ai[j3 + 1][k3] & 0x1280180) == 0 + && (ai[j3][k3 + 1] & 0x1280120) == 0) { + bigX[l3] = j3 + 1; + bigY[l3] = k3 + 1; + l3 = (l3 + 1) % j4; + anIntArrayArray901[j3 + 1][k3 + 1] = 12; + anIntArrayArray825[j3 + 1][k3 + 1] = l4; + } + } + anInt1264 = 0; + if (!flag1) { + if (flag) { + int i5 = 100; + for (int k5 = 1; k5 < 2; k5++) { + for (int i6 = k2 - k5; i6 <= k2 + k5; i6++) { + for (int l6 = i2 - k5; l6 <= i2 + k5; l6++) { + if (i6 >= 0 && l6 >= 0 && i6 < 104 && l6 < 104 && anIntArrayArray825[i6][l6] < i5) { + i5 = anIntArrayArray825[i6][l6]; + j3 = i6; + k3 = l6; + anInt1264 = 1; + flag1 = true; + } + } + } + if (flag1) + break; + } + } + if (!flag1) + return false; + } + i4 = 0; + bigX[i4] = j3; + bigY[i4++] = k3; + int l5; + for (int j5 = l5 = anIntArrayArray901[j3][k3]; j3 != j2 || k3 != j1; j5 = anIntArrayArray901[j3][k3]) { + if (j5 != l5) { + l5 = j5; + bigX[i4] = j3; + bigY[i4++] = k3; + } + if ((j5 & 2) != 0) + j3++; + else if ((j5 & 8) != 0) + j3--; + if ((j5 & 1) != 0) + k3++; + else if ((j5 & 4) != 0) + k3--; + } + if (i4 > 0) { + int k4 = i4; + if (k4 > 25) + k4 = 25; + i4--; + int k6 = bigX[i4]; + int i7 = bigY[i4]; + anInt1288 += k4; + if (anInt1288 >= 92) { + // TODO unknown (anti-cheat) + outgoing.writeOpcode(36); + outgoing.writeInt(0); + anInt1288 = 0; + } + if (type == 0) { + // regular walk + outgoing.writeOpcode(164); + outgoing.writeByte(k4 + k4 + 3); + } + if (type == 1) { + // map walk + outgoing.writeOpcode(248); + outgoing.writeByte(k4 + k4 + 3 + 14); + } + if (type == 2) { + // walk on command + outgoing.writeOpcode(98); + outgoing.writeByte(k4 + k4 + 3); + } + outgoing.writeLEShortA(k6 + regionBaseX); + destinationX = bigX[0]; + destY = bigY[0]; + for (int j7 = 1; j7 < k4; j7++) { + i4--; + outgoing.writeByte(bigX[i4] - k6); + outgoing.writeByte(bigY[i4] - i7); + } + outgoing.writeLEShort(i7 + regionBaseY); + outgoing.writeNegatedByte(super.keyArray[5] != 1 ? 0 : 1); + return true; + } + return type != 1; + } + + private void npcUpdateMask(Buffer stream) { + for (int j = 0; j < mobsAwaitingUpdateCount; j++) { + int k = mobsAwaitingUpdate[j]; + Npc npc = npcs[k]; + int mask = stream.readUnsignedByte(); + if ((mask & 0x10) != 0) { + int i1 = stream.readLEUShort(); + if (i1 == 65535) + i1 = -1; + int i2 = stream.readUnsignedByte(); + if (i1 == npc.emoteAnimation && i1 != -1) { + int l2 = Animation.animations[i1].replayMode; + if (l2 == 1) { + npc.displayedEmoteFrames = 0; + npc.emoteTimeRemaining = 0; + npc.animationDelay = i2; + npc.currentAnimationLoops = 0; + } + if (l2 == 2) + npc.currentAnimationLoops = 0; + } else if (i1 == -1 || npc.emoteAnimation == -1 + || Animation.animations[i1].priority >= Animation.animations[npc.emoteAnimation].priority) { + npc.emoteAnimation = i1; + npc.displayedEmoteFrames = 0; + npc.emoteTimeRemaining = 0; + npc.animationDelay = i2; + npc.currentAnimationLoops = 0; + npc.anInt1542 = npc.remainingPath; + } + } + if ((mask & 8) != 0) { + int damage = stream.readUByteA(); + int type = stream.readNegUByte(); + npc.updateHitData(type, damage, tick); + npc.loopCycleStatus = tick + 300; + npc.currentHealth = stream.readUByteA(); + npc.maxHealth = stream.readUnsignedByte(); + } + if ((mask & 0x80) != 0) { + npc.graphic = stream.readUShort(); + int k1 = stream.readInt(); + npc.graphicHeight = k1 >> 16; + npc.graphicDelay = tick + (k1 & 0xffff); + npc.currentAnimation = 0; + npc.anInt1522 = 0; + if (npc.graphicDelay > tick) + npc.currentAnimation = -1; + if (npc.graphic == 65535) + npc.graphic = -1; + } + if ((mask & 0x20) != 0) { + npc.interactingEntity = stream.readUShort(); + if (npc.interactingEntity == 65535) + npc.interactingEntity = -1; + } + if ((mask & 1) != 0) { + npc.spokenText = stream.readString(); + npc.textCycle = 100; + } + if ((mask & 0x40) != 0) { + int damage = stream.readNegUByte(); + int type = stream.readUByteS(); + npc.updateHitData(type, damage, tick); + npc.loopCycleStatus = tick + 300; + npc.currentHealth = stream.readUByteS(); + npc.maxHealth = stream.readNegUByte(); + } + if ((mask & 2) != 0) { + npc.desc = NpcDefinition.lookup(stream.readLEUShortA()); + npc.size = npc.desc.size; + npc.degreesToTurn = npc.desc.degreesToTurn; + npc.walkAnimIndex = npc.desc.walkAnim; + npc.turn180AnimIndex = npc.desc.turn180AnimIndex; + npc.turn90CWAnimIndex = npc.desc.turn90CWAnimIndex; + npc.turn90CCWAnimIndex = npc.desc.turn90CCWAnimIndex; + npc.idleAnimation = npc.desc.standAnim; + } + if ((mask & 4) != 0) { + npc.faceX = stream.readLEUShort(); + npc.faceY = stream.readLEUShort(); + } + } + } + + private void buildAtNPCMenu(NpcDefinition entityDef, int i, int j, int k) { + if (openInterfaceId == 15244) { + return; + } + if (menuActionRow >= 400) + return; + if (entityDef.childrenIDs != null) + entityDef = entityDef.morph(); + if (entityDef == null) + return; + if (!entityDef.clickable) + return; + String s = entityDef.name; + + if (entityDef.combatLevel != 0) + s = s + combatDiffColor(localPlayer.combatLevel, entityDef.combatLevel) + " (level-" + entityDef.combatLevel + + ")"; + if (itemSelected == 1) { + menuActionText[menuActionRow] = "Use " + selectedItemName + " with @yel@" + s; + menuActionTypes[menuActionRow] = 582; + selectedMenuActions[menuActionRow] = i; + firstMenuAction[menuActionRow] = k; + secondMenuAction[menuActionRow] = j; + menuActionRow++; + return; + } + if (spellSelected == 1) { + if ((spellUsableOn & 2) == 2) { + menuActionText[menuActionRow] = spellTooltip + " @yel@" + s; + menuActionTypes[menuActionRow] = 413; + selectedMenuActions[menuActionRow] = i; + firstMenuAction[menuActionRow] = k; + secondMenuAction[menuActionRow] = j; + menuActionRow++; + } + } else { + if (entityDef.actions != null) { + for (int l = 4; l >= 0; l--) + if (entityDef.actions[l] != null && !entityDef.actions[l].equalsIgnoreCase("attack")) { + menuActionText[menuActionRow] = entityDef.actions[l] + " @yel@" + s; + if (l == 0) + menuActionTypes[menuActionRow] = 20; + if (l == 1) + menuActionTypes[menuActionRow] = 412; + if (l == 2) + menuActionTypes[menuActionRow] = 225; + if (l == 3) + menuActionTypes[menuActionRow] = 965; + if (l == 4) + menuActionTypes[menuActionRow] = 478; + selectedMenuActions[menuActionRow] = i; + firstMenuAction[menuActionRow] = k; + secondMenuAction[menuActionRow] = j; + menuActionRow++; + } + + } + if (entityDef.actions != null) { + for (int i1 = 4; i1 >= 0; i1--) + if (entityDef.actions[i1] != null && entityDef.actions[i1].equalsIgnoreCase("attack")) { + char c = '\0'; + if (entityDef.combatLevel > localPlayer.combatLevel) + c = '\u07D0'; + menuActionText[menuActionRow] = entityDef.actions[i1] + " @yel@" + s; + if (i1 == 0) + menuActionTypes[menuActionRow] = 20 + c; + if (i1 == 1) + menuActionTypes[menuActionRow] = 412 + c; + if (i1 == 2) + menuActionTypes[menuActionRow] = 225 + c; + if (i1 == 3) + menuActionTypes[menuActionRow] = 965 + c; + if (i1 == 4) + menuActionTypes[menuActionRow] = 478 + c; + selectedMenuActions[menuActionRow] = i; + firstMenuAction[menuActionRow] = k; + secondMenuAction[menuActionRow] = j; + menuActionRow++; + } + + } + if (Configuration.enableIds && (myPrivilege >= 2 && myPrivilege <= 3)) { + menuActionText[menuActionRow] = "Examine @yel@" + s + " @gre@(@whi@" + entityDef.interfaceType + + "@gre@)"; + } else { + menuActionText[menuActionRow] = "Examine @yel@" + s; + } + menuActionTypes[menuActionRow] = 1025; + selectedMenuActions[menuActionRow] = i; + firstMenuAction[menuActionRow] = k; + secondMenuAction[menuActionRow] = j; + menuActionRow++; + } + } + + private void buildAtPlayerMenu(int i, int j, Player player, int k) { + if (openInterfaceId == 15244) { + return; + } + if (player == localPlayer) + return; + if (menuActionRow >= 400) + return; + String s; + if (player.skill == 0) + s = player.name + combatDiffColor(localPlayer.combatLevel, player.combatLevel) + " (level-" + + player.combatLevel + ")"; + else + s = player.name + " (skill-" + player.skill + ")"; + if (itemSelected == 1) { + menuActionText[menuActionRow] = "Use " + selectedItemName + " with @whi@" + s; + menuActionTypes[menuActionRow] = 491; + selectedMenuActions[menuActionRow] = j; + firstMenuAction[menuActionRow] = i; + secondMenuAction[menuActionRow] = k; + menuActionRow++; + } else if (spellSelected == 1) { + if ((spellUsableOn & 8) == 8) { + menuActionText[menuActionRow] = spellTooltip + " @whi@" + s; + menuActionTypes[menuActionRow] = 365; + selectedMenuActions[menuActionRow] = j; + firstMenuAction[menuActionRow] = i; + secondMenuAction[menuActionRow] = k; + menuActionRow++; + } + } else { + for (int type = 4; type >= 0; type--) { + if (playerOptions[type] != null) { + menuActionText[menuActionRow] = playerOptions[type] + " @whi@" + s; + char c = '\0'; + if (playerOptions[type].equalsIgnoreCase("attack")) { + if (player.combatLevel > localPlayer.combatLevel) + c = '\u07D0'; + if (localPlayer.team != 0 && player.team != 0) + if (localPlayer.team == player.team) { + c = '\u07D0'; + } else { + c = '\0'; + } + } else if (playerOptionsHighPriority[type]) + c = '\u07D0'; + if (type == 0) { + menuActionTypes[menuActionRow] = 561 + c; + } + if (type == 1) { + menuActionTypes[menuActionRow] = 779 + c; + } + if (type == 2) { + menuActionTypes[menuActionRow] = 27 + c; + } + if (type == 3) { + menuActionTypes[menuActionRow] = 577 + c; + } + if (type == 4) { + menuActionTypes[menuActionRow] = 729 + c; + } + selectedMenuActions[menuActionRow] = j; + firstMenuAction[menuActionRow] = i; + secondMenuAction[menuActionRow] = k; + menuActionRow++; + } + } + } + for (int row = 0; row < menuActionRow; row++) { + if (menuActionTypes[row] == 519) { + menuActionText[row] = "Walk here @whi@" + s; + return; + } + } + } + + private void method89(SpawnedObject class30_sub1) { + int i = 0; + int j = -1; + int k = 0; + int l = 0; + if (class30_sub1.group == 0) + i = scene.getWallObjectUid(class30_sub1.plane, class30_sub1.x, class30_sub1.y); + if (class30_sub1.group == 1) + i = scene.getWallDecorationUid(class30_sub1.plane, class30_sub1.x, class30_sub1.y); + if (class30_sub1.group == 2) + i = scene.getGameObjectUid(class30_sub1.plane, class30_sub1.x, class30_sub1.y); + if (class30_sub1.group == 3) + i = scene.getGroundDecorationUid(class30_sub1.plane, class30_sub1.x, class30_sub1.y); + if (i != 0) { + int i1 = scene.getMask(class30_sub1.plane, class30_sub1.x, class30_sub1.y, i); + j = i >> 14 & 0x7fff; + k = i1 & 0x1f; + l = i1 >> 6; + } + class30_sub1.getPreviousId = j; + class30_sub1.previousType = k; + class30_sub1.previousOrientation = l; + } + + void startUp() { + drawLoadingText(20, "Starting up"); + SpriteCache.load(); + if (SignLink.cache_dat != null) { + for (int i = 0; i < 5; i++) + indices[i] = new FileStore(SignLink.cache_dat, SignLink.indices[i], i + 1); + } + try { + + if (Configuration.useJaggrab) { + requestCrcs(); + } + titleArchive = createArchive(1, "title screen", "title", archiveCRCs[1], 25); + smallText = new GameFont(false, "p11_full", titleArchive); + regularText = new GameFont(false, "p12_full", titleArchive); + boldText = new GameFont(false, "b12_full", titleArchive); + newSmallFont = new RSFont(false, "p11_full", titleArchive); + newRegularFont = new RSFont(false, "p12_full", titleArchive); + newBoldFont = new RSFont(false, "b12_full", titleArchive); + newFancyFont = new RSFont(true, "q8_full", titleArchive); + gameFont = new GameFont(true, "q8_full", titleArchive); + drawLogo(); + loadTitleScreen(); + FileArchive configArchive = createArchive(2, "config", "config", archiveCRCs[2], 30); + FileArchive interfaceArchive = createArchive(3, "interface", "interface", archiveCRCs[3], 35); + FileArchive mediaArchive = createArchive(4, "2d graphics", "media", archiveCRCs[4], 40); + this.mediaStreamLoader = mediaArchive; + FileArchive textureArchive = createArchive(6, "textures", "textures", archiveCRCs[6], 45); + FileArchive wordencArchive = createArchive(7, "chat system", "wordenc", archiveCRCs[7], 50); + + @SuppressWarnings("unused") + FileArchive soundArchive = createArchive(8, "sound effects", "sounds", archiveCRCs[8], 55); + tileFlags = new byte[4][104][104]; + tileHeights = new int[4][105][105]; + scene = new SceneGraph(tileHeights); + + for (int j = 0; j < 4; j++) + collisionMaps[j] = new CollisionMap(); + + minimapImage = new Sprite(512, 512); + FileArchive streamLoader_6 = createArchive(5, "update list", "versionlist", archiveCRCs[5], 60); + drawLoadingText(60, "Connecting to update server"); + resourceProvider = new ResourceProvider(); + resourceProvider.initialize(streamLoader_6, this); + Frame.animationlist = new Frame[2500][0]; + Model.method459(resourceProvider.getModelCount(), resourceProvider); + drawLoadingText(80, "Unpacking media"); + + FileArchive soundEffectArchive = createArchive(8, "sound effects", "sounds", archiveCRCs[8], 55); + byte[] soundData = soundEffectArchive.readFile("sounds.dat"); + + Buffer stream = new Buffer(soundData); + Track.unpack(stream); + + if (Configuration.repackIndexOne) { + CacheUtils.repackCacheIndex(this, Store.MODEL); + } + + if (Configuration.repackIndexTwo) { + CacheUtils.repackCacheIndex(this, Store.ANIMATION); + } + + if (Configuration.repackIndexThree) { + CacheUtils.repackCacheIndex(this, Store.MUSIC); + } + + if (Configuration.repackIndexFour) { + CacheUtils.repackCacheIndex(this, Store.MAP); + } + + if (Configuration.dumpIndexOne) { + CacheUtils.dumpCacheIndex(this, Store.MODEL); + } + + if (Configuration.dumpIndexTwo) { + CacheUtils.dumpCacheIndex(this, Store.ANIMATION); + } + + if (Configuration.dumpIndexThree) { + CacheUtils.dumpCacheIndex(this, Store.MUSIC); + } + + if (Configuration.repackIndexFour) { + CacheUtils.dumpCacheIndex(this, Store.MAP); + } + + for (int imageId = 73, index = 0; imageId < SkillConstants.SKILL_COUNT; imageId++, index++) { + skill_sprites[index] = SpriteCache.lookup(imageId); + } + + Sprite[] clanIcons = new Sprite[9]; + + for (int index = 0; index < clanIcons.length; index++) { + clanIcons[index] = SpriteCache.lookup(index + 218); + } + + RSFont.unpackImages(modIcons, clanIcons); + multiOverlay = new Sprite(mediaArchive, "overlay_multiway", 0); + mapBack = new IndexedImage(mediaArchive, "mapback", 0); + for (int j3 = 0; j3 <= 14; j3++) + sideIcons[j3] = new Sprite(mediaArchive, "sideicons", j3); + compass = new Sprite(mediaArchive, "compass", 0); + try { + for (int k3 = 0; k3 < 100; k3++) + mapScenes[k3] = new IndexedImage(mediaArchive, "mapscene", k3); + } catch (Exception _ex) { + } + try { + for (int l3 = 0; l3 < 100; l3++) + mapFunctions[l3] = new Sprite(mediaArchive, "mapfunction", l3); + } catch (Exception _ex) { + } + try { + for (int i4 = 0; i4 < 20; i4++) + hitMarks[i4] = new Sprite(mediaArchive, "hitmarks", i4); + } catch (Exception _ex) { + } + try { + for (int h1 = 0; h1 < 6; h1++) + headIconsHint[h1] = new Sprite(mediaArchive, "headicons_hint", h1); + } catch (Exception _ex) { + } + try { + for (int j4 = 0; j4 < 8; j4++) + headIcons[j4] = new Sprite(mediaArchive, "headicons_prayer", j4); + for (int j45 = 0; j45 < 3; j45++) + skullIcons[j45] = new Sprite(mediaArchive, "headicons_pk", j45); + } catch (Exception _ex) { + } + mapFlag = new Sprite(mediaArchive, "mapmarker", 0); + mapMarker = new Sprite(mediaArchive, "mapmarker", 1); + for (int k4 = 0; k4 < 8; k4++) + crosses[k4] = new Sprite(mediaArchive, "cross", k4); + mapDotItem = new Sprite(mediaArchive, "mapdots", 0); + mapDotNPC = new Sprite(mediaArchive, "mapdots", 1); + mapDotPlayer = new Sprite(mediaArchive, "mapdots", 2); + mapDotFriend = new Sprite(mediaArchive, "mapdots", 3); + mapDotTeam = new Sprite(mediaArchive, "mapdots", 4); + mapDotClan = new Sprite(mediaArchive, "mapdots", 5); + scrollBar1 = new Sprite(mediaArchive, "scrollbar", 0); + scrollBar2 = new Sprite(mediaArchive, "scrollbar", 1); + for (int l4 = 0; l4 < 2; l4++) + modIcons[l4] = new Sprite(mediaArchive, "mod_icons", l4); + Sprite sprite = new Sprite(mediaArchive, "screenframe", 0); + leftFrame = new ProducingGraphicsBuffer(sprite.getMyWidth(), sprite.getMyHeight()); + sprite.method346(0, 0); + sprite = new Sprite(mediaArchive, "screenframe", 1); + topFrame = new ProducingGraphicsBuffer(sprite.getMyWidth(), sprite.getMyHeight()); + sprite.method346(0, 0); + int i5 = (int) (Math.random() * 21D) - 10; + int j5 = (int) (Math.random() * 21D) - 10; + int k5 = (int) (Math.random() * 21D) - 10; + int l5 = (int) (Math.random() * 41D) - 20; + for (int i6 = 0; i6 < 100; i6++) { + if (mapFunctions[i6] != null) + mapFunctions[i6].method344(i5 + l5, j5 + l5, k5 + l5); + if (mapScenes[i6] != null) + mapScenes[i6].offsetColor(i5 + l5, j5 + l5, k5 + l5); + } + drawLoadingText(83, "Unpacking textures"); + Rasterizer3D.loadTextures(textureArchive); + Rasterizer3D.setBrightness(0.80000000000000004D); + Rasterizer3D.initiateRequestBuffers(); + drawLoadingText(86, "Unpacking config"); + Animation.init(configArchive); + ObjectDefinition.init(configArchive); + FloorDefinition.unpackConfig(configArchive); + ItemDefinition.init(configArchive); + NpcDefinition.init(configArchive); + IdentityKit.init(configArchive); + Graphic.init(configArchive); + Varp.init(configArchive); + Varbit.init(configArchive); + ItemDefinition.isMembers = isMembers; + drawLoadingText(95, "Unpacking interfaces"); + GameFont[] gameFonts = {smallText, regularText, boldText, gameFont}; + Widget.load(interfaceArchive, gameFonts, mediaArchive); + drawLoadingText(100, "Preparing game engine"); + for (int j6 = 0; j6 < 33; j6++) { + int k6 = 999; + int i7 = 0; + for (int k7 = 0; k7 < 34; k7++) { + if (mapBack.palettePixels[k7 + j6 * mapBack.width] == 0) { + if (k6 == 999) + k6 = k7; + continue; + } + if (k6 == 999) + continue; + i7 = k7; + break; + } + anIntArray968[j6] = k6; + anIntArray1057[j6] = i7 - k6; + } + for (int l6 = 1; l6 < 153; l6++) { + int j7 = 999; + int l7 = 0; + for (int j8 = 24; j8 < 177; j8++) { + if (mapBack.palettePixels[j8 + l6 * mapBack.width] == 0 && (j8 > 34 || l6 > 34)) { + if (j7 == 999) { + j7 = j8; + } + continue; + } + if (j7 == 999) { + continue; + } + l7 = j8; + break; + } + minimapLeft[l6 - 1] = j7 - 24; + minimapLineWidth[l6 - 1] = l7 - j7; + } + setBounds(); + MessageCensor.load(wordencArchive); + mouseDetection = new MouseDetection(this); + startRunnable(mouseDetection, 10); + SceneObject.clientInstance = this; + ObjectDefinition.clientInstance = this; + NpcDefinition.clientInstance = this; + return; + } catch (Exception exception) { + exception.printStackTrace(); + SignLink.reporterror("loaderror " + aString1049 + " " + anInt1079); + } + loadingError = true; + } + + private void updatePlayerList(Buffer stream, int packetSize) { + while (stream.bitPosition + 10 < packetSize * 8) { + int index = stream.readBits(11); + if (index == 2047) { + break; + } + if (players[index] == null) { + players[index] = new Player(); + if (playerSynchronizationBuffers[index] != null) { + players[index].updateAppearance(playerSynchronizationBuffers[index]); + } + } + playerList[playerCount++] = index; + Player player = players[index]; + player.time = tick; + + int update = stream.readBits(1); + + if (update == 1) + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = index; + + int discardWalkingQueue = stream.readBits(1); + + int y = stream.readBits(5); + + if (y > 15) { + y -= 32; + } + + int x = stream.readBits(5); + + if (x > 15) { + x -= 32; + } + + player.setPos(localPlayer.pathX[0] + x, localPlayer.pathY[0] + y, discardWalkingQueue == 1); + } + stream.disableBitAccess(); + } + + public boolean inCircle(int circleX, int circleY, int clickX, int clickY, int radius) { + return java.lang.Math.pow((circleX + radius - clickX), 2) + + java.lang.Math.pow((circleY + radius - clickY), 2) < java.lang.Math.pow(radius, 2); + } + + private void processMainScreenClick() { + if (openInterfaceId == 15244) { + return; + } + if (minimapState != 0) { + return; + } + if (super.clickMode3 == 1) { + int i = super.saveClickX - 25 - 547; + int j = super.saveClickY - 5 - 3; + if (frameMode != ScreenMode.FIXED) { + i = super.saveClickX - (frameWidth - 182 + 24); + j = super.saveClickY - 8; + } + if (inCircle(0, 0, i, j, 76) && mouseMapPosition() && !runHover) { + i -= 73; + j -= 75; + int k = cameraHorizontal + minimapRotation & 0x7ff; + int i1 = Rasterizer3D.anIntArray1470[k]; + int j1 = Rasterizer3D.COSINE[k]; + i1 = i1 * (minimapZoom + 256) >> 8; + j1 = j1 * (minimapZoom + 256) >> 8; + int k1 = j * i1 + i * j1 >> 11; + int l1 = j * j1 - i * i1 >> 11; + int i2 = localPlayer.x + k1 >> 7; + int j2 = localPlayer.y - l1 >> 7; + boolean flag1 = doWalkTo(1, 0, 0, 0, localPlayer.pathY[0], 0, 0, j2, localPlayer.pathX[0], true, i2); + if (flag1) { + outgoing.writeByte(i); + outgoing.writeByte(j); + outgoing.writeShort(cameraHorizontal); + outgoing.writeByte(57); + outgoing.writeByte(minimapRotation); + outgoing.writeByte(minimapZoom); + outgoing.writeByte(89); + outgoing.writeShort(localPlayer.x); + outgoing.writeShort(localPlayer.y); + outgoing.writeByte(anInt1264); + outgoing.writeByte(63); + } + } + anInt1117++; + if (anInt1117 > 1151) { + anInt1117 = 0; + // anti-cheat + outgoing.writeOpcode(246); + outgoing.writeByte(0); + int bufPos = outgoing.currentPosition; + + if ((int) (Math.random() * 2D) == 0) { + outgoing.writeByte(101); + } + + outgoing.writeByte(197); + outgoing.writeShort((int) (Math.random() * 65536D)); + outgoing.writeByte((int) (Math.random() * 256D)); + outgoing.writeByte(67); + outgoing.writeShort(14214); + + if ((int) (Math.random() * 2D) == 0) { + outgoing.writeShort(29487); + } + + outgoing.writeShort((int) (Math.random() * 65536D)); + + if ((int) (Math.random() * 2D) == 0) { + outgoing.writeByte(220); + } + + outgoing.writeByte(180); + outgoing.writeBytes(outgoing.currentPosition - bufPos); + } + } + } + + private String interfaceIntToString(int j) { + if (j < 0x3b9ac9ff) + return String.valueOf(j); + else + return "*"; + } + + private void showErrorScreen() { + Graphics g = getGameComponent().getGraphics(); + g.setColor(Color.black); + g.fillRect(0, 0, 765, 503); + method4(1); + if (loadingError) { + aBoolean831 = false; + g.setFont(new Font("Helvetica", 1, 16)); + g.setColor(Color.yellow); + int k = 35; + g.drawString("Sorry, an error has occured whilst loading " + Configuration.CLIENT_NAME, 30, k); + k += 50; + g.setColor(Color.white); + g.drawString("To fix this try the following (in order):", 30, k); + k += 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, k); + k += 30; + g.drawString("2: Try clearing your web-browsers cache from tools->internet options", 30, k); + k += 30; + g.drawString("3: Try using a different game-world", 30, k); + k += 30; + g.drawString("4: Try rebooting your computer", 30, k); + k += 30; + g.drawString("5: Try selecting a different version of Java from the play-game menu", 30, k); + } + if (genericLoadingError) { + aBoolean831 = false; + g.setFont(new Font("Helvetica", 1, 20)); + g.setColor(Color.white); + g.drawString("Error - unable to load game!", 50, 50); + g.drawString("To play " + Configuration.CLIENT_NAME + " make sure you play from", 50, 100); + g.drawString("http://www.UrlHere.com", 50, 150); + } + if (rsAlreadyLoaded) { + aBoolean831 = false; + g.setColor(Color.yellow); + int l = 35; + g.drawString("Error a copy of " + Configuration.CLIENT_NAME + " already appears to be loaded", 30, l); + l += 50; + g.setColor(Color.white); + g.drawString("To fix this try the following (in order):", 30, l); + l += 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, l); + l += 30; + g.drawString("2: Try rebooting your computer, and reloading", 30, l); + l += 30; + } + } + + public URL getCodeBase() { + try { + return new URL(server + ":" + (80 + portOffset)); + } catch (Exception _ex) { + } + return null; + } + + private void processNpcMovement() { + for (int j = 0; j < npcCount; j++) { + int k = npcIndices[j]; + Npc npc = npcs[k]; + if (npc != null) + processMovement(npc); + } + } + + private void processMovement(Mob mob) { + if (mob.x < 128 || mob.y < 128 || mob.x >= 13184 || mob.y >= 13184) { + mob.emoteAnimation = -1; + mob.graphic = -1; + mob.startForceMovement = 0; + mob.endForceMovement = 0; + mob.x = mob.pathX[0] * 128 + mob.size * 64; + mob.y = mob.pathY[0] * 128 + mob.size * 64; + mob.resetPath(); + } + if (mob == localPlayer && (mob.x < 1536 || mob.y < 1536 || mob.x >= 11776 || mob.y >= 11776)) { + mob.emoteAnimation = -1; + mob.graphic = -1; + mob.startForceMovement = 0; + mob.endForceMovement = 0; + mob.x = mob.pathX[0] * 128 + mob.size * 64; + mob.y = mob.pathY[0] * 128 + mob.size * 64; + mob.resetPath(); + } + if (mob.startForceMovement > tick) { + mob.nextPreForcedStep(); + } else if (mob.endForceMovement >= tick) { + mob.nextForcedMovementStep(); + } else { + mob.nextStep(); + } + appendFocusDestination(mob); + mob.updateAnimation(); + } + + private void appendFocusDestination(Mob entity) { + if (entity.degreesToTurn == 0) + return; + if (entity.interactingEntity != -1 && entity.interactingEntity < 32768) { + Npc npc = npcs[entity.interactingEntity]; + if (npc != null) { + int i1 = entity.x - npc.x; + int k1 = entity.y - npc.y; + if (i1 != 0 || k1 != 0) + entity.nextStepOrientation = (int) (Math.atan2(i1, k1) * 325.94900000000001D) & 0x7ff; + } + } + if (entity.interactingEntity >= 32768) { + int j = entity.interactingEntity - 32768; + if (j == localPlayerIndex) + j = internalLocalPlayerIndex; + Player player = players[j]; + if (player != null) { + int l1 = entity.x - player.x; + int i2 = entity.y - player.y; + if (l1 != 0 || i2 != 0) + entity.nextStepOrientation = (int) (Math.atan2(l1, i2) * 325.94900000000001D) & 0x7ff; + } + } + if ((entity.faceX != 0 || entity.faceY != 0) && (entity.remainingPath == 0 || entity.anInt1503 > 0)) { + int k = entity.x - (entity.faceX - regionBaseX - regionBaseX) * 64; + int j1 = entity.y - (entity.faceY - regionBaseY - regionBaseY) * 64; + if (k != 0 || j1 != 0) + entity.nextStepOrientation = (int) (Math.atan2(k, j1) * 325.94900000000001D) & 0x7ff; + entity.faceX = 0; + entity.faceY = 0; + } + int l = entity.nextStepOrientation - entity.orientation & 0x7ff; + if (l != 0) { + if (l < entity.degreesToTurn || l > 2048 - entity.degreesToTurn) + entity.orientation = entity.nextStepOrientation; + else if (l > 1024) + entity.orientation -= entity.degreesToTurn; + else + entity.orientation += entity.degreesToTurn; + entity.orientation &= 0x7ff; + if (entity.movementAnimation == entity.idleAnimation && entity.orientation != entity.nextStepOrientation) { + if (entity.standTurnAnimIndex != -1) { + entity.movementAnimation = entity.standTurnAnimIndex; + return; + } + entity.movementAnimation = entity.walkAnimIndex; + } + } + } + + private void drawGameScreen() { + if (fullscreenInterfaceID != -1 && (loadingStage == 2 || super.fullGameScreen != null)) { + if (loadingStage == 2) { + try { + processWidgetAnimations(tickDelta, fullscreenInterfaceID); + if (openInterfaceId != -1) { + processWidgetAnimations(tickDelta, openInterfaceId); + } + } catch (Exception ex) { + + } + tickDelta = 0; + resetAllImageProducers(); + super.fullGameScreen.initDrawingArea(); + Rasterizer3D.scanOffsets = fullScreenTextureArray; + Rasterizer2D.clear(); + welcomeScreenRaised = true; + if (openInterfaceId != -1) { + Widget rsInterface_1 = Widget.interfaceCache[openInterfaceId]; + if (rsInterface_1.width == 512 && rsInterface_1.height == 334 && rsInterface_1.type == 0) { + rsInterface_1.width = 765; + rsInterface_1.height = 503; + } + try { + drawInterface(0, 0, rsInterface_1, 8); + } catch (Exception ex) { + + } + } + Widget rsInterface = Widget.interfaceCache[fullscreenInterfaceID]; + if (rsInterface.width == 512 && rsInterface.height == 334 && rsInterface.type == 0) { + rsInterface.width = 765; + rsInterface.height = 503; + } + try { + drawInterface(0, 0, rsInterface, 8); + } catch (Exception ex) { + + } + if (!menuOpen) { + processRightClick(); + drawTooltip(); + } else { + drawMenu(frameMode == ScreenMode.FIXED ? 4 : 0, frameMode == ScreenMode.FIXED ? 4 : 0); + } + } + drawCount++; + super.fullGameScreen.drawGraphics(0, super.graphics, 0); + return; + } else { + if (drawCount != 0) { + setupGameplayScreen(); + } + } + if (welcomeScreenRaised) { + welcomeScreenRaised = false; + if (frameMode == ScreenMode.FIXED) { + topFrame.drawGraphics(0, super.graphics, 0); + leftFrame.drawGraphics(4, super.graphics, 0); + } + updateChatbox = true; + tabAreaAltered = true; + if (loadingStage != 2) { + if (frameMode == ScreenMode.FIXED) { + gameScreenImageProducer.drawGraphics(frameMode == ScreenMode.FIXED ? 4 : 0, super.graphics, + frameMode == ScreenMode.FIXED ? 4 : 0); + minimapImageProducer.drawGraphics(0, super.graphics, 516); + } + } + } + if (overlayInterfaceId != -1) { + try { + processWidgetAnimations(tickDelta, overlayInterfaceId); + } catch (Exception ex) { + + } + } + drawTabArea(); + if (backDialogueId == -1) { + aClass9_1059.scrollPosition = anInt1211 - anInt1089 - 110; + if (super.mouseX >= 496 && super.mouseX <= 511 + && super.mouseY > (frameMode == ScreenMode.FIXED ? 345 : frameHeight - 158)) + method65(494, 110, super.mouseX, + super.mouseY - (frameMode == ScreenMode.FIXED ? 345 : frameHeight - 158), aClass9_1059, 0, + false, anInt1211); + int i = anInt1211 - 110 - aClass9_1059.scrollPosition; + if (i < 0) { + i = 0; + } + if (i > anInt1211 - 110) { + i = anInt1211 - 110; + } + if (anInt1089 != i) { + anInt1089 = i; + updateChatbox = true; + } + } + if (backDialogueId != -1) { + boolean flag2 = false; + + try { + flag2 = processWidgetAnimations(tickDelta, backDialogueId); + } catch (Exception ex) { + + } + if (flag2) { + updateChatbox = true; + } + } + if (atInventoryInterfaceType == 3) + updateChatbox = true; + if (activeInterfaceType == 3) + updateChatbox = true; + if (clickToContinueString != null) + updateChatbox = true; + if (menuOpen && menuScreenArea == 2) + updateChatbox = true; + if (updateChatbox) { + drawChatArea(); + updateChatbox = false; + } + if (loadingStage == 2) + moveCameraWithPlayer(); + if (loadingStage == 2) { + if (frameMode == ScreenMode.FIXED) { + drawMinimap(); + minimapImageProducer.drawGraphics(0, super.graphics, 516); + } + } + if (flashingSidebarId != -1) + tabAreaAltered = true; + if (tabAreaAltered) { + if (flashingSidebarId != -1 && flashingSidebarId == tabId) { + flashingSidebarId = -1; + // flashing sidebar + outgoing.writeOpcode(120); + outgoing.writeByte(tabId); + } + tabAreaAltered = false; + chatSettingImageProducer.initDrawingArea(); + gameScreenImageProducer.initDrawingArea(); + } + tickDelta = 0; + } + + private boolean buildFriendsListMenu(Widget class9) { + int i = class9.contentType; + if (i >= 1 && i <= 200 || i >= 701 && i <= 900) { + if (i >= 801) + i -= 701; + else if (i >= 701) + i -= 601; + else if (i >= 101) + i -= 101; + else + i--; + menuActionText[menuActionRow] = "Remove @whi@" + friendsList[i]; + menuActionTypes[menuActionRow] = 792; + menuActionRow++; + menuActionText[menuActionRow] = "Message @whi@" + friendsList[i]; + menuActionTypes[menuActionRow] = 639; + menuActionRow++; + return true; + } + if (i >= 401 && i <= 500) { + menuActionText[menuActionRow] = "Remove @whi@" + class9.defaultText; + menuActionTypes[menuActionRow] = 322; + menuActionRow++; + return true; + } else { + return false; + } + } + + private void createStationaryGraphics() { + AnimableObject class30_sub2_sub4_sub3 = (AnimableObject) incompleteAnimables.reverseGetFirst(); + for (; class30_sub2_sub4_sub3 != null; class30_sub2_sub4_sub3 = (AnimableObject) incompleteAnimables + .reverseGetNext()) + if (class30_sub2_sub4_sub3.anInt1560 != plane || class30_sub2_sub4_sub3.aBoolean1567) + class30_sub2_sub4_sub3.unlink(); + else if (tick >= class30_sub2_sub4_sub3.anInt1564) { + class30_sub2_sub4_sub3.method454(tickDelta); + if (class30_sub2_sub4_sub3.aBoolean1567) + class30_sub2_sub4_sub3.unlink(); + else + scene.addAnimableA(class30_sub2_sub4_sub3.anInt1560, 0, class30_sub2_sub4_sub3.anInt1563, -1, + class30_sub2_sub4_sub3.anInt1562, 60, class30_sub2_sub4_sub3.anInt1561, + class30_sub2_sub4_sub3, false); + } + + } + + public void drawBlackBox(int xPos, int yPos) { + Rasterizer2D.drawBox(xPos - 2, yPos - 1, 1, 71, 0x726451); + Rasterizer2D.drawBox(xPos + 174, yPos, 1, 69, 0x726451); + Rasterizer2D.drawBox(xPos - 2, yPos - 2, 178, 1, 0x726451); + Rasterizer2D.drawBox(xPos, yPos + 68, 174, 1, 0x726451); + Rasterizer2D.drawBox(xPos - 1, yPos - 1, 1, 71, 0x2E2B23); + Rasterizer2D.drawBox(xPos + 175, yPos - 1, 1, 71, 0x2E2B23); + Rasterizer2D.drawBox(xPos, yPos - 1, 175, 1, 0x2E2B23); + Rasterizer2D.drawBox(xPos, yPos + 69, 175, 1, 0x2E2B23); + Rasterizer2D.drawTransparentBox(xPos, yPos, 174, 68, 0, 220); + } + + private void drawInterface(int scroll_y, int x, Widget rsInterface, int y) throws Exception { + if (rsInterface == null) + rsInterface = Widget.interfaceCache[21356]; + if (rsInterface.type != 0 || rsInterface.children == null) + return; + if (rsInterface.invisible && anInt1026 != rsInterface.id && anInt1048 != rsInterface.id + && anInt1039 != rsInterface.id) + return; + int clipLeft = Rasterizer2D.leftX; + int clipTop = Rasterizer2D.topY; + int clipRight = Rasterizer2D.bottomX; + int clipBottom = Rasterizer2D.bottomY; + Rasterizer2D.setDrawingArea(y + rsInterface.height, x, x + rsInterface.width, y); + int childCount = rsInterface.children.length; + int alpha = rsInterface.transparency; + for (int childId = 0; childId < childCount; childId++) { + int _x = rsInterface.childX[childId] + x; + int currentY = (rsInterface.childY[childId] + y) - scroll_y; + Widget childInterface = Widget.interfaceCache[rsInterface.children[childId]]; + _x += childInterface.x; + currentY += childInterface.anInt265; + if (childInterface.contentType > 0) + drawFriendsListOrWelcomeScreen(childInterface); + // here + int[] IDs = {1196, 1199, 1206, 1215, 1224, 1231, 1240, 1249, 1258, 1267, 1274, 1283, 1573, 1290, 1299, + 1308, 1315, 1324, 1333, 1340, 1349, 1358, 1367, 1374, 1381, 1388, 1397, 1404, 1583, 12038, 1414, + 1421, 1430, 1437, 1446, 1453, 1460, 1469, 15878, 1602, 1613, 1624, 7456, 1478, 1485, 1494, 1503, + 1512, 1521, 1530, 1544, 1553, 1563, 1593, 1635, 12426, 12436, 12446, 12456, 6004, 18471, + /* Ancients */ + 12940, 12988, 13036, 12902, 12862, 13046, 12964, 13012, 13054, 12920, 12882, 13062, 12952, 13000, + 13070, 12912, 12872, 13080, 12976, 13024, 13088, 12930, 12892, 13096}; + for (int m5 = 0; m5 < IDs.length; m5++) { + if (childInterface.id == IDs[m5] + 1) { + if (m5 > 61) + drawBlackBox(_x + 1, currentY); + else + drawBlackBox(_x, currentY + 1); + } + } + int[] runeChildren = {1202, 1203, 1209, 1210, 1211, 1218, 1219, 1220, 1227, 1228, 1234, 1235, 1236, 1243, + 1244, 1245, 1252, 1253, 1254, 1261, 1262, 1263, 1270, 1271, 1277, 1278, 1279, 1286, 1287, 1293, + 1294, 1295, 1302, 1303, 1304, 1311, 1312, 1318, 1319, 1320, 1327, 1328, 1329, 1336, 1337, 1343, + 1344, 1345, 1352, 1353, 1354, 1361, 1362, 1363, 1370, 1371, 1377, 1378, 1384, 1385, 1391, 1392, + 1393, 1400, 1401, 1407, 1408, 1410, 1417, 1418, 1424, 1425, 1426, 1433, 1434, 1440, 1441, 1442, + 1449, 1450, 1456, 1457, 1463, 1464, 1465, 1472, 1473, 1474, 1481, 1482, 1488, 1489, 1490, 1497, + 1498, 1499, 1506, 1507, 1508, 1515, 1516, 1517, 1524, 1525, 1526, 1533, 1534, 1535, 1547, 1548, + 1549, 1556, 1557, 1558, 1566, 1567, 1568, 1576, 1577, 1578, 1586, 1587, 1588, 1596, 1597, 1598, + 1605, 1606, 1607, 1616, 1617, 1618, 1627, 1628, 1629, 1638, 1639, 1640, 6007, 6008, 6011, 8673, + 8674, 12041, 12042, 12429, 12430, 12431, 12439, 12440, 12441, 12449, 12450, 12451, 12459, 12460, + 15881, 15882, 15885, 18474, 18475, 18478}; + for (int r = 0; r < runeChildren.length; r++) + if (childInterface.id == runeChildren[r]) + childInterface.modelZoom = 775; + if (childInterface.type == Widget.TYPE_CONTAINER) { + if (childInterface.scrollPosition > childInterface.scrollMax - childInterface.height) + childInterface.scrollPosition = childInterface.scrollMax - childInterface.height; + if (childInterface.scrollPosition < 0) + childInterface.scrollPosition = 0; + drawInterface(childInterface.scrollPosition, _x, childInterface, currentY); + if (childInterface.scrollMax > childInterface.height) + drawScrollbar(childInterface.height, childInterface.scrollPosition, currentY, + _x + childInterface.width, childInterface.scrollMax, false); + } else if (childInterface.type != 1) + if (childInterface.type == Widget.TYPE_INVENTORY) { + int item = 0; + for (int row = 0; row < childInterface.height; row++) { + for (int column = 0; column < childInterface.width; column++) { + int tileX = _x + column * (32 + childInterface.spritePaddingX); + int tileY = currentY + row * (32 + childInterface.spritePaddingY); + if (item < 20) { + tileX += childInterface.spritesX[item]; + tileY += childInterface.spritesY[item]; + } + if (childInterface.inventoryItemId[item] > 0) { + int differenceX = 0; + int differenceY = 0; + int itemId = childInterface.inventoryItemId[item] - 1; + if (tileX > Rasterizer2D.leftX - 32 && tileX < Rasterizer2D.bottomX + && tileY > Rasterizer2D.topY - 32 && tileY < Rasterizer2D.bottomY + || activeInterfaceType != 0 && anInt1085 == item) { + int l9 = 0; + if (itemSelected == 1 && anInt1283 == item && anInt1284 == childInterface.id) + l9 = 0xffffff; + Sprite item_icon = ItemDefinition.getSprite(itemId, + childInterface.inventoryAmounts[item], l9); + if (item_icon != null) { + if (activeInterfaceType != 0 && anInt1085 == item + && anInt1084 == childInterface.id) { + differenceX = super.mouseX - anInt1087; + differenceY = super.mouseY - anInt1088; + if (differenceX < 5 && differenceX > -5) + differenceX = 0; + if (differenceY < 5 && differenceY > -5) + differenceY = 0; + if (anInt989 < 10) { + differenceX = 0; + differenceY = 0; + } + item_icon.drawSprite1(tileX + differenceX, tileY + differenceY); + if (tileY + differenceY < Rasterizer2D.topY + && rsInterface.scrollPosition > 0) { + int i10 = (tickDelta * (Rasterizer2D.topY - tileY - differenceY)) / 3; + if (i10 > tickDelta * 10) + i10 = tickDelta * 10; + if (i10 > rsInterface.scrollPosition) + i10 = rsInterface.scrollPosition; + rsInterface.scrollPosition -= i10; + anInt1088 += i10; + } + if (tileY + differenceY + 32 > Rasterizer2D.bottomY + && rsInterface.scrollPosition < rsInterface.scrollMax + - rsInterface.height) { + int j10 = (tickDelta + * ((tileY + differenceY + 32) - Rasterizer2D.bottomY)) / 3; + if (j10 > tickDelta * 10) + j10 = tickDelta * 10; + if (j10 > rsInterface.scrollMax - rsInterface.height + - rsInterface.scrollPosition) + j10 = rsInterface.scrollMax - rsInterface.height + - rsInterface.scrollPosition; + rsInterface.scrollPosition += j10; + anInt1088 -= j10; + } + } else if (atInventoryInterfaceType != 0 && atInventoryIndex == item + && atInventoryInterface == childInterface.id) + item_icon.drawSprite1(tileX, tileY); + else + item_icon.drawSprite(tileX, tileY); + if (item_icon.getMaxWidth() == 33 + || childInterface.inventoryAmounts[item] != 1) { + int k10 = childInterface.inventoryAmounts[item]; + + smallText.render(0, intToKOrMil(k10), tileY + 10 + differenceY, + tileX + 1 + differenceX); + if (k10 >= 1) + smallText.render(0xFFFF00, intToKOrMil(k10), tileY + 9 + differenceY, + tileX + differenceX); + if (k10 >= 100000) + smallText.render(0xFFFFFF, intToKOrMil(k10), tileY + 9 + differenceY, + tileX + differenceX); + if (k10 >= 10000000) + smallText.render(0x00FF80, intToKOrMil(k10), tileY + 9 + differenceY, + tileX + differenceX); + } + } + } + } else if (childInterface.sprites != null && item < 20) { + Sprite image = childInterface.sprites[item]; + if (image != null) + image.drawSprite(tileX, tileY); + } + item++; + } + } + } else if (childInterface.type == Widget.TYPE_RECTANGLE) { + boolean hover = false; + if (anInt1039 == childInterface.id || anInt1048 == childInterface.id + || anInt1026 == childInterface.id) + hover = true; + int colour; + if (interfaceIsSelected(childInterface)) { + colour = childInterface.secondaryColor; + if (hover && childInterface.secondaryHoverColor != 0) + colour = childInterface.secondaryHoverColor; + } else { + colour = childInterface.textColor; + if (hover && childInterface.defaultHoverColor != 0) + colour = childInterface.defaultHoverColor; + } + if (childInterface.opacity == 0) { + if (childInterface.filled) + Rasterizer2D.drawBox(_x, currentY, childInterface.width, childInterface.height, colour); + else + Rasterizer2D.drawBoxOutline(_x, currentY, childInterface.width, childInterface.height, + colour); + } else if (childInterface.filled) + Rasterizer2D.drawTransparentBox(_x, currentY, childInterface.width, childInterface.height, + colour, 256 - (childInterface.opacity & 0xff)); + else + Rasterizer2D.drawTransparentBoxOutline(_x, currentY, childInterface.width, + childInterface.height, colour, 256 - (childInterface.opacity & 0xff)); + } else if (childInterface.type == Widget.TYPE_TEXT) { + GameFont textDrawingArea = childInterface.textDrawingAreas; + String text = childInterface.defaultText; + boolean flag1 = false; + if (anInt1039 == childInterface.id || anInt1048 == childInterface.id + || anInt1026 == childInterface.id) + flag1 = true; + int colour; + if (interfaceIsSelected(childInterface)) { + colour = childInterface.secondaryColor; + if (flag1 && childInterface.secondaryHoverColor != 0) + colour = childInterface.secondaryHoverColor; + if (childInterface.secondaryText.length() > 0) + text = childInterface.secondaryText; + } else { + colour = childInterface.textColor; + if (flag1 && childInterface.defaultHoverColor != 0) + colour = childInterface.defaultHoverColor; + } + if (childInterface.optionType == Widget.OPTION_CONTINUE && continuedDialogue) { + text = "Please wait..."; + colour = childInterface.textColor; + } + if (Rasterizer2D.width == 516) { + if (colour == 0xffff00) + colour = 255; + if (colour == 49152) + colour = 0xffffff; + } + if (frameMode != ScreenMode.FIXED) { + if ((backDialogueId != -1 || dialogueId != -1 + || childInterface.defaultText.contains("Click here to continue")) + && (rsInterface.id == backDialogueId || rsInterface.id == dialogueId)) { + if (colour == 0xffff00) { + colour = 255; + } + if (colour == 49152) { + colour = 0xffffff; + } + } + } + if ((childInterface.parent == 1151) || (childInterface.parent == 12855)) { + switch (colour) { + case 16773120: + colour = 0xFE981F; + break; + case 7040819: + colour = 0xAF6A1A; + break; + } + } + for (int drawY = currentY + textDrawingArea.verticalSpace; text + .length() > 0; drawY += textDrawingArea.verticalSpace) { + if (text.indexOf("%") != -1) { + do { + int index = text.indexOf("%1"); + if (index == -1) + break; + if (childInterface.id < 4000 || childInterface.id > 5000 && childInterface.id != 13921 + && childInterface.id != 13922 && childInterface.id != 12171 + && childInterface.id != 12172) { + text = text.substring(0, index) + formatCoins(executeScript(childInterface, 0)) + + text.substring(index + 2); + } else { + text = text.substring(0, index) + + interfaceIntToString(executeScript(childInterface, 0)) + + text.substring(index + 2); + } + } while (true); + do { + int index = text.indexOf("%2"); + if (index == -1) { + break; + } + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 1)) + + text.substring(index + 2); + } while (true); + do { + int index = text.indexOf("%3"); + + if (index == -1) { + break; + } + + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 2)) + + text.substring(index + 2); + } while (true); + do { + int index = text.indexOf("%4"); + + if (index == -1) { + break; + } + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 3)) + + text.substring(index + 2); + } while (true); + do { + int index = text.indexOf("%5"); + + if (index == -1) { + break; + } + + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 4)) + + text.substring(index + 2); + } while (true); + } + + int line = text.indexOf("\\n"); + + String drawn; + + if (line != -1) { + drawn = text.substring(0, line); + text = text.substring(line + 2); + } else { + drawn = text; + text = ""; + } + RSFont font = null; + if (textDrawingArea == smallText) { + font = newSmallFont; + } else if (textDrawingArea == regularText) { + font = newRegularFont; + } else if (textDrawingArea == boldText) { + font = newBoldFont; + } else if (textDrawingArea == gameFont) { + font = newFancyFont; + } + if (childInterface.centerText) { + font.drawCenteredString(drawn, _x + childInterface.width / 2, drawY, colour, + childInterface.textShadow ? 0 : -1); + } else { + font.drawBasicString(drawn, _x, drawY, colour, childInterface.textShadow ? 0 : -1); + } + } + } else if (childInterface.type == Widget.TYPE_SPRITE) { + Sprite sprite; + + if (interfaceIsSelected(childInterface)) { + sprite = childInterface.enabledSprite; + } else { + sprite = childInterface.disabledSprite; + } + + if (spellSelected == 1 && childInterface.id == spellId && spellId != 0 && sprite != null) { + sprite.drawSprite(_x, currentY, 0xffffff); + } else { + if (sprite != null) { + if (childInterface.drawsTransparent) { + sprite.drawTransparentSprite(_x, currentY, alpha); + } else { + sprite.drawSprite(_x, currentY); + } + } + } + if (autocast && childInterface.id == autoCastId) + SpriteCache.lookup(43).drawSprite(_x - 3, currentY - 3); + if (sprite != null) + if (childInterface.drawsTransparent) { + sprite.drawSprite1(_x, currentY); + } else { + sprite.drawSprite(_x, currentY); + } + } else if (childInterface.type == Widget.TYPE_MODEL) { + int centreX = Rasterizer3D.originViewX; + int centreY = Rasterizer3D.originViewY; + Rasterizer3D.originViewX = _x + childInterface.width / 2; + Rasterizer3D.originViewY = currentY + childInterface.height / 2; + int sine = Rasterizer3D.anIntArray1470[childInterface.modelRotation1] + * childInterface.modelZoom >> 16; + int cosine = Rasterizer3D.COSINE[childInterface.modelRotation1] * childInterface.modelZoom >> 16; + boolean selected = interfaceIsSelected(childInterface); + int emoteAnimation; + if (selected) + emoteAnimation = childInterface.secondaryAnimationId; + else + emoteAnimation = childInterface.defaultAnimationId; + Model model; + if (emoteAnimation == -1) { + model = childInterface.method209(-1, -1, selected); + } else { + Animation animation = Animation.animations[emoteAnimation]; + model = childInterface.method209(animation.secondaryFrames[childInterface.currentFrame], + animation.primaryFrames[childInterface.currentFrame], selected); + } + if (model != null) + model.method482(childInterface.modelRotation2, 0, childInterface.modelRotation1, 0, sine, + cosine); + Rasterizer3D.originViewX = centreX; + Rasterizer3D.originViewY = centreY; + } else if (childInterface.type == Widget.TYPE_ITEM_LIST) { + GameFont font = childInterface.textDrawingAreas; + int slot = 0; + for (int row = 0; row < childInterface.height; row++) { + for (int column = 0; column < childInterface.width; column++) { + if (childInterface.inventoryItemId[slot] > 0) { + ItemDefinition item = ItemDefinition.lookup(childInterface.inventoryItemId[slot] - 1); + String name = item.name; + if (item.stackable || childInterface.inventoryAmounts[slot] != 1) + name = name + " x" + intToKOrMilLongName(childInterface.inventoryAmounts[slot]); + int __x = _x + column * (115 + childInterface.spritePaddingX); + int __y = currentY + row * (12 + childInterface.spritePaddingY); + if (childInterface.centerText) + font.method382(childInterface.textColor, __x + childInterface.width / 2, name, __y, + childInterface.textShadow); + else + font.drawTextWithPotentialShadow(childInterface.textShadow, __x, + childInterface.textColor, name, __y); + } + slot++; + } + } + } else if (childInterface.type == 9) { + drawHoverBox(_x, currentY, childInterface.popupString); + } else if (childInterface.type == 8 && (anInt1500 == childInterface.id || anInt1044 == childInterface.id + || anInt1129 == childInterface.id) && anInt1501 == 0 && !menuOpen) { + int boxWidth = 0; + int boxHeight = 0; + GameFont font = regularText; + for (String text = childInterface.defaultText; text.length() > 0; ) { + if (text.indexOf("%") != -1) { + do { + int index = text.indexOf("%1"); + if (index == -1) + break; + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 0)) + + text.substring(index + 2); + } while (true); + do { + int index = text.indexOf("%2"); + if (index == -1) + break; + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 1)) + + text.substring(index + 2); + } while (true); + do { + int index = text.indexOf("%3"); + if (index == -1) + break; + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 2)) + + text.substring(index + 2); + } while (true); + do { + int index = text.indexOf("%4"); + if (index == -1) + break; + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 3)) + + text.substring(index + 2); + } while (true); + do { + int index = text.indexOf("%5"); + if (index == -1) + break; + text = text.substring(0, index) + interfaceIntToString(executeScript(childInterface, 4)) + + text.substring(index + 2); + } while (true); + } + int line = text.indexOf("\\n"); + String drawn; + if (line != -1) { + drawn = text.substring(0, line); + text = text.substring(line + 2); + } else { + drawn = text; + text = ""; + } + int j10 = font.getTextWidth(drawn); + if (j10 > boxWidth) { + boxWidth = j10; + } + boxHeight += font.verticalSpace + 1; + } + boxWidth += 6; + boxHeight += 7; + int xPos = (_x + childInterface.width) - 5 - boxWidth; + int yPos = currentY + childInterface.height + 5; + if (xPos < _x + 5) { + xPos = _x + 5; + } + if (xPos + boxWidth > x + rsInterface.width) { + xPos = (x + rsInterface.width) - boxWidth; + } + if (yPos + boxHeight > y + rsInterface.height) { + yPos = (currentY - boxHeight); + } + Rasterizer2D.drawBox(xPos, yPos, boxWidth, boxHeight, 0xFFFFA0); + Rasterizer2D.drawBoxOutline(xPos, yPos, boxWidth, boxHeight, 0); + String s2 = childInterface.defaultText; + for (int j11 = yPos + font.verticalSpace + 2; s2.length() > 0; j11 += font.verticalSpace + 1) {// verticalSpace + if (s2.indexOf("%") != -1) { + do { + int k7 = s2.indexOf("%1"); + if (k7 == -1) + break; + s2 = s2.substring(0, k7) + interfaceIntToString(executeScript(childInterface, 0)) + + s2.substring(k7 + 2); + } while (true); + do { + int l7 = s2.indexOf("%2"); + if (l7 == -1) + break; + s2 = s2.substring(0, l7) + interfaceIntToString(executeScript(childInterface, 1)) + + s2.substring(l7 + 2); + } while (true); + do { + int i8 = s2.indexOf("%3"); + if (i8 == -1) + break; + s2 = s2.substring(0, i8) + interfaceIntToString(executeScript(childInterface, 2)) + + s2.substring(i8 + 2); + } while (true); + do { + int j8 = s2.indexOf("%4"); + if (j8 == -1) + break; + s2 = s2.substring(0, j8) + interfaceIntToString(executeScript(childInterface, 3)) + + s2.substring(j8 + 2); + } while (true); + do { + int k8 = s2.indexOf("%5"); + if (k8 == -1) + break; + s2 = s2.substring(0, k8) + interfaceIntToString(executeScript(childInterface, 4)) + + s2.substring(k8 + 2); + } while (true); + } + int l11 = s2.indexOf("\\n"); + String s5; + if (l11 != -1) { + s5 = s2.substring(0, l11); + s2 = s2.substring(l11 + 2); + } else { + s5 = s2; + s2 = ""; + } + if (childInterface.centerText) { + font.method382(yPos, xPos + childInterface.width / 2, s5, j11, false); + } else { + if (s5.contains("\\r")) { + String text = s5.substring(0, s5.indexOf("\\r")); + String text2 = s5.substring(s5.indexOf("\\r") + 2); + font.drawTextWithPotentialShadow(false, xPos + 3, 0, text, j11); + int rightX = boxWidth + xPos - font.getTextWidth(text2) - 2; + font.drawTextWithPotentialShadow(false, rightX, 0, text2, j11); + System.out.println("Box: " + boxWidth + ""); + } else + font.drawTextWithPotentialShadow(false, xPos + 3, 0, s5, j11); + } + } + } + } + Rasterizer2D.setDrawingArea(clipBottom, clipLeft, clipRight, clipTop); + } + + private void randomizeBackground(IndexedImage background) { + int j = 256; + for (int k = 0; k < anIntArray1190.length; k++) + anIntArray1190[k] = 0; + + for (int l = 0; l < 5000; l++) { + int i1 = (int) (Math.random() * 128D * (double) j); + anIntArray1190[i1] = (int) (Math.random() * 256D); + } + for (int j1 = 0; j1 < 20; j1++) { + for (int k1 = 1; k1 < j - 1; k1++) { + for (int i2 = 1; i2 < 127; i2++) { + int k2 = i2 + (k1 << 7); + anIntArray1191[k2] = (anIntArray1190[k2 - 1] + anIntArray1190[k2 + 1] + anIntArray1190[k2 - 128] + + anIntArray1190[k2 + 128]) / 4; + } + + } + int[] ai = anIntArray1190; + anIntArray1190 = anIntArray1191; + anIntArray1191 = ai; + } + if (background != null) { + int l1 = 0; + for (int j2 = 0; j2 < background.height; j2++) { + for (int l2 = 0; l2 < background.width; l2++) + if (background.palettePixels[l1++] != 0) { + int i3 = l2 + 16 + background.drawOffsetX; + int j3 = j2 + 16 + background.drawOffsetY; + int k3 = i3 + (j3 << 7); + anIntArray1190[k3] = 0; + } + } + } + } + + private void appendPlayerUpdateMask(int mask, int index, Buffer buffer, Player player) { + if ((mask & 0x400) != 0) { + player.initialX = buffer.readUByteS(); + player.initialY = buffer.readUByteS(); + player.destinationX = buffer.readUByteS(); + player.destinationY = buffer.readUByteS(); + player.startForceMovement = buffer.readLEUShortA() + tick; + player.endForceMovement = buffer.readUShortA() + tick; + player.direction = buffer.readUByteS(); + player.resetPath(); + } + if ((mask & 0x100) != 0) { + player.graphic = buffer.readLEUShort(); + int info = buffer.readInt(); + player.graphicHeight = info >> 16; + player.graphicDelay = tick + (info & 0xffff); + player.currentAnimation = 0; + player.anInt1522 = 0; + if (player.graphicDelay > tick) + player.currentAnimation = -1; + if (player.graphic == 65535) + player.graphic = -1; + } + if ((mask & 8) != 0) { + int animation = buffer.readLEUShort(); + if (animation == 65535) { + animation = -1; + } + int delay = buffer.readNegUByte(); + if (animation == player.emoteAnimation && animation != -1) { + int replayMode = Animation.animations[animation].replayMode; + if (replayMode == 1) { + player.displayedEmoteFrames = 0; + player.emoteTimeRemaining = 0; + player.animationDelay = delay; + player.currentAnimationLoops = 0; + } + if (replayMode == 2) + player.currentAnimationLoops = 0; + } else if (animation == -1 || player.emoteAnimation == -1 + || Animation.animations[animation].priority >= Animation.animations[player.emoteAnimation].priority) { + player.emoteAnimation = animation; + player.displayedEmoteFrames = 0; + player.emoteTimeRemaining = 0; + player.animationDelay = delay; + player.currentAnimationLoops = 0; + player.anInt1542 = player.remainingPath; + } + } + if ((mask & 4) != 0) { + player.spokenText = buffer.readString(); + if (player.spokenText.charAt(0) == '~') { + player.spokenText = player.spokenText.substring(1); + sendMessage(player.spokenText, 2, player.name); + } else if (player == localPlayer) + sendMessage(player.spokenText, 2, player.name); + player.textColour = 0; + player.textEffect = 0; + player.textCycle = 150; + } + if ((mask & 0x80) != 0) { + int textInfo = buffer.readLEUShort(); + int privilege = buffer.readUnsignedByte(); + int offset = buffer.readNegUByte(); + int off = buffer.currentPosition; + if (player.name != null && player.visible) { + long name = StringUtils.encodeBase37(player.name); + boolean ignored = false; + if (privilege <= 1) { + for (int count = 0; count < ignoreCount; count++) { + if (ignoreListAsLongs[count] != name) + continue; + ignored = true; + break; + } + + } + if (!ignored && onTutorialIsland == 0) + try { + chatBuffer.currentPosition = 0; + buffer.readReverseData(chatBuffer.payload, offset, 0); + chatBuffer.currentPosition = 0; + String text = ChatMessageCodec.decode(offset, chatBuffer); + // s = Censor.doCensor(s); + player.spokenText = text; + player.textColour = textInfo >> 8; + player.privelage = privilege; + player.textEffect = textInfo & 0xff; + player.textCycle = 150; + if (privilege == 2 || privilege == 3) + sendMessage(text, 1, "@cr2@" + player.name); + else if (privilege == 1) + sendMessage(text, 1, "@cr1@" + player.name); + else + sendMessage(text, 2, player.name); + } catch (Exception exception) { + SignLink.reporterror("cde2"); + } + } + buffer.currentPosition = off + offset; + } + if ((mask & 1) != 0) { + player.interactingEntity = buffer.readLEUShort(); + if (player.interactingEntity == 65535) + player.interactingEntity = -1; + } + if ((mask & 0x10) != 0) { + int length = buffer.readNegUByte(); + byte[] data = new byte[length]; + Buffer appearanceBuffer = new Buffer(data); + buffer.readBytes(length, 0, data); + playerSynchronizationBuffers[index] = appearanceBuffer; + player.updateAppearance(appearanceBuffer); + } + if ((mask & 2) != 0) { + player.faceX = buffer.readLEUShortA(); + player.faceY = buffer.readLEUShort(); + } + if ((mask & 0x20) != 0) { + int damage = buffer.readUnsignedByte(); + int type = buffer.readUByteA(); + player.updateHitData(type, damage, tick); + player.loopCycleStatus = tick + 300; + player.currentHealth = buffer.readNegUByte(); + player.maxHealth = buffer.readUnsignedByte(); + } + if ((mask & 0x200) != 0) { + int damage = buffer.readUnsignedByte(); + int type = buffer.readUByteS(); + player.updateHitData(type, damage, tick); + player.loopCycleStatus = tick + 300; + player.currentHealth = buffer.readUnsignedByte(); + player.maxHealth = buffer.readNegUByte(); + } + } + + private void checkForGameUsages() { + try { + int j = localPlayer.x + cameraX; + int k = localPlayer.y + cameraY; + if (anInt1014 - j < -500 || anInt1014 - j > 500 || anInt1015 - k < -500 || anInt1015 - k > 500) { + anInt1014 = j; + anInt1015 = k; + } + if (anInt1014 != j) + anInt1014 += (j - anInt1014) / 16; + if (anInt1015 != k) + anInt1015 += (k - anInt1015) / 16; + if (super.keyArray[1] == 1) + anInt1186 += (-24 - anInt1186) / 2; + else if (super.keyArray[2] == 1) + anInt1186 += (24 - anInt1186) / 2; + else + anInt1186 /= 2; + if (super.keyArray[3] == 1) + anInt1187 += (12 - anInt1187) / 2; + else if (super.keyArray[4] == 1) + anInt1187 += (-12 - anInt1187) / 2; + else + anInt1187 /= 2; + cameraHorizontal = cameraHorizontal + anInt1186 / 2 & 0x7ff; + anInt1184 += anInt1187 / 2; + if (anInt1184 < 128) + anInt1184 = 128; + if (anInt1184 > 383) + anInt1184 = 383; + int l = anInt1014 >> 7; + int i1 = anInt1015 >> 7; + int j1 = getCenterHeight(plane, anInt1015, anInt1014); + int k1 = 0; + if (l > 3 && i1 > 3 && l < 100 && i1 < 100) { + for (int l1 = l - 4; l1 <= l + 4; l1++) { + for (int k2 = i1 - 4; k2 <= i1 + 4; k2++) { + int l2 = plane; + if (l2 < 3 && (tileFlags[1][l1][k2] & 2) == 2) + l2++; + int i3 = j1 - tileHeights[l2][l1][k2]; + if (i3 > k1) + k1 = i3; + } + + } + + } + anInt1005++; + if (anInt1005 > 1512) { + anInt1005 = 0; + // TODO unknown (anti-cheat) + outgoing.writeOpcode(77); + outgoing.writeByte(0); + int bufPos = outgoing.currentPosition; + outgoing.writeByte((int) (Math.random() * 256D)); + outgoing.writeByte(101); + outgoing.writeByte(233); + outgoing.writeShort(45092); + + if ((int) (Math.random() * 2D) == 0) { + outgoing.writeShort(35784); + } + + outgoing.writeByte((int) (Math.random() * 256D)); + outgoing.writeByte(64); + outgoing.writeByte(38); + outgoing.writeShort((int) (Math.random() * 65536D)); + outgoing.writeShort((int) (Math.random() * 65536D)); + outgoing.writeBytes(outgoing.currentPosition - bufPos); + } + int j2 = k1 * 192; + if (j2 > 0x17f00) + j2 = 0x17f00; + if (j2 < 32768) + j2 = 32768; + if (j2 > anInt984) { + anInt984 += (j2 - anInt984) / 24; + return; + } + if (j2 < anInt984) { + anInt984 += (j2 - anInt984) / 80; + } + } catch (Exception _ex) { + SignLink.reporterror("glfc_ex " + localPlayer.x + "," + localPlayer.y + "," + anInt1014 + "," + anInt1015 + + "," + this.regionX + "," + this.regionY + "," + regionBaseX + "," + regionBaseY); + throw new RuntimeException("eek"); + } + } + + public void processDrawing() { + if (rsAlreadyLoaded || loadingError || genericLoadingError) { + showErrorScreen(); + return; + } + if (!loggedIn) + drawLoginScreen(false); + else + drawGameScreen(); + anInt1213 = 0; + } + + private boolean isFriendOrSelf(String s) { + if (s == null) + return false; + for (int i = 0; i < friendsCount; i++) + if (s.equalsIgnoreCase(friendsList[i])) + return true; + return s.equalsIgnoreCase(localPlayer.name); + } + + private void setWaveVolume(int i) { + SignLink.wavevol = i; + } + + private void draw3dScreen() { + if (showChatComponents) { + drawSplitPrivateChat(); + } + if (crossType == 1) { + int offSet = frameMode == ScreenMode.FIXED ? 4 : 0; + crosses[crossIndex / 100].drawSprite(crossX - 8 - offSet, crossY - 8 - offSet); + anInt1142++; + if (anInt1142 > 67) { + anInt1142 = 0; + // TODO unknown (drawing game screen) + outgoing.writeOpcode(78); + } + } + if (crossType == 2) { + int offSet = frameMode == ScreenMode.FIXED ? 4 : 0; + crosses[4 + crossIndex / 100].drawSprite(crossX - 8 - offSet, crossY - 8 - offSet); + } + if (openWalkableInterface != -1) { + try { + processWidgetAnimations(tickDelta, openWalkableInterface); + if (openWalkableInterface == 197 && frameMode != ScreenMode.FIXED) { + skullIcons[0].drawSprite(frameWidth - 157, 168); + String text = Widget.interfaceCache[199].defaultText.replace("@yel@", ""); + regularText.drawChatInput(0xE1981D, frameWidth - 165, text, 207, true); + } else if (openWalkableInterface == 201 && frameMode != ScreenMode.FIXED) { + drawInterface(0, frameWidth - 560, Widget.interfaceCache[openWalkableInterface], -109); + } else { + drawInterface(0, frameMode == ScreenMode.FIXED ? 0 : (frameWidth / 2) - 356, + Widget.interfaceCache[openWalkableInterface], + frameMode == ScreenMode.FIXED ? 0 : (frameHeight / 2) - 230); + } + } catch (Exception ex) { + + } + } + if (openInterfaceId != -1) { + try { + processWidgetAnimations(tickDelta, openInterfaceId); + drawInterface(0, frameMode == ScreenMode.FIXED ? 0 : (frameWidth / 2) - 356, + Widget.interfaceCache[openInterfaceId], + frameMode == ScreenMode.FIXED ? 0 : (frameHeight / 2) - 230); + } catch (Exception ex) { + + } + } + if (!menuOpen) { + processRightClick(); + drawTooltip(); + } else if (menuScreenArea == 0) { + drawMenu(frameMode == ScreenMode.FIXED ? 4 : 0, frameMode == ScreenMode.FIXED ? 4 : 0); + } + if (multicombat == 1) { + multiOverlay.drawSprite(frameMode == ScreenMode.FIXED ? 472 : frameWidth - 85, + frameMode == ScreenMode.FIXED ? 296 : 186); + } + int x = regionBaseX + (localPlayer.x - 6 >> 7); + int y = regionBaseY + (localPlayer.y - 6 >> 7); + final String screenMode = frameMode == ScreenMode.FIXED ? "Fixed" : "Resizable"; + if (Configuration.clientData) { + int textColour = 0xffff00; + int fpsColour = 0xffff00; + if (super.fps < 15) { + fpsColour = 0xff0000; + } + // regularText.render(textColour, + // "frameWidth: " + (mouseX - frameWidth) + ", frameHeight: " + + // (mouseY - frameHeight), + // frameHeight - 271, 5); + regularText.render(textColour, "Client Zoom: " + cameraZoom, 90, + frameMode == ScreenMode.FIXED ? 5 : frameWidth - 5); + regularText.render(fpsColour, "Fps: " + super.fps, 12, + frameMode == ScreenMode.FIXED ? 470 : frameWidth - 265); + Runtime runtime = Runtime.getRuntime(); + int clientMemory = (int) ((runtime.totalMemory() - runtime.freeMemory()) / 1024L); + regularText.render(textColour, "Mem: " + clientMemory + "k", 27, + frameMode == ScreenMode.FIXED ? 428 : frameWidth - 265); + regularText.render(textColour, "Mouse X: " + super.mouseX + " , Mouse Y: " + super.mouseY, 30, + frameMode == ScreenMode.FIXED ? 5 : frameWidth - 5); + regularText.render(textColour, "Coords: " + x + ", " + y, 45, + frameMode == ScreenMode.FIXED ? 5 : frameWidth - 5); + regularText.render(textColour, "Client Mode: " + screenMode + "", 60, + frameMode == ScreenMode.FIXED ? 5 : frameWidth - 5); + regularText.render(textColour, "Client Resolution: " + botFrame.getWidth() + "x" + botFrame.getHeight(), 75, + frameMode == ScreenMode.FIXED ? 5 : frameWidth - 5); + } + if (systemUpdateTime != 0) { + int seconds = systemUpdateTime / 50; + int minutes = seconds / 60; + int yOffset = frameMode == ScreenMode.FIXED ? 0 : frameHeight - 498; + seconds %= 60; + if (seconds < 10) + regularText.render(0xffff00, "System update in: " + minutes + ":0" + seconds, 329 + yOffset, 4); + else + regularText.render(0xffff00, "System update in: " + minutes + ":" + seconds, 329 + yOffset, 4); + anInt849++; + if (anInt849 > 75) { + anInt849 = 0; + // TODO unknown (system updating) + outgoing.writeOpcode(148); + } + } + } + + private void addIgnore(long l) { + try { + if (l == 0L) + return; + if (ignoreCount >= 100) { + sendMessage("Your ignore list is full. Max of 100 hit", 0, ""); + return; + } + String s = StringUtils.formatUsername(StringUtils.decodeBase37(l)); + for (int j = 0; j < ignoreCount; j++) + if (ignoreListAsLongs[j] == l) { + sendMessage(s + " is already on your ignore list", 0, ""); + return; + } + for (int k = 0; k < friendsCount; k++) + if (friendsListAsLongs[k] == l) { + sendMessage("Please remove " + s + " from your friend list first", 0, ""); + return; + } + + ignoreListAsLongs[ignoreCount++] = l; + // add ignore + outgoing.writeOpcode(133); + outgoing.writeLong(l); + return; + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("45688, " + l + ", " + 4 + ", " + runtimeexception.toString()); + } + throw new RuntimeException(); + } + + private void processPlayerMovement() { + for (int index = -1; index < playerCount; index++) { + + int playerIndex; + + if (index == -1) { + playerIndex = internalLocalPlayerIndex; + } else { + playerIndex = playerList[index]; + } + + Player player = players[playerIndex]; + + if (player != null) { + processMovement(player); + } + } + + } + + private void method115() { + if (loadingStage == 2) { + for (SpawnedObject spawnedObject = (SpawnedObject) spawns + .reverseGetFirst(); spawnedObject != null; spawnedObject = (SpawnedObject) spawns + .reverseGetNext()) { + if (spawnedObject.getLongetivity > 0) + spawnedObject.getLongetivity--; + if (spawnedObject.getLongetivity == 0) { + if (spawnedObject.getPreviousId < 0 + || MapRegion.modelReady(spawnedObject.getPreviousId, spawnedObject.previousType)) { + removeObject(spawnedObject.y, spawnedObject.plane, spawnedObject.previousOrientation, + spawnedObject.previousType, spawnedObject.x, spawnedObject.group, + spawnedObject.getPreviousId); + spawnedObject.unlink(); + } + } else { + if (spawnedObject.delay > 0) + spawnedObject.delay--; + if (spawnedObject.delay == 0 && spawnedObject.x >= 1 && spawnedObject.y >= 1 + && spawnedObject.x <= 102 && spawnedObject.y <= 102 + && (spawnedObject.id < 0 || MapRegion.modelReady(spawnedObject.id, spawnedObject.type))) { + removeObject(spawnedObject.y, spawnedObject.plane, spawnedObject.orientation, + spawnedObject.type, spawnedObject.x, spawnedObject.group, spawnedObject.id); + spawnedObject.delay = -1; + if (spawnedObject.id == spawnedObject.getPreviousId && spawnedObject.getPreviousId == -1) + spawnedObject.unlink(); + else if (spawnedObject.id == spawnedObject.getPreviousId + && spawnedObject.orientation == spawnedObject.previousOrientation + && spawnedObject.type == spawnedObject.previousType) + spawnedObject.unlink(); + } + } + } + + } + } + + private void determineMenuSize() { + int boxLength = boldText.getTextWidth("Choose option"); + for (int row = 0; row < menuActionRow; row++) { + int actionLength = boldText.getTextWidth(menuActionText[row]); + if (actionLength > boxLength) + boxLength = actionLength; + } + boxLength += 8; + int offset = 15 * menuActionRow + 21; + if (super.saveClickX > 0 && super.saveClickY > 0 && super.saveClickX < frameWidth + && super.saveClickY < frameHeight) { + int xClick = super.saveClickX - boxLength / 2; + if (xClick + boxLength > frameWidth - 4) { + xClick = frameWidth - 4 - boxLength; + } + if (xClick < 0) { + xClick = 0; + } + int yClick = super.saveClickY - 0; + if (yClick + offset > frameHeight - 6) { + yClick = frameHeight - 6 - offset; + } + if (yClick < 0) { + yClick = 0; + } + menuOpen = true; + menuOffsetX = xClick; + menuOffsetY = yClick; + menuWidth = boxLength; + menuHeight = 15 * menuActionRow + 22; + } + } + + private void updateLocalPlayerMovement(Buffer stream) { + stream.initBitAccess(); + + int update = stream.readBits(1); + + if (update == 0) { + return; + } + + int type = stream.readBits(2); + + if (type == 0) { + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = internalLocalPlayerIndex; + } + if (type == 1) { + int direction = stream.readBits(3); + localPlayer.moveInDir(false, direction); + int updateRequired = stream.readBits(1); + + if (updateRequired == 1) { + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = internalLocalPlayerIndex; + } + } + if (type == 2) { + int firstDirection = stream.readBits(3); + localPlayer.moveInDir(true, firstDirection); + + int secondDirection = stream.readBits(3); + localPlayer.moveInDir(true, secondDirection); + + int updateRequired = stream.readBits(1); + + if (updateRequired == 1) { + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = internalLocalPlayerIndex; + } + } + if (type == 3) { + plane = stream.readBits(2); + int teleport = stream.readBits(1); + int updateRequired = stream.readBits(1); + + if (updateRequired == 1) { + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = internalLocalPlayerIndex; + } + + int y = stream.readBits(7); + int x = stream.readBits(7); + localPlayer.setPos(x, y, teleport == 1); + } + } + + private void nullLoader() { + aBoolean831 = false; + while (drawingFlames) { + aBoolean831 = false; + try { + Thread.sleep(50L); + } catch (Exception _ex) { + } + } + titleBoxIndexedImage = null; + titleButtonIndexedImage = null; + titleIndexedImages = null; + anIntArray850 = null; + anIntArray851 = null; + anIntArray852 = null; + anIntArray853 = null; + anIntArray1190 = null; + anIntArray1191 = null; + anIntArray828 = null; + anIntArray829 = null; + flameLeftSprite = null; + flameRightSprite = null; + } + + private boolean processWidgetAnimations(int tick, int interfaceId) throws Exception { + boolean redrawRequired = false; + Widget widget = Widget.interfaceCache[interfaceId]; + + if (widget == null || widget.children == null) { + return false; + } + + for (int element : widget.children) { + if (element == -1) { + break; + } + + Widget child = Widget.interfaceCache[element]; + + if (child.type == Widget.TYPE_MODEL_LIST) { + redrawRequired |= processWidgetAnimations(tick, child.id); + } + + if (child.type == 6 && (child.defaultAnimationId != -1 || child.secondaryAnimationId != -1)) { + boolean updated = interfaceIsSelected(child); + + int animationId = updated ? child.secondaryAnimationId : child.defaultAnimationId; + + if (animationId != -1) { + Animation animation = Animation.animations[animationId]; + for (child.lastFrameTime += tick; child.lastFrameTime > animation.duration(child.currentFrame); ) { + child.lastFrameTime -= animation.duration(child.currentFrame) + 1; + child.currentFrame++; + if (child.currentFrame >= animation.frameCount) { + child.currentFrame -= animation.loopOffset; + if (child.currentFrame < 0 || child.currentFrame >= animation.frameCount) + child.currentFrame = 0; + } + redrawRequired = true; + } + + } + } + } + + return redrawRequired; + } + + private int setCameraLocation() { + if (!Configuration.enableRoofs) + return plane; + int j = 3; + if (yCameraCurve < 310) { + int k = xCameraPos >> 7; + int l = yCameraPos >> 7; + int i1 = localPlayer.x >> 7; + int j1 = localPlayer.y >> 7; + if ((tileFlags[plane][k][l] & 4) != 0) + j = plane; + int k1; + if (i1 > k) + k1 = i1 - k; + else + k1 = k - i1; + int l1; + if (j1 > l) + l1 = j1 - l; + else + l1 = l - j1; + if (k1 > l1) { + int i2 = (l1 * 0x10000) / k1; + int k2 = 32768; + while (k != i1) { + if (k < i1) + k++; + else if (k > i1) + k--; + if ((tileFlags[plane][k][l] & 4) != 0) + j = plane; + k2 += i2; + if (k2 >= 0x10000) { + k2 -= 0x10000; + if (l < j1) + l++; + else if (l > j1) + l--; + if ((tileFlags[plane][k][l] & 4) != 0) + j = plane; + } + } + } else { + int j2 = (k1 * 0x10000) / l1; + int l2 = 32768; + while (l != j1) { + if (l < j1) + l++; + else if (l > j1) + l--; + if ((tileFlags[plane][k][l] & 4) != 0) + j = plane; + l2 += j2; + if (l2 >= 0x10000) { + l2 -= 0x10000; + if (k < i1) + k++; + else if (k > i1) + k--; + if ((tileFlags[plane][k][l] & 4) != 0) + j = plane; + } + } + } + } + if ((tileFlags[plane][localPlayer.x >> 7][localPlayer.y >> 7] & 4) != 0) + j = plane; + return j; + } + + private int resetCameraHeight() { + int orientation = getCenterHeight(plane, yCameraPos, xCameraPos); + if (orientation - zCameraPos < 800 && (tileFlags[plane][xCameraPos >> 7][yCameraPos >> 7] & 4) != 0) + return plane; + else + return 3; + } + + private void removeFriend(long name) { + try { + if (name == 0L) + return; + for (int index = 0; index < friendsCount; index++) { + if (friendsListAsLongs[index] != name) + continue; + friendsCount--; + for (int count = index; count < friendsCount; count++) { + friendsList[count] = friendsList[count + 1]; + friendsNodeIDs[count] = friendsNodeIDs[count + 1]; + friendsListAsLongs[count] = friendsListAsLongs[count + 1]; + } + // remove friend + outgoing.writeOpcode(215); + outgoing.writeLong(name); + break; + } + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("18622, " + false + ", " + name + ", " + runtimeexception.toString()); + throw new RuntimeException(); + } + } + + private void removeIgnore(long name) { + try { + if (name == 0L) + return; + for (int index = 0; index < ignoreCount; index++) + if (ignoreListAsLongs[index] == name) { + ignoreCount--; + System.arraycopy(ignoreListAsLongs, index + 1, ignoreListAsLongs, index, ignoreCount - index); + + // remove ignore + outgoing.writeOpcode(74); + outgoing.writeLong(name); + return; + } + + return; + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("47229, " + 3 + ", " + name + ", " + runtimeexception.toString()); + } + throw new RuntimeException(); + } + + private void chatJoin(long l) { + try { + if (l == 0L) + return; + // type on interface + outgoing.writeOpcode(60); + outgoing.writeLong(l); + return; + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("47229, " + 3 + ", " + l + ", " + runtimeexception.toString()); + } + throw new RuntimeException(); + + } + + public final void requestCrcs() { + int delay = 5; + archiveCRCs[8] = 0; + int k = 0; + System.out.println("1"); + while (archiveCRCs[8] == 0) { + System.out.println("2"); + String error = "Unknown problem"; + drawLoadingText(20, "Connecting to web server"); + try (DataInputStream in = requestCacheIndex("crc" + (int) (Math.random() * 99999999D) + "-" + 317)) { + System.out.println("3"); + Buffer buffer = new Buffer(new byte[40]); + in.readFully(buffer.payload, 0, 40); + in.close(); + for (int index = 0; index < 9; index++) { + archiveCRCs[index] = buffer.readInt(); + } + + int expected = buffer.readInt(); + int calculated = 1234; + for (int index = 0; index < 9; index++) { + calculated = (calculated << 1) + archiveCRCs[index]; + } + + if (expected != calculated) { + error = "checksum problem"; + archiveCRCs[8] = 0; + } + } catch (EOFException ex) { + error = "EOF problem"; + archiveCRCs[8] = 0; + } catch (IOException ex) { + ex.printStackTrace(); + error = "connection problem"; + archiveCRCs[8] = 0; + } catch (Exception ex) { + error = "logic problem"; + archiveCRCs[8] = 0; + if (!SignLink.reporterror) { + return; + } + } + + if (archiveCRCs[8] == 0) { + k++; + for (int remaining = delay; remaining > 0; remaining--) { + if (k >= 10) { + drawLoadingText(10, "Game updated - please reload page"); + remaining = 10; + } else { + drawLoadingText(10, error + " - Will retry in " + remaining + " secs."); + } + try { + Thread.sleep(1000L); + } catch (InterruptedException ex) { + } + } + + delay *= 2; + if (delay > 60) { + delay = 60; + } + Configuration.useJaggrab = !Configuration.useJaggrab; + } + } + } + + public String getParameter(String s) { + if (SignLink.mainapp != null) + return SignLink.mainapp.getParameter(s); + else + return super.getParameter(s); + } + + private int executeScript(Widget widget, int id) { + if (widget.scripts == null || id >= widget.scripts.length) + return -2; + try { + int[] script = widget.scripts[id]; + int accumulator = 0; + int counter = 0; + int operator = 0; + do { + int instruction = script[counter++]; + int value = 0; + byte next = 0; + + if (instruction == 0) { + return accumulator; + } + + if (instruction == 1) { + value = currentStats[script[counter++]]; + } + + if (instruction == 2) { + value = maximumLevels[script[counter++]]; + } + + if (instruction == 3) { + value = currentExp[script[counter++]]; + } + + if (instruction == 4) { + Widget other = Widget.interfaceCache[script[counter++]]; + int item = script[counter++]; + if (item >= 0 && item < ItemDefinition.itemCount + && (!ItemDefinition.lookup(item).members || isMembers)) { + for (int slot = 0; slot < other.inventoryItemId.length; slot++) + if (other.inventoryItemId[slot] == item + 1) + value += other.inventoryAmounts[slot]; + + } + } + if (instruction == 5) { + value = settings[script[counter++]]; + } + + if (instruction == 6) { + value = SKILL_EXPERIENCE[maximumLevels[script[counter++]] - 1]; + } + + if (instruction == 7) { + value = (settings[script[counter++]] * 100) / 46875; + } + + if (instruction == 8) { + value = localPlayer.combatLevel; + } + + if (instruction == 9) { + for (int skill = 0; skill < SkillConstants.SKILL_COUNT; skill++) + if (SkillConstants.ENABLED_SKILLS[skill]) + value += maximumLevels[skill]; + + } + + if (instruction == 10) { + Widget other = Widget.interfaceCache[script[counter++]]; + int item = script[counter++] + 1; + if (item >= 0 && item < ItemDefinition.itemCount && isMembers) { + for (int stored = 0; stored < other.inventoryItemId.length; stored++) { + if (other.inventoryItemId[stored] != item) + continue; + value = 0x3b9ac9ff; + break; + } + + } + } + + if (instruction == 11) { + value = runEnergy; + } + + if (instruction == 12) { + value = weight; + } + + if (instruction == 13) { + int bool = settings[script[counter++]]; + int shift = script[counter++]; + value = (bool & 1 << shift) == 0 ? 0 : 1; + } + + if (instruction == 14) { + int index = script[counter++]; + Varbit bits = Varbit.varbits[index]; + int setting = bits.getSetting(); + int low = bits.getLow(); + int high = bits.getHigh(); + int mask = BIT_MASKS[high - low]; + value = settings[setting] >> low & mask; + } + + if (instruction == 15) { + next = 1; + } + + if (instruction == 16) { + next = 2; + } + + if (instruction == 17) { + next = 3; + } + + if (instruction == 18) { + value = (localPlayer.x >> 7) + regionBaseX; + } + + if (instruction == 19) { + value = (localPlayer.y >> 7) + regionBaseY; + } + + if (instruction == 20) { + value = script[counter++]; + } + + if (next == 0) { + + if (operator == 0) { + accumulator += value; + } + + if (operator == 1) { + accumulator -= value; + } + + if (operator == 2 && value != 0) { + accumulator /= value; + } + + if (operator == 3) { + accumulator *= value; + } + operator = 0; + } else { + operator = next; + } + } while (true); + } catch (Exception _ex) { + return -1; + } + } + + private void drawTooltip() { + if (menuActionRow < 2 && itemSelected == 0 && spellSelected == 0) + return; + String s; + if (itemSelected == 1 && menuActionRow < 2) + s = "Use " + selectedItemName + " with..."; + else if (spellSelected == 1 && menuActionRow < 2) + s = spellTooltip + "..."; + else + s = menuActionText[menuActionRow - 1]; + if (menuActionRow > 2) + s = s + "@whi@ / " + (menuActionRow - 2) + " more options"; + boldText.method390(4, 0xffffff, s, tick / 1000, 15); + } + + private void markMinimap(Sprite sprite, int x, int y) { + if (sprite == null) { + return; + } + int angle = cameraHorizontal + minimapRotation & 0x7ff; + int l = x * x + y * y; + if (l > 6400) { + return; + } + int sineAngle = Model.SINE[angle]; + int cosineAngle = Model.COSINE[angle]; + sineAngle = (sineAngle * 256) / (minimapZoom + 256); + cosineAngle = (cosineAngle * 256) / (minimapZoom + 256); + int spriteOffsetX = y * sineAngle + x * cosineAngle >> 16; + int spriteOffsetY = y * cosineAngle - x * sineAngle >> 16; + if (frameMode == ScreenMode.FIXED) { + sprite.drawSprite(((94 + spriteOffsetX) - sprite.getMaxWidth() / 2) + 4 + 30, + 83 - spriteOffsetY - sprite.getMaxHeight() / 2 - 4 + 5); + } else { + sprite.drawSprite(((77 + spriteOffsetX) - sprite.getMaxWidth() / 2) + 4 + 5 + (frameWidth - 167), + 85 - spriteOffsetY - sprite.getMaxHeight() / 2); + } + } + + private void drawMinimap() { + if (frameMode == ScreenMode.FIXED) { + minimapImageProducer.initDrawingArea(); + } + if (minimapState == 2) { + if (frameMode == ScreenMode.FIXED) { + SpriteCache.lookup(19).drawSprite(0, 0); + } else { + SpriteCache.lookup(44).drawSprite(frameWidth - 181, 0); + SpriteCache.lookup(45).drawSprite(frameWidth - 158, 7); + } + if (frameMode == ScreenMode.FIXED + ? super.mouseX >= 519 && super.mouseX <= 536 && super.mouseY >= 22 && super.mouseY <= 41 + : super.mouseX >= frameWidth - 185 && super.mouseX <= frameWidth - 158 && super.mouseY >= 40 + && super.mouseY <= 66) { + SpriteCache.lookup(23).drawSprite( + Configuration.enableOrbs && frameMode == ScreenMode.FIXED ? 0 : frameWidth - 185, + frameMode == ScreenMode.FIXED ? 21 : 41); + } else { + SpriteCache.lookup(22).drawSprite( + Configuration.enableOrbs && frameMode == ScreenMode.FIXED ? 0 : frameWidth - 185, + frameMode == ScreenMode.FIXED ? 21 : 41); + } + if (frameMode != ScreenMode.FIXED && changeTabArea) { + if (super.mouseX >= frameWidth - 26 && super.mouseX <= frameWidth - 1 && super.mouseY >= 2 + && super.mouseY <= 24 || tabId == 15) { + SpriteCache.lookup(27).drawSprite(frameWidth - 25, 2); + } else { + SpriteCache.lookup(27).drawARGBSprite(frameWidth - 25, 2, 165); + } + } + loadAllOrbs(frameMode == ScreenMode.FIXED ? 0 : frameWidth - 217); + compass.rotate(33, cameraHorizontal, anIntArray1057, 256, anIntArray968, + (frameMode == ScreenMode.FIXED ? 25 : 24), 4, + (frameMode == ScreenMode.FIXED ? 29 : frameWidth - 176), 33, 25); + if (menuOpen) { + drawMenu(frameMode == ScreenMode.FIXED ? 516 : 0, 0); + } + if (frameMode == ScreenMode.FIXED) { + minimapImageProducer.initDrawingArea(); + } + return; + } + int angle = cameraHorizontal + minimapRotation & 0x7ff; + int centreX = 48 + localPlayer.x / 32; + int centreY = 464 - localPlayer.y / 32; + minimapImage.rotate(151, angle, minimapLineWidth, 256 + minimapZoom, minimapLeft, centreY, + (frameMode == ScreenMode.FIXED ? 9 : 7), (frameMode == ScreenMode.FIXED ? 54 : frameWidth - 158), 146, + centreX); + for (int icon = 0; icon < anInt1071; icon++) { + int mapX = (minimapHintX[icon] * 4 + 2) - localPlayer.x / 32; + int mapY = (minimapHintY[icon] * 4 + 2) - localPlayer.y / 32; + markMinimap(minimapHint[icon], mapX, mapY); + } + for (int x = 0; x < 104; x++) { + for (int y = 0; y < 104; y++) { + Deque class19 = groundItems[plane][x][y]; + if (class19 != null) { + int mapX = (x * 4 + 2) - localPlayer.x / 32; + int mapY = (y * 4 + 2) - localPlayer.y / 32; + markMinimap(mapDotItem, mapX, mapY); + } + } + } + for (int n = 0; n < npcCount; n++) { + Npc npc = npcs[npcIndices[n]]; + if (npc != null && npc.isVisible()) { + NpcDefinition entityDef = npc.desc; + if (entityDef.childrenIDs != null) { + entityDef = entityDef.morph(); + } + if (entityDef != null && entityDef.drawMinimapDot && entityDef.clickable) { + int mapX = npc.x / 32 - localPlayer.x / 32; + int mapY = npc.y / 32 - localPlayer.y / 32; + markMinimap(mapDotNPC, mapX, mapY); + } + } + } + for (int p = 0; p < playerCount; p++) { + Player player = players[playerList[p]]; + if (player != null && player.isVisible()) { + int mapX = player.x / 32 - localPlayer.x / 32; + int mapY = player.y / 32 - localPlayer.y / 32; + boolean friend = false; + boolean clanMember = false; + for (int clan = 0; clan < clanList.length; clan++) { + if (clanList[clan] == null) { + continue; + } + if (!clanList[clan].equalsIgnoreCase(player.name)) { + continue; + } + clanMember = true; + break; + } + long nameHash = StringUtils.encodeBase37(player.name); + for (int f = 0; f < friendsCount; f++) { + if (nameHash != friendsListAsLongs[f] || friendsNodeIDs[f] == 0) { + continue; + } + friend = true; + break; + } + boolean team = false; + if (localPlayer.team != 0 && player.team != 0 && localPlayer.team == player.team) { + team = true; + } + if (friend) { + markMinimap(mapDotFriend, mapX, mapY); + } else if (clanMember) { + markMinimap(mapDotClan, mapX, mapY); + } else if (team) { + markMinimap(mapDotTeam, mapX, mapY); + } else { + markMinimap(mapDotPlayer, mapX, mapY); + } + } + } + if (hintIconDrawType != 0 && tick % 20 < 10) { + if (hintIconDrawType == 1 && hintIconNpcId >= 0 && hintIconNpcId < npcs.length) { + Npc npc = npcs[hintIconNpcId]; + if (npc != null) { + int mapX = npc.x / 32 - localPlayer.x / 32; + int mapY = npc.y / 32 - localPlayer.y / 32; + refreshMinimap(mapMarker, mapY, mapX); + } + } + if (hintIconDrawType == 2) { + int mapX = ((hintIconX - regionBaseX) * 4 + 2) - localPlayer.x / 32; + int mapY = ((hintIconY - regionBaseY) * 4 + 2) - localPlayer.y / 32; + refreshMinimap(mapMarker, mapY, mapX); + } + if (hintIconDrawType == 10 && hintIconPlayerId >= 0 && hintIconPlayerId < players.length) { + Player player = players[hintIconPlayerId]; + if (player != null) { + int mapX = player.x / 32 - localPlayer.x / 32; + int mapY = player.y / 32 - localPlayer.y / 32; + refreshMinimap(mapMarker, mapY, mapX); + } + } + } + if (destinationX != 0) { + int mapX = (destinationX * 4 + 2) - localPlayer.x / 32; + int mapY = (destY * 4 + 2) - localPlayer.y / 32; + markMinimap(mapFlag, mapX, mapY); + } + Rasterizer2D.drawBox((frameMode == ScreenMode.FIXED ? 127 : frameWidth - 88), + (frameMode == ScreenMode.FIXED ? 83 : 80), 3, 3, 0xffffff); + if (frameMode == ScreenMode.FIXED) { + SpriteCache.lookup(19).drawSprite(0, 0); + } else { + SpriteCache.lookup(44).drawSprite(frameWidth - 181, 0); + } + compass.rotate(33, cameraHorizontal, anIntArray1057, 256, anIntArray968, + (frameMode == ScreenMode.FIXED ? 25 : 24), 4, (frameMode == ScreenMode.FIXED ? 29 : frameWidth - 176), + 33, 25); + if (frameMode == ScreenMode.FIXED + ? super.mouseX >= 519 && super.mouseX <= 536 && super.mouseY >= 22 && super.mouseY <= 41 + : super.mouseX >= frameWidth - 185 && super.mouseX <= frameWidth - 158 && super.mouseY >= 40 + && super.mouseY <= 66) { + SpriteCache.lookup(23).drawSprite( + Configuration.enableOrbs && frameMode == ScreenMode.FIXED ? 0 : frameWidth - 185, + frameMode == ScreenMode.FIXED ? 21 : 41); + } else { + SpriteCache.lookup(22).drawSprite( + Configuration.enableOrbs && frameMode == ScreenMode.FIXED ? 0 : frameWidth - 185, + frameMode == ScreenMode.FIXED ? 21 : 41); + } + if (frameMode != ScreenMode.FIXED && changeTabArea) { + if (super.mouseX >= frameWidth - 26 && super.mouseX <= frameWidth - 1 && super.mouseY >= 2 + && super.mouseY <= 24 || tabId == 10) { + SpriteCache.lookup(27).drawSprite(frameWidth - 25, 2); + } else { + SpriteCache.lookup(27).drawARGBSprite(frameWidth - 25, 2, 165); + } + } + loadAllOrbs(frameMode == ScreenMode.FIXED ? 0 : frameWidth - 217); + if (menuOpen) { + drawMenu(frameMode == ScreenMode.FIXED ? 516 : 0, 0); + } + if (frameMode == ScreenMode.FIXED) { + gameScreenImageProducer.initDrawingArea(); + } + } + + private void loadAllOrbs(int xOffset) { + loadHpOrb(xOffset); + loadPrayerOrb(xOffset); + loadRunOrb(xOffset); + loadSpecialOrb(xOffset); + if (frameMode == ScreenMode.FIXED) { + SpriteCache.lookup(worldHover ? 54 : 53).drawSprite(202, 20); + } else { + SpriteCache.lookup(worldHover ? 52 : 51).drawSprite(frameWidth - 118, 154); + } + } + + private void loadHpOrb(int xOffset) { + int hover = poisonType == 0 ? 8 : 7; + Sprite bg = SpriteCache.lookup(hpHover ? hover : 7); + int id = 0; + if (poisonType == 0) + id = 0; + if (poisonType == 1) + id = 177; + if (poisonType == 2) + id = 5; + Sprite fg = SpriteCache.lookup(id); + bg.drawSprite(0 + xOffset, 41); + fg.drawSprite(27 + xOffset, 45); + int level = currentStats[3]; + int max = maximumLevels[3]; + double percent = level / (double) max; + SpriteCache.lookup(14).setMyHeight((int) (26 * (1 - percent))); + SpriteCache.lookup(14).drawSprite(27 + xOffset, 45); + if (percent <= .25) { + SpriteCache.lookup(9).drawSprite1(33 + xOffset, 52, 200 + (int) (50 * Math.sin(tick / 7.0))); + } else { + SpriteCache.lookup(9).drawSprite(33 + xOffset, 52); + } + smallText.method382(getOrbTextColor((int) (percent * 100)), 15 + xOffset, "" + level, 67, true); + } + + private void loadPrayerOrb(int xOffset) { + Sprite bg = SpriteCache.lookup(prayHover ? 8 : 7); + Sprite fg = SpriteCache.lookup(prayClicked ? 2 : 1); + bg.drawSprite(0 + xOffset, 85); + fg.drawSprite(27 + xOffset, 89); + int level = currentStats[5]; + int max = maximumLevels[5]; + double percent = level / (double) max; + SpriteCache.lookup(14).setMyHeight((int) (26 * (1 - percent))); + SpriteCache.lookup(14).drawSprite(27 + xOffset, 89); + if (percent <= .25) { + SpriteCache.lookup(10).drawSprite1(30 + xOffset, 92, 200 + (int) (50 * Math.sin(tick / 7.0))); + } else { + SpriteCache.lookup(10).drawSprite(30 + xOffset, 92); + } + smallText.method382(getOrbTextColor((int) (percent * 100)), 16 + xOffset, level + "", 111, true); + } + + private void loadRunOrb(int xOffset) { + Sprite bg = SpriteCache.lookup(runHover ? 8 : 7); + Sprite fg = SpriteCache.lookup(settings[173] == 1 ? 4 : 3); + bg.drawSprite(24 + xOffset, 122); + fg.drawSprite(51 + xOffset, 126); + int level = runEnergy; + double percent = level / (double) 100; + SpriteCache.lookup(14).setMyHeight((int) (26 * (1 - percent))); + SpriteCache.lookup(14).drawSprite(51 + xOffset, 126); + if (percent <= .25) { + SpriteCache.lookup(settings[173] == 1 ? 12 : 11).drawSprite1(58 + xOffset, 130, + 200 + (int) (50 * Math.sin(tick / 7.0))); + } else { + SpriteCache.lookup(settings[173] == 1 ? 12 : 11).drawSprite(58 + xOffset, 130); + } + smallText.method382(getOrbTextColor((int) (percent * 100)), 40 + xOffset, level + "", 148, true); + } + + private void loadSpecialOrb(int xOffset) { + Sprite image = SpriteCache.lookup(specialHover ? 56 : 42); + Sprite fill = SpriteCache.lookup(specialEnabled == 0 ? 5 : 6); + Sprite sword = SpriteCache.lookup(55); + double percent = specialOrb / (double) 100; + boolean isFixed = frameMode == ScreenMode.FIXED; + image.drawSprite((isFixed ? 170 : 160) + xOffset, isFixed ? 122 : 148); + fill.drawSprite((isFixed ? 174 : 163) + xOffset, isFixed ? 126 : 151); + SpriteCache.lookup(14).setMyHeight((int) (26 * (1 - percent))); + SpriteCache.lookup(14).drawSprite(175 + xOffset, 127); + sword.drawSprite((isFixed ? 179 : 168) + xOffset, isFixed ? 131 : 156); + smallText.method382(getOrbTextColor((int) (percent * 100)), (isFixed ? 212 : 202) + xOffset, specialOrb + "", + isFixed ? 148 : 173, true); + } + + private void npcScreenPos(Mob entity, int i) { + calcEntityScreenPos(entity.x, i, entity.y); + } + + private void calcEntityScreenPos(int i, int j, int l) { + if (i < 128 || l < 128 || i > 13056 || l > 13056) { + spriteDrawX = -1; + spriteDrawY = -1; + return; + } + int i1 = getCenterHeight(plane, l, i) - j; + i -= xCameraPos; + i1 -= zCameraPos; + l -= yCameraPos; + int j1 = Model.SINE[yCameraCurve]; + int k1 = Model.COSINE[yCameraCurve]; + int l1 = Model.SINE[xCameraCurve]; + int i2 = Model.COSINE[xCameraCurve]; + int j2 = l * l1 + i * i2 >> 16; + l = l * i2 - i * l1 >> 16; + i = j2; + j2 = i1 * k1 - l * j1 >> 16; + l = i1 * j1 + l * k1 >> 16; + i1 = j2; + if (l >= 50) { + spriteDrawX = Rasterizer3D.originViewX + (i << SceneGraph.viewDistance) / l; + spriteDrawY = Rasterizer3D.originViewY + (i1 << SceneGraph.viewDistance) / l; + } else { + spriteDrawX = -1; + spriteDrawY = -1; + } + } + + private void buildSplitPrivateChatMenu() { + if (splitPrivateChat == 0) + return; + int message = 0; + if (systemUpdateTime != 0) + message = 1; + for (int index = 0; index < 100; index++) + if (chatMessages[index] != null) { + int type = chatTypes[index]; + String name = chatNames[index]; + if (name != null && name.startsWith("@cr1@")) { + name = name.substring(5); + } + if (name != null && name.startsWith("@cr2@")) { + name = name.substring(5); + } + if ((type == 3 || type == 7) + && (type == 7 || privateChatMode == 0 || privateChatMode == 1 && isFriendOrSelf(name))) { + int offSet = frameMode == ScreenMode.FIXED ? 4 : 0; + int y = 329 - message * 13; + if (frameMode != ScreenMode.FIXED) { + y = frameHeight - 170 - message * 13; + } + if (super.mouseX > 4 && super.mouseY - offSet > y - 10 && super.mouseY - offSet <= y + 3) { + int i1 = regularText.getTextWidth("From: " + name + chatMessages[index]) + 25; + if (i1 > 450) + i1 = 450; + if (super.mouseX < 4 + i1) { + if (myPrivilege >= 1) { + menuActionText[menuActionRow] = "Report abuse @whi@" + name; + menuActionTypes[menuActionRow] = 2606; + menuActionRow++; + } + menuActionText[menuActionRow] = "Add ignore @whi@" + name; + menuActionTypes[menuActionRow] = 2042; + menuActionRow++; + menuActionText[menuActionRow] = "Add friend @whi@" + name; + menuActionTypes[menuActionRow] = 2337; + menuActionRow++; + } + } + if (++message >= 5) + return; + } + if ((type == 5 || type == 6) && privateChatMode < 2 && ++message >= 5) + return; + } + + } + + private void requestSpawnObject(int longetivity, int id, int orientation, int group, int y, int type, int plane, + int x, int delay) { + SpawnedObject object = null; + for (SpawnedObject node = (SpawnedObject) spawns.reverseGetFirst(); node != null; node = (SpawnedObject) spawns + .reverseGetNext()) { + if (node.plane != plane || node.x != x || node.y != y || node.group != group) + continue; + object = node; + break; + } + + if (object == null) { + object = new SpawnedObject(); + object.plane = plane; + object.group = group; + object.x = x; + object.y = y; + method89(object); + spawns.insertHead(object); + } + object.id = id; + object.type = type; + object.orientation = orientation; + object.delay = delay; + object.getLongetivity = longetivity; + } + + private boolean interfaceIsSelected(Widget widget) { + if (widget.scriptOperators == null) + return false; + for (int i = 0; i < widget.scriptOperators.length; i++) { + int j = executeScript(widget, i); + int k = widget.scriptDefaults[i]; + if (widget.scriptOperators[i] == 2) { + if (j >= k) + return false; + } else if (widget.scriptOperators[i] == 3) { + if (j <= k) + return false; + } else if (widget.scriptOperators[i] == 4) { + if (j == k) + return false; + } else if (j != k) + return false; + } + + return true; + } + + private DataInputStream requestCacheIndex(String request) throws IOException { + if (!Configuration.useJaggrab) { + if (SignLink.mainapp != null) { + return SignLink.openUrl(request); + } + return new DataInputStream(new URL(getCodeBase(), request).openStream()); + } + if (jaggrab != null) { + try { + jaggrab.close(); + } catch (Exception _ex) { + } + jaggrab = null; + } + jaggrab = openSocket(43595); + jaggrab.setSoTimeout(10000); + java.io.InputStream inputstream = jaggrab.getInputStream(); + OutputStream outputstream = jaggrab.getOutputStream(); + outputstream.write(("JAGGRAB /" + request + "\n\n").getBytes()); + return new DataInputStream(inputstream); + } + + private void doFlamesDrawing() { + char c = '\u0100'; + if (anInt1040 > 0) { + for (int i = 0; i < 256; i++) + if (anInt1040 > 768) + anIntArray850[i] = method83(anIntArray851[i], anIntArray852[i], 1024 - anInt1040); + else if (anInt1040 > 256) + anIntArray850[i] = anIntArray852[i]; + else + anIntArray850[i] = method83(anIntArray852[i], anIntArray851[i], 256 - anInt1040); + + } else if (anInt1041 > 0) { + for (int j = 0; j < 256; j++) + if (anInt1041 > 768) + anIntArray850[j] = method83(anIntArray851[j], anIntArray853[j], 1024 - anInt1041); + else if (anInt1041 > 256) + anIntArray850[j] = anIntArray853[j]; + else + anIntArray850[j] = method83(anIntArray853[j], anIntArray851[j], 256 - anInt1041); + + } else { + System.arraycopy(anIntArray851, 0, anIntArray850, 0, 256); + + } + System.arraycopy(flameLeftSprite.getMyPixels(), 0, flameLeftBackground.canvasRaster, 0, 33920); + + int i1 = 0; + int j1 = 1152; + for (int k1 = 1; k1 < c - 1; k1++) { + int l1 = (anIntArray969[k1] * (c - k1)) / c; + int j2 = 22 + l1; + if (j2 < 0) + j2 = 0; + i1 += j2; + for (int l2 = j2; l2 < 128; l2++) { + int j3 = anIntArray828[i1++]; + if (j3 != 0) { + int l3 = j3; + int j4 = 256 - j3; + j3 = anIntArray850[j3]; + int l4 = flameLeftBackground.canvasRaster[j1]; + flameLeftBackground.canvasRaster[j1++] = ((j3 & 0xff00ff) * l3 + (l4 & 0xff00ff) * j4 & 0xff00ff00) + + ((j3 & 0xff00) * l3 + (l4 & 0xff00) * j4 & 0xff0000) >> 8; + } else { + j1++; + } + } + + j1 += j2; + } + + flameLeftBackground.drawGraphics(0, super.graphics, 0); + System.arraycopy(flameRightSprite.getMyPixels(), 0, flameRightBackground.canvasRaster, 0, 33920); + + i1 = 0; + j1 = 1176; + for (int k2 = 1; k2 < c - 1; k2++) { + int i3 = (anIntArray969[k2] * (c - k2)) / c; + int k3 = 103 - i3; + j1 += i3; + for (int i4 = 0; i4 < k3; i4++) { + int k4 = anIntArray828[i1++]; + if (k4 != 0) { + int i5 = k4; + int j5 = 256 - k4; + k4 = anIntArray850[k4]; + int k5 = flameRightBackground.canvasRaster[j1]; + flameRightBackground.canvasRaster[j1++] = ((k4 & 0xff00ff) * i5 + (k5 & 0xff00ff) * j5 & 0xff00ff00) + + ((k4 & 0xff00) * i5 + (k5 & 0xff00) * j5 & 0xff0000) >> 8; + } else { + j1++; + } + } + + i1 += 128 - k3; + j1 += 128 - k3 - i3; + } + + flameRightBackground.drawGraphics(0, super.graphics, 637); + } + + private void updateOtherPlayerMovement(Buffer stream) { + int count = stream.readBits(8); + + if (count < playerCount) { + for (int index = count; index < playerCount; index++) { + removedMobs[removedMobCount++] = playerList[index]; + } + } + if (count > playerCount) { + SignLink.reporterror(myUsername + " Too many players"); + throw new RuntimeException("eek"); + } + playerCount = 0; + for (int globalIndex = 0; globalIndex < count; globalIndex++) { + int index = playerList[globalIndex]; + Player player = players[index]; + + int updateRequired = stream.readBits(1); + + if (updateRequired == 0) { + playerList[playerCount++] = index; + player.time = tick; + } else { + int movementType = stream.readBits(2); + if (movementType == 0) { + playerList[playerCount++] = index; + player.time = tick; + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = index; + } else if (movementType == 1) { + playerList[playerCount++] = index; + player.time = tick; + + int direction = stream.readBits(3); + + player.moveInDir(false, direction); + + int update = stream.readBits(1); + + if (update == 1) { + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = index; + } + } else if (movementType == 2) { + playerList[playerCount++] = index; + player.time = tick; + + int firstDirection = stream.readBits(3); + player.moveInDir(true, firstDirection); + + int secondDirection = stream.readBits(3); + player.moveInDir(true, secondDirection); + + int update = stream.readBits(1); + if (update == 1) { + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = index; + } + } else if (movementType == 3) { + removedMobs[removedMobCount++] = index; + } + } + } + } + + public void loginScreenAccessories() { + /** + * World-selection + */ + setupLoginScreen(); + + loginScreenAccessories.drawGraphics(400, super.graphics, 0); + loginScreenAccessories.initDrawingArea(); + SpriteCache.lookup(57).drawSprite(6, 63); + if (!Configuration.worldSwitch) { + boldText.method382(0xffffff, 55, "World 301", 78, true); + smallText.method382(0xffffff, 55, "Click to switch", 92, true); + Configuration.server_address = "localhost"; + Configuration.server_port = 43594; + } else { + boldText.method382(0xffffff, 55, "World 302", 78, true); + smallText.method382(0xffffff, 55, "Click to switch", 92, true); + Configuration.server_address = "localhost"; + Configuration.server_port = 5555; + } + + loginMusicImageProducer.drawGraphics(265, super.graphics, 562); + loginMusicImageProducer.initDrawingArea(); + if (Configuration.enableMusic) { + SpriteCache.lookup(58).drawSprite(158, 196); + } else { + SpriteCache.lookup(59).drawSprite(158, 196); + stopMidi(); + } + + } + + public void drawMusicSprites() { + + int musicState = 0; + bottomRightImageProducer.initDrawingArea(); + switch (musicState) { + case 0: + SpriteCache.lookup(58).drawSprite(158, 196); + break; + + case 1: + SpriteCache.lookup(59).drawSprite(158, 196); + break; + } + } + + private void drawLoginScreen(boolean flag) { + setupLoginScreen(); + loginBoxImageProducer.initDrawingArea(); + titleBoxIndexedImage.draw(0, 0); + // regularText.render(0xffffff, "Mouse X: " + super.mouseX + + // " , Mouse Y: " + super.mouseY, 30, frameMode == ScreenMode.FIXED ? 5 + // : frameWidth - 5); + char c = '\u0168'; + char c1 = '\310'; + if (Configuration.enableMusic && !lowMemory) { + playSong(SoundConstants.SCAPE_RUNE); + } + if (loginScreenState == 0) { + int i = c1 / 2 + 80; + smallText.method382(0x75a9a9, c / 2, resourceProvider.loadingMessage, i, true); + i = c1 / 2 - 20; + boldText.method382(0xffff00, c / 2, "Welcome to " + Configuration.CLIENT_NAME, i, true); + i += 30; + int l = c / 2 - 80; + int k1 = c1 / 2 + 20; + titleButtonIndexedImage.draw(l - 73, k1 - 20); + boldText.method382(0xffffff, l, "New User", k1 + 5, true); + l = c / 2 + 80; + titleButtonIndexedImage.draw(l - 73, k1 - 20); + boldText.method382(0xffffff, l, "Existing User", k1 + 5, true); + } + if (loginScreenState == 2) { + int j = c1 / 2 - 40; + if (firstLoginMessage.length() > 0) { + boldText.method382(0xffff00, c / 2, firstLoginMessage, j - 15, true); + boldText.method382(0xffff00, c / 2, secondLoginMessage, j, true); + j += 30; + } else { + boldText.method382(0xffff00, c / 2, secondLoginMessage, j - 7, true); + j += 30; + } + boldText.drawTextWithPotentialShadow(true, c / 2 - 90, 0xffffff, + "Login: " + myUsername + ((loginScreenCursorPos == 0) & (tick % 40 < 20) ? "@yel@|" : ""), j); + j += 15; + boldText.drawTextWithPotentialShadow(true, c / 2 - 88, 0xffffff, + "Password: " + StringUtils.passwordAsterisks(myPassword) + + ((loginScreenCursorPos == 1) & (tick % 40 < 20) ? "@yel@|" : ""), + j); + j += 15; + if (!flag) { + int i1 = c / 2 - 80; + int l1 = c1 / 2 + 50; + titleButtonIndexedImage.draw(i1 - 73, l1 - 20); + boldText.method382(0xffffff, i1, "Login", l1 + 5, true); + i1 = c / 2 + 80; + titleButtonIndexedImage.draw(i1 - 73, l1 - 20); + boldText.method382(0xffffff, i1, "Cancel", l1 + 5, true); + } + } + if (loginScreenState == 3) { + loginScreenState = 0; + MiscUtils.launchURL(Configuration.REGISTER_ACCOUNT); + } + loginBoxImageProducer.drawGraphics(171, super.graphics, 202); + if (welcomeScreenRaised) { + welcomeScreenRaised = false; + topLeft1BackgroundTile.drawGraphics(0, super.graphics, 128); + bottomLeft1BackgroundTile.drawGraphics(371, super.graphics, 202); + bottomLeft0BackgroundTile.drawGraphics(265, super.graphics, 0); + bottomRightImageProducer.drawGraphics(265, super.graphics, 562); + middleLeft1BackgroundTile.drawGraphics(171, super.graphics, 128); + aRSImageProducer_1115.drawGraphics(171, super.graphics, 562); + } + loginScreenAccessories(); + } + + private void drawFlames() { + drawingFlames = true; + try { + long l = System.currentTimeMillis(); + int i = 0; + int j = 20; + while (aBoolean831) { + calcFlamesPosition(); + calcFlamesPosition(); + doFlamesDrawing(); + if (++i > 10) { + long l1 = System.currentTimeMillis(); + int k = (int) (l1 - l) / 10 - j; + j = 40 - k; + if (j < 5) + j = 5; + i = 0; + l = l1; + } + try { + Thread.sleep(j); + } catch (Exception _ex) { + } + } + } catch (Exception _ex) { + } + drawingFlames = false; + } + + public void raiseWelcomeScreen() { + welcomeScreenRaised = true; + } + + private void parseRegionPackets(Buffer stream, int packetType) { + if (packetType == PacketConstants.SEND_ALTER_GROUND_ITEM_COUNT) { + int offset = stream.readUnsignedByte(); + int xLoc = localX + (offset >> 4 & 7); + int yLoc = localY + (offset & 7); + int itemId = stream.readUShort(); + int oldItemCount = stream.readUShort(); + int newItemCount = stream.readUShort(); + if (xLoc >= 0 && yLoc >= 0 && xLoc < 104 && yLoc < 104) { + Deque groundItemsDeque = groundItems[plane][xLoc][yLoc]; + if (groundItemsDeque != null) { + for (Item groundItem = (Item) groundItemsDeque + .reverseGetFirst(); groundItem != null; groundItem = (Item) groundItemsDeque + .reverseGetNext()) { + if (groundItem.ID != (itemId & 0x7fff) || groundItem.itemCount != oldItemCount) + continue; + groundItem.itemCount = newItemCount; + break; + } + + updateGroundItems(xLoc, yLoc); + } + } + return; + } + if (packetType == 105) { + int l = stream.readUnsignedByte(); + int k3 = localX + (l >> 4 & 7); + int j6 = localY + (l & 7); + int i9 = stream.readUShort(); + int l11 = stream.readUnsignedByte(); + int i14 = l11 >> 4 & 0xf; + int i16 = l11 & 7; + if (localPlayer.pathX[0] >= k3 - i14 && localPlayer.pathX[0] <= k3 + i14 && localPlayer.pathY[0] >= j6 - i14 + && localPlayer.pathY[0] <= j6 + i14 && aBoolean848 && !lowMemory && trackCount < 50) { + tracks[trackCount] = i9; + trackLoops[trackCount] = i16; + soundDelay[trackCount] = Track.delays[i9]; + trackCount++; + } + } + if (packetType == 215) { + int i1 = stream.readUShortA(); + int l3 = stream.readUByteS(); + int k6 = localX + (l3 >> 4 & 7); + int j9 = localY + (l3 & 7); + int i12 = stream.readUShortA(); + int j14 = stream.readUShort(); + if (k6 >= 0 && j9 >= 0 && k6 < 104 && j9 < 104 && i12 != localPlayerIndex) { + Item class30_sub2_sub4_sub2_2 = new Item(); + class30_sub2_sub4_sub2_2.ID = i1; + class30_sub2_sub4_sub2_2.itemCount = j14; + if (groundItems[plane][k6][j9] == null) + groundItems[plane][k6][j9] = new Deque(); + groundItems[plane][k6][j9].insertHead(class30_sub2_sub4_sub2_2); + updateGroundItems(k6, j9); + } + return; + } + if (packetType == PacketConstants.SEND_REMOVE_GROUND_ITEM) { + int offset = stream.readUByteA(); + int xLoc = localX + (offset >> 4 & 7); + int yLoc = localY + (offset & 7); + int itemId = stream.readUShort(); + if (xLoc >= 0 && yLoc >= 0 && xLoc < 104 && yLoc < 104) { + Deque groundItemsDeque = groundItems[plane][xLoc][yLoc]; + if (groundItemsDeque != null) { + for (Item item = (Item) groundItemsDeque + .reverseGetFirst(); item != null; item = (Item) groundItemsDeque.reverseGetNext()) { + if (item.ID != (itemId & 0x7fff)) + continue; + item.unlink(); + break; + } + + if (groundItemsDeque.reverseGetFirst() == null) + groundItems[plane][xLoc][yLoc] = null; + updateGroundItems(xLoc, yLoc); + } + } + return; + } + if (packetType == PacketConstants.ANIMATE_OBJECT) { + int offset = stream.readUByteS(); + int xLoc = localX + (offset >> 4 & 7); + int yLoc = localY + (offset & 7); + int objectTypeFace = stream.readUByteS(); + int objectType = objectTypeFace >> 2; + int objectFace = objectTypeFace & 3; + int objectGenre = objectGroups[objectType]; + int animId = stream.readUShortA(); + if (xLoc >= 0 && yLoc >= 0 && xLoc < 103 && yLoc < 103) { + int heightA = tileHeights[plane][xLoc][yLoc]; + int heightB = tileHeights[plane][xLoc + 1][yLoc]; + int heightC = tileHeights[plane][xLoc + 1][yLoc + 1]; + int heightD = tileHeights[plane][xLoc][yLoc + 1]; + if (objectGenre == 0) {// WallObject + WallObject wallObjectObject = scene.getWallObject(plane, xLoc, yLoc); + if (wallObjectObject != null) { + int objectId = wallObjectObject.uid >> 14 & 0x7fff; + if (objectType == 2) { + wallObjectObject.renderable1 = new SceneObject(objectId, 4 + objectFace, 2, heightB, + heightC, heightA, heightD, animId, false); + wallObjectObject.renderable2 = new SceneObject(objectId, objectFace + 1 & 3, 2, heightB, + heightC, heightA, heightD, animId, false); + } else { + wallObjectObject.renderable1 = new SceneObject(objectId, objectFace, objectType, heightB, + heightC, heightA, heightD, animId, false); + } + } + } + if (objectGenre == 1) { // WallDecoration + WallDecoration wallDecoration = scene.getWallDecoration(xLoc, yLoc, plane); + if (wallDecoration != null) + wallDecoration.renderable = new SceneObject(wallDecoration.uid >> 14 & 0x7fff, 0, 4, heightB, + heightC, heightA, heightD, animId, false); + } + if (objectGenre == 2) { // TiledObject + GameObject tiledObject = scene.getGameObject(xLoc, yLoc, plane); + if (objectType == 11) + objectType = 10; + if (tiledObject != null) + tiledObject.renderable = new SceneObject(tiledObject.uid >> 14 & 0x7fff, objectFace, objectType, + heightB, heightC, heightA, heightD, animId, false); + } + if (objectGenre == 3) { // GroundDecoration + GroundDecoration groundDecoration = scene.getGroundDecoration(yLoc, xLoc, plane); + if (groundDecoration != null) + groundDecoration.renderable = new SceneObject(groundDecoration.uid >> 14 & 0x7fff, objectFace, + 22, heightB, heightC, heightA, heightD, animId, false); + } + } + return; + } + if (packetType == PacketConstants.TRANSFORM_PLAYER_TO_OBJECT) { + int offset = stream.readUByteS(); + int xLoc = localX + (offset >> 4 & 7); + int yLoc = localY + (offset & 7); + int playerIndex = stream.readUShort(); + byte byte0GreaterXLoc = stream.readByteS(); + int startDelay = stream.readLEUShort(); + byte byte1GreaterYLoc = stream.readNegByte(); + int stopDelay = stream.readUShort(); + int objectTypeFace = stream.readUByteS(); + int objectType = objectTypeFace >> 2; + int objectFace = objectTypeFace & 3; + int objectGenre = objectGroups[objectType]; + byte byte2LesserXLoc = stream.readSignedByte(); + int objectId = stream.readUShort(); + byte byte3LesserYLoc = stream.readNegByte(); + Player player; + if (playerIndex == localPlayerIndex) + player = localPlayer; + else + player = players[playerIndex]; + if (player != null) { + ObjectDefinition objectDefinition = ObjectDefinition.lookup(objectId); + int heightA = tileHeights[plane][xLoc][yLoc]; + int heightB = tileHeights[plane][xLoc + 1][yLoc]; + int heightC = tileHeights[plane][xLoc + 1][yLoc + 1]; + int heightD = tileHeights[plane][xLoc][yLoc + 1]; + Model model = objectDefinition.modelAt(objectType, objectFace, heightA, heightB, heightC, heightD, -1); + if (model != null) { + requestSpawnObject(stopDelay + 1, -1, 0, objectGenre, yLoc, 0, plane, xLoc, startDelay + 1); + player.objectModelStart = startDelay + tick; + player.objectModelStop = stopDelay + tick; + player.playerModel = model; + int playerSizeX = objectDefinition.objectSizeX; + int playerSizeY = objectDefinition.objectSizeY; + if (objectFace == 1 || objectFace == 3) { + playerSizeX = objectDefinition.objectSizeY; + playerSizeY = objectDefinition.objectSizeX; + } + player.objectXPos = xLoc * 128 + playerSizeX * 64; + player.objectYPos = yLoc * 128 + playerSizeY * 64; + player.objectCenterHeight = getCenterHeight(plane, player.objectYPos, player.objectXPos); + if (byte2LesserXLoc > byte0GreaterXLoc) { + byte tmp = byte2LesserXLoc; + byte2LesserXLoc = byte0GreaterXLoc; + byte0GreaterXLoc = tmp; + } + if (byte3LesserYLoc > byte1GreaterYLoc) { + byte tmp = byte3LesserYLoc; + byte3LesserYLoc = byte1GreaterYLoc; + byte1GreaterYLoc = tmp; + } + player.objectAnInt1719LesserXLoc = xLoc + byte2LesserXLoc; + player.objectAnInt1721GreaterXLoc = xLoc + byte0GreaterXLoc; + player.objectAnInt1720LesserYLoc = yLoc + byte3LesserYLoc; + player.objectAnInt1722GreaterYLoc = yLoc + byte1GreaterYLoc; + } + } + } + if (packetType == PacketConstants.SEND_OBJECT) { + int offset = stream.readUByteA(); + int x = localX + (offset >> 4 & 7); + int y = localY + (offset & 7); + int id = stream.readLEUShort(); + int objectTypeFace = stream.readUByteS(); + int type = objectTypeFace >> 2; + int orientation = objectTypeFace & 3; + int group = objectGroups[type]; + if (x >= 0 && y >= 0 && x < 104 && y < 104) { + requestSpawnObject(-1, id, orientation, group, y, type, plane, x, 0); + } + return; + } + if (packetType == PacketConstants.SEND_GFX) { + int offset = stream.readUnsignedByte(); + int xLoc = localX + (offset >> 4 & 7); + int yLoc = localY + (offset & 7); + int gfxId = stream.readUShort(); + int gfxHeight = stream.readUnsignedByte(); + int gfxDelay = stream.readUShort(); + if (xLoc >= 0 && yLoc >= 0 && xLoc < 104 && yLoc < 104) { + xLoc = xLoc * 128 + 64; + yLoc = yLoc * 128 + 64; + AnimableObject loneGfx = new AnimableObject(plane, tick, gfxDelay, gfxId, + getCenterHeight(plane, yLoc, xLoc) - gfxHeight, yLoc, xLoc); + incompleteAnimables.insertHead(loneGfx); + } + return; + } + if (packetType == PacketConstants.SEND_GROUND_ITEM) { + int itemId = stream.readLEUShortA(); + int itemCount = stream.readUShort(); + int offset = stream.readUnsignedByte(); + int xLoc = localX + (offset >> 4 & 7); + int yLoc = localY + (offset & 7); + if (xLoc >= 0 && yLoc >= 0 && xLoc < 104 && yLoc < 104) { + Item groundItem = new Item(); + groundItem.ID = itemId; + groundItem.itemCount = itemCount; + if (groundItems[plane][xLoc][yLoc] == null) + groundItems[plane][xLoc][yLoc] = new Deque(); + groundItems[plane][xLoc][yLoc].insertHead(groundItem); + updateGroundItems(xLoc, yLoc); + } + return; + } + if (packetType == PacketConstants.SEND_REMOVE_OBJECT) { + int objectTypeFace = stream.readNegUByte(); + int type = objectTypeFace >> 2; + int orientation = objectTypeFace & 3; + int group = objectGroups[type]; + int offset = stream.readUnsignedByte(); + int x = localX + (offset >> 4 & 7); + int y = localY + (offset & 7); + if (x >= 0 && y >= 0 && x < 104 && y < 104) { + requestSpawnObject(-1, -1, orientation, group, y, type, plane, x, 0); + } + return; + } + if (packetType == PacketConstants.SEND_PROJECTILE) { + int offset = stream.readUnsignedByte(); + int x1 = localX + (offset >> 4 & 7); + int y1 = localY + (offset & 7); + int x2 = x1 + stream.readSignedByte(); + int y2 = y1 + stream.readSignedByte(); + int target = stream.readShort(); + int gfxMoving = stream.readUShort(); + int startHeight = stream.readUnsignedByte() * 4; + int endHeight = stream.readUnsignedByte() * 4; + int startDelay = stream.readUShort(); + int speed = stream.readUShort(); + int initialSlope = stream.readUnsignedByte(); + int frontOffset = stream.readUnsignedByte(); + if (x1 >= 0 && y1 >= 0 && x1 < 104 && y1 < 104 && x2 >= 0 && y2 >= 0 && x2 < 104 && y2 < 104 + && gfxMoving != 65535) { + x1 = x1 * 128 + 64; + y1 = y1 * 128 + 64; + x2 = x2 * 128 + 64; + y2 = y2 * 128 + 64; + Projectile projectile = new Projectile(initialSlope, endHeight, startDelay + tick, speed + tick, + frontOffset, plane, getCenterHeight(plane, y1, x1) - startHeight, y1, x1, target, gfxMoving); + projectile.calculateIncrements(startDelay + tick, y2, getCenterHeight(plane, y2, x2) - endHeight, x2); + projectiles.insertHead(projectile); + } + } + } + + private void method139(Buffer stream) { + stream.initBitAccess(); + int k = stream.readBits(8); + if (k < npcCount) { + for (int l = k; l < npcCount; l++) + removedMobs[removedMobCount++] = npcIndices[l]; + + } + if (k > npcCount) { + SignLink.reporterror(myUsername + " Too many npcs"); + throw new RuntimeException("eek"); + } + npcCount = 0; + for (int i1 = 0; i1 < k; i1++) { + int j1 = npcIndices[i1]; + Npc npc = npcs[j1]; + int k1 = stream.readBits(1); + if (k1 == 0) { + npcIndices[npcCount++] = j1; + npc.time = tick; + } else { + int l1 = stream.readBits(2); + if (l1 == 0) { + npcIndices[npcCount++] = j1; + npc.time = tick; + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = j1; + } else if (l1 == 1) { + npcIndices[npcCount++] = j1; + npc.time = tick; + int i2 = stream.readBits(3); + npc.moveInDir(false, i2); + int k2 = stream.readBits(1); + if (k2 == 1) + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = j1; + } else if (l1 == 2) { + npcIndices[npcCount++] = j1; + npc.time = tick; + int j2 = stream.readBits(3); + npc.moveInDir(true, j2); + int l2 = stream.readBits(3); + npc.moveInDir(true, l2); + int i3 = stream.readBits(1); + if (i3 == 1) + mobsAwaitingUpdate[mobsAwaitingUpdateCount++] = j1; + } else if (l1 == 3) + removedMobs[removedMobCount++] = j1; + } + } + + } + + private void processLoginScreenInput() { + if (loginScreenState == 0) { + if (super.clickMode3 == 1 && super.saveClickX >= 722 && super.saveClickX <= 751 && super.saveClickY >= 463 + && super.saveClickY <= 493) { + Configuration.enableMusic = !Configuration.enableMusic; + } + + if (super.clickMode3 == 1 && super.saveClickX >= 7 && super.saveClickX <= 104 && super.saveClickY >= 464 + && super.saveClickY <= 493) { + Configuration.worldSwitch = !Configuration.worldSwitch; + } + + int i = super.myWidth / 2 - 80; + int l = super.myHeight / 2 + 20; + l += 20; + if (super.clickMode3 == 1 && super.saveClickX >= i - 75 && super.saveClickX <= i + 75 + && super.saveClickY >= l - 20 && super.saveClickY <= l + 20) { + loginScreenState = 3; + loginScreenCursorPos = 0; + } + i = super.myWidth / 2 + 80; + if (super.clickMode3 == 1 && super.saveClickX >= i - 75 && super.saveClickX <= i + 75 + && super.saveClickY >= l - 20 && super.saveClickY <= l + 20) { + firstLoginMessage = ""; + secondLoginMessage = "Enter your username & password."; + loginScreenState = 2; + loginScreenCursorPos = 0; + } + } else if (loginScreenState == 2) { + + if (super.clickMode3 == 1 && super.saveClickX >= 722 && super.saveClickX <= 751 && super.saveClickY >= 463 + && super.saveClickY <= 493) { + Configuration.enableMusic = !Configuration.enableMusic; + } + if (super.clickMode3 == 1 && super.saveClickX >= 7 && super.saveClickX <= 104 && super.saveClickY >= 464 + && super.saveClickY <= 493) { + Configuration.worldSwitch = !Configuration.worldSwitch; + } + int j = super.myHeight / 2 - 40; + j += 30; + j += 25; + if (super.clickMode3 == 1 && super.saveClickY >= j - 15 && super.saveClickY < j) + loginScreenCursorPos = 0; + j += 15; + if (super.clickMode3 == 1 && super.saveClickY >= j - 15 && super.saveClickY < j) + loginScreenCursorPos = 1; + j += 15; + int i1 = super.myWidth / 2 - 80; + int k1 = super.myHeight / 2 + 50; + k1 += 20; + if (super.clickMode3 == 1 && super.saveClickX >= i1 - 75 && super.saveClickX <= i1 + 75 + && super.saveClickY >= k1 - 20 && super.saveClickY <= k1 + 20) { + loginFailures = 0; + login(myUsername, myPassword, false); + if (loggedIn) + return; + } + i1 = super.myWidth / 2 + 80; + if (super.clickMode3 == 1 && super.saveClickX >= i1 - 75 && super.saveClickX <= i1 + 75 + && super.saveClickY >= k1 - 20 && super.saveClickY <= k1 + 20) { + loginScreenState = 0; + } + do { + int l1 = readChar(-796); + if (l1 == -1) + break; + boolean flag1 = false; + for (int i2 = 0; i2 < validUserPassChars.length(); i2++) { + if (l1 != validUserPassChars.charAt(i2)) + continue; + flag1 = true; + break; + } + + if (loginScreenCursorPos == 0) { + if (l1 == 8 && myUsername.length() > 0) + myUsername = myUsername.substring(0, myUsername.length() - 1); + if (l1 == 9 || l1 == 10 || l1 == 13) + loginScreenCursorPos = 1; + if (flag1) + myUsername += (char) l1; + if (myUsername.length() > 12) + myUsername = myUsername.substring(0, 12); + } else if (loginScreenCursorPos == 1) { + if (l1 == 8 && myPassword.length() > 0) + myPassword = myPassword.substring(0, myPassword.length() - 1); + if (l1 == 9 || l1 == 10 || l1 == 13) + loginScreenCursorPos = 0; + if (flag1) + myPassword += (char) l1; + if (myPassword.length() > 20) + myPassword = myPassword.substring(0, 20); + } + } while (true); + return; + } else if (loginScreenState == 3) { + int k = super.myWidth / 2; + int j1 = super.myHeight / 2 + 50; + j1 += 20; + if (super.clickMode3 == 1 && super.saveClickX >= k - 75 && super.saveClickX <= k + 75 + && super.saveClickY >= j1 - 20 && super.saveClickY <= j1 + 20) + loginScreenState = 0; + } + } + + private void removeObject(int y, int z, int k, int l, int x, int group, int previousId) { + if (x >= 1 && y >= 1 && x <= 102 && y <= 102) { + if (lowMemory && z != plane) + return; + int key = 0; + if (group == 0) + key = scene.getWallObjectUid(z, x, y); + if (group == 1) + key = scene.getWallDecorationUid(z, x, y); + if (group == 2) + key = scene.getGameObjectUid(z, x, y); + if (group == 3) + key = scene.getGroundDecorationUid(z, x, y); + if (key != 0) { + int config = scene.getMask(z, x, y, key); + int id = key >> 14 & 0x7fff; + int objectType = config & 0x1f; + int orientation = config >> 6; + if (group == 0) { + scene.removeWallObject(x, z, y); + ObjectDefinition objectDef = ObjectDefinition.lookup(id); + if (objectDef.solid) + collisionMaps[z].removeObject(orientation, objectType, objectDef.impenetrable, x, y); + } + if (group == 1) + scene.removeWallDecoration(y, z, x); + if (group == 2) { + scene.removeTiledObject(z, x, y); + ObjectDefinition objectDef = ObjectDefinition.lookup(id); + if (x + objectDef.objectSizeX > 103 || y + objectDef.objectSizeX > 103 + || x + objectDef.objectSizeY > 103 || y + objectDef.objectSizeY > 103) + return; + if (objectDef.solid) + collisionMaps[z].removeObject(orientation, objectDef.objectSizeX, x, y, objectDef.objectSizeY, + objectDef.impenetrable); + } + if (group == 3) { + scene.removeGroundDecoration(z, y, x); + ObjectDefinition objectDef = ObjectDefinition.lookup(id); + if (objectDef.solid && objectDef.isInteractive) + collisionMaps[z].removeFloorDecoration(y, x); + } + } + if (previousId >= 0) { + int plane = z; + if (plane < 3 && (tileFlags[1][x][y] & 2) == 2) + plane++; + MapRegion.placeObject(scene, k, y, l, plane, collisionMaps[z], tileHeights, x, previousId, z); + } + } + } + + private void updatePlayers(int packetSize, Buffer stream) { + removedMobCount = 0; + mobsAwaitingUpdateCount = 0; + updateLocalPlayerMovement(stream); + updateOtherPlayerMovement(stream); + updatePlayerList(stream, packetSize); + parsePlayerSynchronizationMask(stream); + for (int count = 0; count < removedMobCount; count++) { + int index = removedMobs[count]; + + if (players[index].time != tick) { + players[index] = null; + } + } + + if (stream.currentPosition != packetSize) { + SignLink.reporterror( + "Error packet size mismatch in getplayer pos:" + stream.currentPosition + " psize:" + packetSize); + throw new RuntimeException("eek"); + } + for (int count = 0; count < playerCount; count++) { + if (players[playerList[count]] == null) { + SignLink.reporterror(myUsername + " null entry in pl list - pos:" + count + " size:" + playerCount); + throw new RuntimeException("eek"); + } + } + + } + + private void setCameraPos(int j, int k, int l, int i1, int j1, int k1) { + int l1 = 2048 - k & 0x7ff; + int i2 = 2048 - j1 & 0x7ff; + int j2 = 0; + int k2 = 0; + int l2 = j; + if (l1 != 0) { + int i3 = Model.SINE[l1]; + int k3 = Model.COSINE[l1]; + int i4 = k2 * k3 - l2 * i3 >> 16; + l2 = k2 * i3 + l2 * k3 >> 16; + k2 = i4; + } + if (i2 != 0) { + int j3 = Model.SINE[i2]; + int l3 = Model.COSINE[i2]; + int j4 = l2 * j3 + j2 * l3 >> 16; + l2 = l2 * l3 - j2 * j3 >> 16; + j2 = j4; + } + xCameraPos = l - j2; + zCameraPos = i1 - k2; + yCameraPos = k1 - l2; + yCameraCurve = k; + xCameraCurve = j1; + } + + /** + * This method updates default messages upon login to the desired text of + * the interface text. + */ + public void updateStrings(String message, int index) { + switch (index) { + case 1675: + sendString(message, 17508); + break;// Stab + case 1676: + sendString(message, 17509); + break;// Slash + case 1677: + sendString(message, 17510); + break;// Crush + case 1678: + sendString(message, 17511); + break;// Magic + case 1679: + sendString(message, 17512); + break;// Range + case 1680: + // sendString(message, 17513); + break;// Stab + case 1681: + // sendString(message, 17514); + break;// Slash + case 1682: + // sendString(message, 17515); + break;// Crush + case 1683: + sendString(message, 17516); + break;// Magic + case 1684: + sendString(message, 17517); + break;// Range + case 1686: + sendString(message, 17518); + break;// Strength + case 1687: + sendString(message, 17519); + break;// Prayer + } + } + + /** + * Sends a string + */ + public void sendString(String text, int index) { + Widget.interfaceCache[index].defaultText = text; + if (Widget.interfaceCache[index].parent == tabInterfaceIDs[tabId]) { + } + } + + public void sendButtonClick(int button, int toggle, int type) { + Widget widget = Widget.interfaceCache[button]; + + System.out.println(String.format("button: %d toggle: %d type: %d", button, toggle, type)); + + switch (type) { + case 135: + boolean flag8 = true; + + if (widget.contentType > 0) { + flag8 = promptUserForInput(widget); + } + + if (flag8) { + outgoing.writeOpcode(185); + outgoing.writeShort(button); + } + break; + + // case reset setting widget + case 646: + outgoing.writeOpcode(185); + outgoing.writeShort(button); + + if (widget.scripts != null && widget.scripts[0][0] == 5) { + if (settings[toggle] != widget.scriptDefaults[0]) { + settings[toggle] = widget.scriptDefaults[0]; + updateVarp(toggle); + } + } + break; + + case 169: + outgoing.writeOpcode(185); + outgoing.writeShort(button); + if (widget.scripts != null && widget.scripts[0][0] == 5) { + settings[toggle] = 1 - settings[toggle]; + updateVarp(toggle); + } + break; + + default: + System.out.println("button: " + button + " - toggle: " + toggle + " - type: " + type); + break; + } + } + + /** + * Sets button configurations on interfaces. + */ + public void sendConfiguration(int id, int state) { + anIntArray1045[id] = state; + if (settings[id] != state) { + settings[id] = state; + updateVarp(id); + if (dialogueId != -1) + updateChatbox = true; + } + } + + /** + * Clears the screen of all open interfaces. + */ + public void clearScreen() { + if (overlayInterfaceId != -1) { + overlayInterfaceId = -1; + tabAreaAltered = true; + } + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + } + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + openInterfaceId = -1; + continuedDialogue = false; + } + + /** + * Displays an interface over the sidebar area. + */ + public void inventoryOverlay(int interfaceId, int sideInterfaceId) { + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + } + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + openInterfaceId = interfaceId; + overlayInterfaceId = sideInterfaceId; + tabAreaAltered = true; + continuedDialogue = false; + } + + private boolean readPacket() { + + if (socketStream == null) { + return false; + } + + try { + + int available = socketStream.available(); + + if (available == 0) { + return false; + } + if (opcode == -1) { + socketStream.flushInputStream(incoming.payload, 1); + opcode = incoming.payload[0] & 0xff; + if (encryption != null) + opcode = opcode - encryption.getNextKey() & 0xff; + packetSize = PacketConstants.PACKET_SIZES[opcode]; + available--; + } + if (packetSize == -1) + if (available > 0) { + socketStream.flushInputStream(incoming.payload, 1); + packetSize = incoming.payload[0] & 0xff; + available--; + } else { + return false; + } + if (packetSize == -2) + if (available > 1) { + socketStream.flushInputStream(incoming.payload, 2); + incoming.currentPosition = 0; + packetSize = incoming.readUShort(); + available -= 2; + } else { + return false; + } + if (available < packetSize) + return false; + incoming.currentPosition = 0; + socketStream.flushInputStream(incoming.payload, packetSize); + timeoutCounter = 0; + thirdLastOpcode = secondLastOpcode; + secondLastOpcode = lastOpcode; + lastOpcode = opcode; + + if (opcode == PacketConstants.PLAYER_UPDATING) { + updatePlayers(packetSize, incoming); + validLocalMap = false; + opcode = -1; + return true; + } + + if (opcode == 124) { + int skillId = incoming.readUShort(); + int gainedXP = incoming.readUShort(); + addToXPCounter(skillId, gainedXP); + opcode = -1; + return true; + } + + if (opcode == 183) { + try { + specialEnabled = incoming.readNegUByte(); + } catch (Exception e) { + e.printStackTrace(); + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.OPEN_WELCOME_SCREEN) { + daysSinceRecovChange = incoming.readNegUByte(); + unreadMessages = incoming.readUShortA(); + membersInt = incoming.readUnsignedByte(); + anInt1193 = incoming.readIMEInt(); + daysSinceLastLogin = incoming.readUShort(); + if (anInt1193 != 0 && openInterfaceId == -1) { + SignLink.dnslookup(StringUtils.decodeIp(anInt1193)); + clearTopInterfaces(); + char character = '\u028A'; + if (daysSinceRecovChange != 201 || membersInt == 1) + character = '\u028F'; + reportAbuseInput = ""; + canMute = false; + for (int interfaceId = 0; interfaceId < Widget.interfaceCache.length; interfaceId++) { + if (Widget.interfaceCache[interfaceId] == null + || Widget.interfaceCache[interfaceId].contentType != character) + continue; + openInterfaceId = Widget.interfaceCache[interfaceId].parent; + + } + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.DELETE_GROUND_ITEM) { + localX = incoming.readNegUByte(); + localY = incoming.readUByteS(); + for (int x = localX; x < localX + 8; x++) { + for (int y = localY; y < localY + 8; y++) + if (groundItems[plane][x][y] != null) { + groundItems[plane][x][y] = null; + updateGroundItems(x, y); + } + } + for (SpawnedObject object = (SpawnedObject) spawns + .reverseGetFirst(); object != null; object = (SpawnedObject) spawns.reverseGetNext()) + if (object.x >= localX && object.x < localX + 8 && object.y >= localY && object.y < localY + 8 + && object.plane == plane) + object.getLongetivity = 0; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SHOW_PLAYER_HEAD_ON_INTERFACE) { + int playerHeadModelId = incoming.readLEUShortA(); + Widget.interfaceCache[playerHeadModelId].defaultMediaType = 3; + if (localPlayer.npcDefinition == null) + Widget.interfaceCache[playerHeadModelId].defaultMedia = (localPlayer.appearanceColors[0] << 25) + + (localPlayer.appearanceColors[4] << 20) + (localPlayer.equipment[0] << 15) + + (localPlayer.equipment[8] << 10) + (localPlayer.equipment[11] << 5) + + localPlayer.equipment[1]; + else + Widget.interfaceCache[playerHeadModelId].defaultMedia = (int) (0x12345678L + + localPlayer.npcDefinition.interfaceType); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.CLAN_CHAT) { + try { + name = incoming.readString(); + defaultText = incoming.readString(); + clanname = incoming.readString(); + rights = incoming.readUShort(); + System.out.println(clanname); + sendMessage(defaultText, 16, name); + } catch (Exception e) { + e.printStackTrace(); + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.RESET_CAMERA) { + oriented = false; + for (int l = 0; l < 5; l++) + quakeDirectionActive[l] = false; + xpCounter = 0; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.CLEAN_ITEMS_OF_INTERFACE) { + int id = incoming.readLEUShort(); + Widget widget = Widget.interfaceCache[id]; + for (int slot = 0; slot < widget.inventoryItemId.length; slot++) { + widget.inventoryItemId[slot] = -1; + widget.inventoryItemId[slot] = 0; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SHOW_IGNORE_NAMES) { + ignoreCount = packetSize / 8; + for (int index = 0; index < ignoreCount; index++) + ignoreListAsLongs[index] = incoming.readLong(); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SPIN_CAMERA) { + oriented = true; + x = incoming.readUnsignedByte(); + y = incoming.readUnsignedByte(); + height = incoming.readUShort(); + speed = incoming.readUnsignedByte(); + angle = incoming.readUnsignedByte(); + if (angle >= 100) { + xCameraPos = x * 128 + 64; + yCameraPos = y * 128 + 64; + zCameraPos = getCenterHeight(plane, yCameraPos, xCameraPos) - height; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_SKILL) { + int skill = incoming.readUnsignedByte(); + int experience = incoming.readMEInt(); + int level = incoming.readUnsignedByte(); + if (skill < currentExp.length) { + int xp = experience - currentExp[skill]; + if (currentExp[skill] > -1) + addToXPCounter(skill, xp); + currentExp[skill] = experience; + currentStats[skill] = level; + maximumLevels[skill] = 1; + for (int index = 0; index < 98; index++) + if (experience >= SKILL_EXPERIENCE[index]) + maximumLevels[skill] = index + 2; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_SIDE_TAB) { + int id = incoming.readUShort(); + int tab = incoming.readUByteA(); + if (id == 65535) + id = -1; + tabInterfaceIDs[tab] = id; + tabAreaAltered = true; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.PLAY_SONG) { + int id = incoming.readLEUShort(); + if (id == 65535) + id = -1; + if (id != currentSong && Configuration.enableMusic && !lowMemory && prevSong == 0) { + nextSong = id; + fadeMusic = true; + resourceProvider.provide(2, nextSong); + } + currentSong = id; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.NEXT_OR_PREVIOUS_SONG) { + int id = incoming.readLEUShortA(); + int delay = incoming.readUShortA(); + if (Configuration.enableMusic && !lowMemory) { + nextSong = id; + fadeMusic = false; + resourceProvider.provide(2, nextSong); + prevSong = delay; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.LOGOUT) { + resetLogout(); + opcode = -1; + return false; + } + + if (opcode == PacketConstants.MOVE_COMPONENT) { + int horizontalOffset = incoming.readShort(); + int verticalOffset = incoming.readLEShort(); + int id = incoming.readLEUShort(); + Widget widget = Widget.interfaceCache[id]; + widget.x = horizontalOffset; + widget.anInt265 = verticalOffset; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_MAP_REGION || opcode == PacketConstants.SEND_REGION_MAP_REGION) { + int regionX = this.regionX; + int regionY = this.regionY; + if (opcode == 73) { + regionX = incoming.readUShortA(); + regionY = incoming.readUShort(); + constructedViewport = false; + } else if (opcode == 241) { + regionY = incoming.readUShortA(); + incoming.initBitAccess(); + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 13; x++) { + for (int y = 0; y < 13; y++) { + + int visible = incoming.readBits(1); + + if (visible == 1) { + localRegions[z][x][y] = incoming.readBits(26); + } else { + localRegions[z][x][y] = -1; + } + } + } + } + incoming.disableBitAccess(); + regionX = incoming.readUShort(); + constructedViewport = true; + } + if (this.regionX == regionX && this.regionY == regionY && loadingStage == 2) { + opcode = -1; + return true; + } + this.regionX = regionX; + this.regionY = regionY; + regionBaseX = (this.regionX - 6) * 8; + regionBaseY = (this.regionY - 6) * 8; + inPlayerOwnedHouse = (this.regionX / 8 == 48 || this.regionX / 8 == 49) && this.regionY / 8 == 48; + if (this.regionX / 8 == 48 && this.regionY / 8 == 148) + inPlayerOwnedHouse = true; + loadingStage = 1; + loadingStartTime = System.currentTimeMillis(); + gameScreenImageProducer.initDrawingArea(); + drawLoadingMessages(1, "Loading - please wait.", null); + gameScreenImageProducer.drawGraphics(frameMode == ScreenMode.FIXED ? 4 : 0, super.graphics, + frameMode == ScreenMode.FIXED ? 4 : 0); + if (opcode == 73) { + int regionCount = 0; + for (int x = (this.regionX - 6) / 8; x <= (this.regionX + 6) / 8; x++) { + for (int y = (this.regionY - 6) / 8; y <= (this.regionY + 6) / 8; y++) + regionCount++; + } + localRegionMapData = new byte[regionCount][]; + localRegionLandscapeData = new byte[regionCount][]; + localRegionIds = new int[regionCount]; + localRegionMapIds = new int[regionCount]; + localRegionLandscapeIds = new int[regionCount]; + regionCount = 0; + + for (int x = (this.regionX - 6) / 8; x <= (this.regionX + 6) / 8; x++) { + for (int y = (this.regionY - 6) / 8; y <= (this.regionY + 6) / 8; y++) { + localRegionIds[regionCount] = (x << 8) + y; + if (inPlayerOwnedHouse + && (y == 49 || y == 149 || y == 147 || x == 50 || x == 49 && y == 47)) { + localRegionMapIds[regionCount] = -1; + localRegionLandscapeIds[regionCount] = -1; + regionCount++; + } else { + int map = localRegionMapIds[regionCount] = resourceProvider.resolve(0, y, x); + if (map != -1) { + resourceProvider.provide(3, map); + } + + int landscape = localRegionLandscapeIds[regionCount] = resourceProvider.resolve(1, y, + x); + if (landscape != -1) { + resourceProvider.provide(3, landscape); + } + regionCount++; + } + } + } + } + if (opcode == 241) { + int regionCount = 0; + + int[] regionIds = new int[676]; + + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 13; x++) { + for (int y = 0; y < 13; y++) { + + int data = localRegions[z][x][y]; + + if (data != -1) { + int constructedRegionX = data >> 14 & 0x3ff; + int constructedRegionY = data >> 3 & 0x7ff; + int region = (constructedRegionX / 8 << 8) + constructedRegionY / 8; + for (int index = 0; index < regionCount; index++) { + if (regionIds[index] != region) { + continue; + } + region = -1; + break; + } + if (region != -1) { + regionIds[regionCount++] = region; + } + } + } + } + } + localRegionMapData = new byte[regionCount][]; + localRegionLandscapeData = new byte[regionCount][]; + localRegionIds = new int[regionCount]; + localRegionMapIds = new int[regionCount]; + localRegionLandscapeIds = new int[regionCount]; + for (int index = 0; index < regionCount; index++) { + int id = localRegionIds[index] = regionIds[index]; + int constructedRegionX = id >> 8 & 0xff; + int constructedRegionY = id & 0xff; + int map = localRegionMapIds[index] = resourceProvider.resolve(0, constructedRegionY, + constructedRegionX); + + if (map != -1) { + resourceProvider.provide(3, map); + } + + int landscape = localRegionLandscapeIds[index] = resourceProvider.resolve(1, constructedRegionY, + constructedRegionX); + + if (landscape != -1) { + resourceProvider.provide(3, landscape); + } + + } + } + int dx = regionBaseX - previousAbsoluteX; + int dy = regionBaseY - previousAbsoluteY; + previousAbsoluteX = regionBaseX; + previousAbsoluteY = regionBaseY; + for (int index = 0; index < 16384; index++) { + Npc npc = npcs[index]; + if (npc != null) { + for (int point = 0; point < 10; point++) { + npc.pathX[point] -= dx; + npc.pathY[point] -= dy; + } + npc.x -= dx * 128; + npc.y -= dy * 128; + } + } + for (int index = 0; index < maxPlayers; index++) { + Player player = players[index]; + if (player != null) { + for (int point = 0; point < 10; point++) { + player.pathX[point] -= dx; + player.pathY[point] -= dy; + } + player.x -= dx * 128; + player.y -= dy * 128; + } + } + validLocalMap = true; + byte startX = 0; + byte endX = 104; + byte stepX = 1; + if (dx < 0) { + startX = 103; + endX = -1; + stepX = -1; + } + byte startY = 0; + byte endY = 104; + byte stepY = 1; + + if (dy < 0) { + startY = 103; + endY = -1; + stepY = -1; + } + for (int x = startX; x != endX; x += stepX) { + for (int y = startY; y != endY; y += stepY) { + int shiftedX = x + dx; + int shiftedY = y + dy; + for (int plane = 0; plane < 4; plane++) + if (shiftedX >= 0 && shiftedY >= 0 && shiftedX < 104 && shiftedY < 104) { + groundItems[plane][x][y] = groundItems[plane][shiftedX][shiftedY]; + } else { + groundItems[plane][x][y] = null; + } + } + } + for (SpawnedObject object = (SpawnedObject) spawns + .reverseGetFirst(); object != null; object = (SpawnedObject) spawns.reverseGetNext()) { + object.x -= dx; + object.y -= dy; + if (object.x < 0 || object.y < 0 || object.x >= 104 || object.y >= 104) + object.unlink(); + } + if (destinationX != 0) { + destinationX -= dx; + destY -= dy; + } + oriented = false; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_WALKABLE_INTERFACE) { + int interfaceId = incoming.readLEShort(); + if (interfaceId >= 0) + resetAnimation(interfaceId); + openWalkableInterface = interfaceId; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_MINIMAP_STATE) { + minimapState = incoming.readUnsignedByte(); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SHOW_NPC_HEAD_ON_INTERFACE) { + int npcId = incoming.readLEUShortA(); + int interfaceId = incoming.readLEUShortA(); + Widget.interfaceCache[interfaceId].defaultMediaType = 2; + Widget.interfaceCache[interfaceId].defaultMedia = npcId; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SYSTEM_UPDATE) { + systemUpdateTime = incoming.readLEUShort() * 30; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_MULTIPLE_MAP_PACKETS) { + localY = incoming.readUnsignedByte(); + localX = incoming.readNegUByte(); + while (incoming.currentPosition < packetSize) { + int k3 = incoming.readUnsignedByte(); + parseRegionPackets(incoming, k3); + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_EARTHQUAKE) { + int quakeDirection = incoming.readUnsignedByte(); + int quakeMagnitude = incoming.readUnsignedByte(); + int quakeAmplitude = incoming.readUnsignedByte(); + int fourPiOverPeriod = incoming.readUnsignedByte(); + quakeDirectionActive[quakeDirection] = true; + quakeMagnitudes[quakeDirection] = quakeMagnitude; + quakeAmplitudes[quakeDirection] = quakeAmplitude; + quake4PiOverPeriods[quakeDirection] = fourPiOverPeriod; + quakeTimes[quakeDirection] = 0; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.PLAY_SOUND_EFFECT) { + int soundId = incoming.readUShort(); + int type = incoming.readUnsignedByte(); + int delay = incoming.readUShort(); + int volume = incoming.readUShort(); + tracks[trackCount] = soundId; + trackLoops[trackCount] = type; + soundDelay[trackCount] = delay + Track.delays[soundId]; + soundVolume[trackCount] = volume; + trackCount++; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_PLAYER_OPTION) { + int slot = incoming.readNegUByte(); + int lowPriority = incoming.readUByteA(); + String message = incoming.readString(); + if (slot >= 1 && slot <= 5) { + if (message.equalsIgnoreCase("null")) + message = null; + playerOptions[slot - 1] = message; + playerOptionsHighPriority[slot - 1] = lowPriority == 0; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.CLEAR_MINIMAP_FLAG) { + destinationX = 0; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_MESSAGE) { + String message = incoming.readString(); + if (message.endsWith(":tradereq:")) { + String name = message.substring(0, message.indexOf(":")); + long encodedName = StringUtils.encodeBase37(name); + boolean ignored = false; + for (int index = 0; index < ignoreCount; index++) { + if (ignoreListAsLongs[index] != encodedName) + continue; + ignored = true; + + } + if (!ignored && onTutorialIsland == 0) + sendMessage("wishes to trade with you.", 4, name); + } else if (message.endsWith(":clan:")) { + String name = message.substring(0, message.indexOf(":")); + StringUtils.encodeBase37(name); + sendMessage("Clan: ", 8, name); + } else if (message.endsWith("#url#")) { + String link = message.substring(0, message.indexOf("#")); + sendMessage("Join us at: ", 9, link); + } else if (message.endsWith(":duelreq:")) { + String name = message.substring(0, message.indexOf(":")); + long encodedName = StringUtils.encodeBase37(name); + boolean ignored = false; + for (int count = 0; count < ignoreCount; count++) { + if (ignoreListAsLongs[count] != encodedName) + continue; + ignored = true; + + } + if (!ignored && onTutorialIsland == 0) + sendMessage("wishes to duel with you.", 8, name); + } else if (message.endsWith(":chalreq:")) { + String name = message.substring(0, message.indexOf(":")); + long encodedName = StringUtils.encodeBase37(name); + boolean ignored = false; + for (int index = 0; index < ignoreCount; index++) { + if (ignoreListAsLongs[index] != encodedName) + continue; + ignored = true; + + } + if (!ignored && onTutorialIsland == 0) { + String msg = message.substring(message.indexOf(":") + 1, message.length() - 9); + sendMessage(msg, 8, name); + } + } else if (message.endsWith(":resetautocast:")) { + autocast = false; + autoCastId = 0; + SpriteCache.lookup(43).drawSprite(-100, -100); + } else { + sendMessage(message, 0, ""); + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.STOP_ALL_ANIMATIONS) { + for (int index = 0; index < players.length; index++) { + if (players[index] != null) + players[index].emoteAnimation = -1; + } + for (int index = 0; index < npcs.length; index++) { + if (npcs[index] != null) + npcs[index].emoteAnimation = -1; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.ADD_SET_FRIEND) { + long encodedName = incoming.readLong(); + int world = incoming.readUnsignedByte(); + String name = StringUtils.formatUsername(StringUtils.decodeBase37(encodedName)); + for (int playerIndex = 0; playerIndex < friendsCount; playerIndex++) { + if (encodedName != friendsListAsLongs[playerIndex]) + continue; + if (friendsNodeIDs[playerIndex] != world) { + friendsNodeIDs[playerIndex] = world; + if (world >= 2) { + sendMessage(name + " has logged in.", 5, ""); + } + if (world <= 1) { + sendMessage(name + " has logged out.", 5, ""); + } + } + name = null; + + } + if (name != null && friendsCount < 200) { + friendsListAsLongs[friendsCount] = encodedName; + friendsList[friendsCount] = name; + friendsNodeIDs[friendsCount] = world; + friendsCount++; + } + for (boolean stopSorting = false; !stopSorting; ) { + stopSorting = true; + for (int friendIndex = 0; friendIndex < friendsCount - 1; friendIndex++) + if (friendsNodeIDs[friendIndex] != nodeID && friendsNodeIDs[friendIndex + 1] == nodeID + || friendsNodeIDs[friendIndex] == 0 && friendsNodeIDs[friendIndex + 1] != 0) { + int tempFriendNodeId = friendsNodeIDs[friendIndex]; + friendsNodeIDs[friendIndex] = friendsNodeIDs[friendIndex + 1]; + friendsNodeIDs[friendIndex + 1] = tempFriendNodeId; + String tempFriendName = friendsList[friendIndex]; + friendsList[friendIndex] = friendsList[friendIndex + 1]; + friendsList[friendIndex + 1] = tempFriendName; + long tempFriendLong = friendsListAsLongs[friendIndex]; + friendsListAsLongs[friendIndex] = friendsListAsLongs[friendIndex + 1]; + friendsListAsLongs[friendIndex + 1] = tempFriendLong; + stopSorting = false; + } + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_RUN_ENERGY) { + runEnergy = incoming.readUnsignedByte(); + System.out.println("setting runEnergy: " + runEnergy); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_HINT_ICON) { + // the first byte, which indicates the type of mob + hintIconDrawType = incoming.readUnsignedByte(); + if (hintIconDrawType == 1) // NPC Hint Arrow + // the world index or slot of the npc in the server (which + // is also the same for the client (should)) + hintIconNpcId = incoming.readUShort(); + if (hintIconDrawType >= 2 && hintIconDrawType <= 6) { // Location + // Hint + // Arrow + if (hintIconDrawType == 2) { // Center + hintIconLocationArrowRelX = 64; + hintIconLocationArrowRelY = 64; + } + if (hintIconDrawType == 3) { // West side + hintIconLocationArrowRelX = 0; + hintIconLocationArrowRelY = 64; + } + if (hintIconDrawType == 4) { // East side + hintIconLocationArrowRelX = 128; + hintIconLocationArrowRelY = 64; + } + if (hintIconDrawType == 5) { // South side + hintIconLocationArrowRelX = 64; + hintIconLocationArrowRelY = 0; + } + if (hintIconDrawType == 6) { // North side + hintIconLocationArrowRelX = 64; + hintIconLocationArrowRelY = 128; + } + hintIconDrawType = 2; + // x offset + hintIconX = incoming.readUShort(); + + // y offset + hintIconY = incoming.readUShort(); + + // z offset + hintIconLocationArrowHeight = incoming.readUnsignedByte(); + } + if (hintIconDrawType == 10) // Player Hint Arrow + hintIconPlayerId = incoming.readUShort(); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_DUO_INTERFACE) { // Send Duo + // Interface: + // Main + + // Sidebar + int mainInterfaceId = incoming.readUShortA(); + int sidebarOverlayInterfaceId = incoming.readUShort(); + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + } + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + openInterfaceId = mainInterfaceId; + overlayInterfaceId = sidebarOverlayInterfaceId; + tabAreaAltered = true; + continuedDialogue = false; + opcode = -1; + return true; + } + + if (opcode == 79) { + int id = incoming.readLEUShort(); + int scrollPosition = incoming.readUShortA(); + Widget widget = Widget.interfaceCache[id]; + if (widget != null && widget.type == 0) { + if (scrollPosition < 0) + scrollPosition = 0; + if (scrollPosition > widget.scrollMax - widget.height) + scrollPosition = widget.scrollMax - widget.height; + widget.scrollPosition = scrollPosition; + } + opcode = -1; + return true; + } + + if (opcode == 68) { + for (int k5 = 0; k5 < settings.length; k5++) + if (settings[k5] != anIntArray1045[k5]) { + settings[k5] = anIntArray1045[k5]; + updateVarp(k5); + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_RECEIVED_PRIVATE_MESSAGE) { + long encodedName = incoming.readLong(); + int messageId = incoming.readInt(); + int rights = incoming.readUnsignedByte(); + boolean ignoreRequest = false; + for (int index = 0; index < 100; index++) { + if (privateMessageIds[index] != messageId) + continue; + ignoreRequest = true; + + } + if (rights <= 1) { + for (int index = 0; index < ignoreCount; index++) { + if (ignoreListAsLongs[index] != encodedName) + continue; + ignoreRequest = true; + + } + } + if (!ignoreRequest && onTutorialIsland == 0) + try { + privateMessageIds[privateMessageCount] = messageId; + privateMessageCount = (privateMessageCount + 1) % 100; + String message = ChatMessageCodec.decode(packetSize - 13, incoming); + // if(l21 != 3) + // s9 = Censor.doCensor(s9); + if (rights == 2 || rights == 3) + sendMessage(message, 7, + "@cr2@" + StringUtils.formatUsername(StringUtils.decodeBase37(encodedName))); + else if (rights == 1) + sendMessage(message, 7, + "@cr1@" + StringUtils.formatUsername(StringUtils.decodeBase37(encodedName))); + else + sendMessage(message, 3, StringUtils.formatUsername(StringUtils.decodeBase37(encodedName))); + } catch (Exception ex) { + SignLink.reporterror("cde1"); + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_REGION) { + localY = incoming.readNegUByte(); + localX = incoming.readNegUByte(); + opcode = -1; + return true; + } + + if (opcode == 24) { + flashingSidebarId = incoming.readUByteS(); + if (flashingSidebarId == tabId) { + if (flashingSidebarId == 3) + tabId = 1; + else + tabId = 3; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_ITEM_TO_INTERFACE) { + int widget = incoming.readLEUShort(); + int scale = incoming.readUShort(); + int item = incoming.readUShort(); + if (item == 65535) { + Widget.interfaceCache[widget].defaultMediaType = 0; + opcode = -1; + return true; + } else { + ItemDefinition definition = ItemDefinition.lookup(item); + Widget.interfaceCache[widget].defaultMediaType = 4; + Widget.interfaceCache[widget].defaultMedia = item; + Widget.interfaceCache[widget].modelRotation1 = definition.rotationY; + Widget.interfaceCache[widget].modelRotation2 = definition.rotationY; + Widget.interfaceCache[widget].modelZoom = (definition.modelZoom * 100) / scale; + opcode = -1; + return true; + } + } + + if (opcode == PacketConstants.SHOW_HIDE_INTERFACE_CONTAINER) { + boolean hide = incoming.readUnsignedByte() == 1; + int id = incoming.readUShort(); + Widget.interfaceCache[id].invisible = hide; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_SOLO_NON_WALKABLE_SIDEBAR_INTERFACE) { + int id = incoming.readLEUShort(); + resetAnimation(id); + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + } + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + overlayInterfaceId = id; + tabAreaAltered = true; + openInterfaceId = -1; + continuedDialogue = false; + opcode = -1; + return true; + } + + if (opcode == 137) { + try { + int special = incoming.readUnsignedByte(); + specialOrb = special; + } catch (Exception e) { + e.printStackTrace(); + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SET_INTERFACE_TEXT) { + try { + String text = incoming.readString(); + int id = incoming.readUShortA(); + if (text.startsWith("www.")) { + MiscUtils.launchURL(text); + } + if (text.startsWith(":quicks:")) // TODO what is this + // abomination? + clickedQuickPrayers = text.substring(8).equalsIgnoreCase("on"); + if (text.startsWith(":prayer:")) // TODO and what is this + // abomination? + prayerBook = text.substring(8); + updateStrings(text, id); + sendString(text, id); + if (id >= 18144 && id <= 18244) { + clanList[id - 18144] = text; + } + } catch (Exception e) { + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.UPDATE_CHAT_MODES) { + publicChatMode = incoming.readUnsignedByte(); + privateChatMode = incoming.readUnsignedByte(); + tradeMode = incoming.readUnsignedByte(); + updateChatbox = true; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_PLAYER_WEIGHT) { + weight = incoming.readShort(); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_MODEL_TO_INTERFACE) { + int id = incoming.readLEUShortA(); + int model = incoming.readUShort(); + Widget.interfaceCache[id].defaultMediaType = 1; + Widget.interfaceCache[id].defaultMedia = model; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_CHANGE_INTERFACE_COLOUR) { + int id = incoming.readLEUShortA(); + int color = incoming.readLEUShortA(); + int red = color >> 10 & 0x1f; + int green = color >> 5 & 0x1f; + int blue = color & 0x1f; + Widget.interfaceCache[id].textColor = (red << 19) + (green << 11) + (blue << 3); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_UPDATE_ITEMS) { + int interfaceId = incoming.readUShort(); + Widget widget = Widget.interfaceCache[interfaceId]; + int itemCount = incoming.readUShort(); + for (int j22 = 0; j22 < itemCount; j22++) { + int amount = incoming.readUnsignedByte(); + if (amount == 255) { + amount = incoming.readIMEInt(); + } + widget.inventoryItemId[j22] = incoming.readLEUShortA(); + widget.inventoryAmounts[j22] = amount; + } + for (int slot = itemCount; slot < widget.inventoryItemId.length; slot++) { + widget.inventoryItemId[slot] = 0; + widget.inventoryAmounts[slot] = 0; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SET_MODEL_INTERFACE_ZOOM) { + int scale = incoming.readUShortA(); + int id = incoming.readUShort(); + int pitch = incoming.readUShort(); + int roll = incoming.readLEUShortA(); + Widget.interfaceCache[id].modelRotation1 = pitch; + Widget.interfaceCache[id].modelRotation2 = roll; + Widget.interfaceCache[id].modelZoom = scale; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SET_FRIENDSERVER_STATUS) { + friendServerStatus = incoming.readUnsignedByte(); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.MOVE_CAMERA) { // Gradually turn + // camera to spatial + // point. + oriented = true; + cinematicCamXViewpointLoc = incoming.readUnsignedByte(); + cinematicCamYViewpointLoc = incoming.readUnsignedByte(); + cinematicCamZViewpointLoc = incoming.readUShort(); + constCinematicCamRotationSpeed = incoming.readUnsignedByte(); + varCinematicCamRotationSpeedPromille = incoming.readUnsignedByte(); + if (varCinematicCamRotationSpeedPromille >= 100) { + int cinCamXViewpointPos = cinematicCamXViewpointLoc * 128 + 64; + int cinCamYViewpointPos = cinematicCamYViewpointLoc * 128 + 64; + int cinCamZViewpointPos = getCenterHeight(plane, cinCamYViewpointPos, cinCamXViewpointPos) + - cinematicCamZViewpointLoc; + int dXPos = cinCamXViewpointPos - xCameraPos; + int dYPos = cinCamYViewpointPos - yCameraPos; + int dZPos = cinCamZViewpointPos - zCameraPos; + int flatDistance = (int) Math.sqrt(dXPos * dXPos + dYPos * dYPos); + yCameraCurve = (int) (Math.atan2(dZPos, flatDistance) * 325.94900000000001D) & 0x7ff; + xCameraCurve = (int) (Math.atan2(dXPos, dYPos) * -325.94900000000001D) & 0x7ff; + if (yCameraCurve < 128) + yCameraCurve = 128; + if (yCameraCurve > 383) + yCameraCurve = 383; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_INITIALIZE_PACKET) { + member = incoming.readUByteA(); + localPlayerIndex = incoming.readLEUShortA(); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.NPC_UPDATING) { + updateNPCs(incoming, packetSize); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_ENTER_AMOUNT) { + messagePromptRaised = false; + inputDialogState = 1; + amountOrNameInput = ""; + updateChatbox = true; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_ENTER_NAME) { // Send Enter Name + // Dialogue + // (still allows + // numbers) + messagePromptRaised = false; + inputDialogState = 2; + amountOrNameInput = ""; + updateChatbox = true; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_NON_WALKABLE_INTERFACE) { + int interfaceId = incoming.readUShort(); + resetAnimation(interfaceId); + if (overlayInterfaceId != -1) { + overlayInterfaceId = -1; + tabAreaAltered = true; + } + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + } + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + if (interfaceId == 15244) { + fullscreenInterfaceID = 17511; + openInterfaceId = 15244; + } + openInterfaceId = interfaceId; + continuedDialogue = false; + opcode = -1; + + return true; + } + + if (opcode == PacketConstants.SEND_WALKABLE_CHATBOX_INTERFACE) { + dialogueId = incoming.readLEShortA(); + updateChatbox = true; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_CONFIG_INT) { + int id = incoming.readLEUShort(); + int value = incoming.readMEInt(); + anIntArray1045[id] = value; + if (settings[id] != value) { + settings[id] = value; + updateVarp(id); + if (dialogueId != -1) + updateChatbox = true; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_CONFIG_BYTE) { + int id = incoming.readLEUShort(); + byte value = incoming.readSignedByte(); + anIntArray1045[id] = value; + if (settings[id] != value) { + settings[id] = value; + updateVarp(id); + if (dialogueId != -1) + updateChatbox = true; + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_MULTICOMBAT_ICON) { + multicombat = incoming.readUnsignedByte(); // 1 is active + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_ANIMATE_INTERFACE) { + int id = incoming.readUShort(); + int animation = incoming.readShort(); + Widget widget = Widget.interfaceCache[id]; + widget.defaultAnimationId = animation; + opcode = -1; + return true; + } + + if (opcode == PacketConstants.CLOSE_INTERFACE) { + if (overlayInterfaceId != -1) { + overlayInterfaceId = -1; + tabAreaAltered = true; + } + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + } + if (inputDialogState != 0) { + inputDialogState = 0; + updateChatbox = true; + } + openInterfaceId = -1; + continuedDialogue = false; + opcode = -1; + return true; + } + if (opcode == PacketConstants.UPDATE_SPECIFIC_ITEM) { + int interfaceId = incoming.readUShort(); + Widget widget = Widget.interfaceCache[interfaceId]; + while (incoming.currentPosition < packetSize) { + int slot = incoming.readUSmart(); + int id = incoming.readUShort(); + int amount = incoming.readUnsignedByte(); + if (amount == 255) + amount = incoming.readInt(); + if (slot >= 0 && slot < widget.inventoryItemId.length) { + widget.inventoryItemId[slot] = id; + widget.inventoryAmounts[slot] = amount; + } + } + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SEND_GFX || opcode == PacketConstants.SEND_GROUND_ITEM + || opcode == PacketConstants.SEND_ALTER_GROUND_ITEM_COUNT + || opcode == PacketConstants.SEND_REMOVE_OBJECT || opcode == 105 + || opcode == PacketConstants.SEND_PROJECTILE || opcode == PacketConstants.TRANSFORM_PLAYER_TO_OBJECT + || opcode == PacketConstants.SEND_OBJECT || opcode == PacketConstants.SEND_REMOVE_GROUND_ITEM + || opcode == PacketConstants.ANIMATE_OBJECT || opcode == 215) { + parseRegionPackets(incoming, opcode); + opcode = -1; + return true; + } + + if (opcode == PacketConstants.SWITCH_TAB) { + tabId = incoming.readNegUByte(); + tabAreaAltered = true; + opcode = -1; + return true; + } + if (opcode == PacketConstants.SEND_NONWALKABLE_CHATBOX_INTERFACE) { + int id = incoming.readLEUShort(); + resetAnimation(id); + if (overlayInterfaceId != -1) { + overlayInterfaceId = -1; + tabAreaAltered = true; + } + backDialogueId = id; + updateChatbox = true; + openInterfaceId = -1; + continuedDialogue = false; + opcode = -1; + return true; + } + + SignLink.reporterror( + "T1 - " + opcode + "," + packetSize + " - " + secondLastOpcode + "," + thirdLastOpcode); + // resetLogout(); + } catch (IOException _ex) { + dropClient(); + } catch (Exception exception) { + String s2 = "T2 - " + opcode + "," + secondLastOpcode + "," + thirdLastOpcode + " - " + packetSize + "," + + (regionBaseX + localPlayer.pathX[0]) + "," + (regionBaseY + localPlayer.pathY[0]) + " - "; + for (int j15 = 0; j15 < packetSize && j15 < 50; j15++) + s2 = s2 + incoming.payload[j15] + ","; + SignLink.reporterror(s2); + // resetLogout(); + } + opcode = -1; + return true; + } + + private void moveCameraWithPlayer() { + anInt1265++; + showOtherPlayers(true); + showNPCs(true); + showOtherPlayers(false); + showNPCs(false); + createProjectiles(); + createStationaryGraphics(); + if (!oriented) { + int i = anInt1184; + if (anInt984 / 256 > i) + i = anInt984 / 256; + if (quakeDirectionActive[4] && quakeAmplitudes[4] + 128 > i) + i = quakeAmplitudes[4] + 128; + int k = cameraHorizontal + cameraRotation & 0x7ff; + setCameraPos( + cameraZoom + i * ((SceneGraph.viewDistance == 9) && (frameMode == ScreenMode.RESIZABLE) ? 2 + : SceneGraph.viewDistance == 10 ? 5 : 3), + i, anInt1014, getCenterHeight(plane, localPlayer.y, localPlayer.x) - 50, k, anInt1015); + } + int j; + if (!oriented) + j = setCameraLocation(); + else + j = resetCameraHeight(); + int l = xCameraPos; + int i1 = zCameraPos; + int j1 = yCameraPos; + int k1 = yCameraCurve; + int l1 = xCameraCurve; + for (int i2 = 0; i2 < 5; i2++) + if (quakeDirectionActive[i2]) { + int j2 = (int) ((Math.random() * (double) (quakeMagnitudes[i2] * 2 + 1) - (double) quakeMagnitudes[i2]) + + Math.sin((double) quakeTimes[i2] * ((double) quake4PiOverPeriods[i2] / 100D)) + * (double) quakeAmplitudes[i2]); + if (i2 == 0) + xCameraPos += j2; + if (i2 == 1) + zCameraPos += j2; + if (i2 == 2) + yCameraPos += j2; + if (i2 == 3) + xCameraCurve = xCameraCurve + j2 & 0x7ff; + if (i2 == 4) { + yCameraCurve += j2; + if (yCameraCurve < 128) + yCameraCurve = 128; + if (yCameraCurve > 383) + yCameraCurve = 383; + } + } + int k2 = Rasterizer3D.lastTextureRetrievalCount; + Model.aBoolean1684 = true; + Model.anInt1687 = 0; + Model.anInt1685 = super.mouseX - (frameMode == ScreenMode.FIXED ? 4 : 0); + Model.anInt1686 = super.mouseY - (frameMode == ScreenMode.FIXED ? 4 : 0); + Rasterizer2D.clear(); + scene.render(xCameraPos, yCameraPos, xCameraCurve, zCameraPos, j, yCameraCurve); + scene.clearGameObjectCache(); + if (Configuration.enableFog) { + double fogDistance = Math.sqrt(Math.pow(zCameraPos, 2)); + int fogStartDistance = 1330; + int fogEndDistance = 2100; + fog.setFogDistance((float) fogDistance); + fog.renderFog(false, fogStartDistance, fogEndDistance, 3); + } + updateEntities(); + drawHeadIcon(); + writeBackgroundTexture(k2); + draw3dScreen(); + if (frameMode != ScreenMode.FIXED) { + drawChatArea(); + drawMinimap(); + drawTabArea(); + } + gameScreenImageProducer.drawGraphics(frameMode == ScreenMode.FIXED ? 4 : 0, super.graphics, + frameMode == ScreenMode.FIXED ? 4 : 0); + xCameraPos = l; + zCameraPos = i1; + yCameraPos = j1; + yCameraCurve = k1; + xCameraCurve = l1; + } + + private void processMinimapActions() { + if (openInterfaceId == 15244) { + return; + } + final boolean fixed = frameMode == ScreenMode.FIXED; + if (fixed ? super.mouseX >= 542 && super.mouseX <= 579 && super.mouseY >= 2 && super.mouseY <= 38 + : super.mouseX >= frameWidth - 180 && super.mouseX <= frameWidth - 139 && super.mouseY >= 0 + && super.mouseY <= 40) { + menuActionText[1] = "Face North"; + menuActionTypes[1] = 696; + menuActionRow = 2; + } + if (frameMode != ScreenMode.FIXED && changeTabArea) { + if (super.mouseX >= frameWidth - 26 && super.mouseX <= frameWidth - 1 && super.mouseY >= 2 + && super.mouseY <= 24) { + menuActionText[1] = "Logout"; + menuActionTypes[1] = 700; + menuActionRow = 2; + } + } + if (worldHover && Configuration.enableOrbs) { + menuActionText[1] = "World Map"; + menuActionTypes[1] = 850; + menuActionRow = 2; + } + if (specialHover && Configuration.enableOrbs) { + menuActionText[1] = "Use Special Attack"; + menuActionTypes[1] = 851; + menuActionRow = 2; + } + if (hpHover && Configuration.enableOrbs) { + menuActionText[1] = Configuration.hpAboveHeads ? "Turn HP Above Heads on" : "Turn HP Above heads off"; + menuActionTypes[1] = 1508; + menuActionRow = 2; + } + if (prayHover && Configuration.enableOrbs) { + menuActionText[2] = prayClicked ? "Turn quick-prayers off" : "Turn quick-prayers on"; + menuActionTypes[2] = 1500; + menuActionRow = 2; + menuActionText[1] = "Select quick-prayers"; + menuActionTypes[1] = 1506; + menuActionRow = 3; + } + if (runHover && Configuration.enableOrbs) { + menuActionText[1] = settings[173] == 1 ? "Toggle Run" : "Toggle Run"; + menuActionTypes[1] = 1050; + menuActionRow = 2; + + } + } + + public int getOrbTextColor(int statusInt) { + if (statusInt >= 75 && statusInt <= Integer.MAX_VALUE) + return 0x00FF00; + else if (statusInt >= 50 && statusInt <= 74) + return 0xFFFF00; + else if (statusInt >= 25 && statusInt <= 49) + return 0xFF981F; + else + return 0xFF0000; + } + + public int getOrbFill(int statusInt) { + if (statusInt <= Integer.MAX_VALUE && statusInt >= 97) + return 0; + else if (statusInt <= 96 && statusInt >= 93) + return 1; + else if (statusInt <= 92 && statusInt >= 89) + return 2; + else if (statusInt <= 88 && statusInt >= 85) + return 3; + else if (statusInt <= 84 && statusInt >= 81) + return 4; + else if (statusInt <= 80 && statusInt >= 77) + return 5; + else if (statusInt <= 76 && statusInt >= 73) + return 6; + else if (statusInt <= 72 && statusInt >= 69) + return 7; + else if (statusInt <= 68 && statusInt >= 65) + return 8; + else if (statusInt <= 64 && statusInt >= 61) + return 9; + else if (statusInt <= 60 && statusInt >= 57) + return 10; + else if (statusInt <= 56 && statusInt >= 53) + return 11; + else if (statusInt <= 52 && statusInt >= 49) + return 12; + else if (statusInt <= 48 && statusInt >= 45) + return 13; + else if (statusInt <= 44 && statusInt >= 41) + return 14; + else if (statusInt <= 40 && statusInt >= 37) + return 15; + else if (statusInt <= 36 && statusInt >= 33) + return 16; + else if (statusInt <= 32 && statusInt >= 29) + return 17; + else if (statusInt <= 28 && statusInt >= 25) + return 18; + else if (statusInt <= 24 && statusInt >= 21) + return 19; + else if (statusInt <= 20 && statusInt >= 17) + return 20; + else if (statusInt <= 16 && statusInt >= 13) + return 21; + else if (statusInt <= 12 && statusInt >= 9) + return 22; + else if (statusInt <= 8 && statusInt >= 7) + return 23; + else if (statusInt <= 6 && statusInt >= 5) + return 24; + else if (statusInt <= 4 && statusInt >= 3) + return 25; + else if (statusInt <= 2 && statusInt >= 1) + return 26; + else if (statusInt <= 0) + return 27; + return 0; + } + + public void clearTopInterfaces() { + // close interface + outgoing.writeOpcode(130); + if (overlayInterfaceId != -1) { + overlayInterfaceId = -1; + continuedDialogue = false; + tabAreaAltered = true; + } + if (backDialogueId != -1) { + backDialogueId = -1; + updateChatbox = true; + continuedDialogue = false; + } + openInterfaceId = -1; + fullscreenInterfaceID = -1; + } + + public void resetAllImageProducers() { + if (super.fullGameScreen != null) { + return; + } + chatboxImageProducer = null; + minimapImageProducer = null; + tabImageProducer = null; + gameScreenImageProducer = null; + chatSettingImageProducer = null; + topLeft1BackgroundTile = null; + bottomLeft1BackgroundTile = null; + loginBoxImageProducer = null; + flameLeftBackground = null; + flameRightBackground = null; + bottomLeft0BackgroundTile = null; + bottomRightImageProducer = null; + loginMusicImageProducer = null; + middleLeft1BackgroundTile = null; + aRSImageProducer_1115 = null; + super.fullGameScreen = new ProducingGraphicsBuffer(765, 503); + welcomeScreenRaised = true; + } + + public void mouseWheelDragged(int i, int j) { + if (!mouseWheelDown) { + return; + } + this.anInt1186 += i * 3; + this.anInt1187 += (j << 1); + } + + public enum ScreenMode { + FIXED, RESIZABLE, FULLSCREEN + } +} diff --git a/src/main/java/org/rebotted/Configuration.java b/src/main/java/org/rebotted/Configuration.java new file mode 100644 index 0000000..711531e --- /dev/null +++ b/src/main/java/org/rebotted/Configuration.java @@ -0,0 +1,160 @@ +package org.rebotted; + +import java.math.BigInteger; + +/** + * The main configuration for the Client + * + * @author Freyr + */ +public final class Configuration { + + private Configuration() { + + } + + public static final BigInteger RSA_MODULUS = new BigInteger( + "91553247461173033466542043374346300088148707506479543786501537350363031301992107112953015516557748875487935404852620239974482067336878286174236183516364787082711186740254168914127361643305190640280157664988536979163450791820893999053469529344247707567448479470137716627440246788713008490213212272520901741443"); + + public static final BigInteger RSA_EXPONENT = new BigInteger("65537"); + + /** + * Sends client-related debug messages to the client output stream + */ + public static boolean client_debug = true; + + /** + * The address of the server that the client will be connecting to + */ + public static String server_address = "2006rebotted.hopto.org"; + + public static final String CACHE_DIRECTORY = "./Cache/"; + + /** + * The port of the server that the client will be connecting to + */ + public static int server_port = 43594; + + public static boolean useJaggrab = false; + + /** + * Toggles a security feature called RSA to prevent packet sniffers + */ + public static final boolean ENABLE_RSA = true; + + /** + * The url that the users will get redirected to after clicking "New User" + */ + public static final String REGISTER_ACCOUNT = "www.google.com"; + + /** + * A string which indicates the Client's name. + */ + public static final String CLIENT_NAME = "2006Rebotted"; + + /** + * Dumps map region images when new regions are loaded. + */ + public static boolean dumpMapRegions = false; + + /** + * Displays debug messages on loginscreen and in-game + */ + public static boolean clientData = true; + + /** + * Enables the use of music played through the client + */ + public static boolean enableMusic = true; + + /** + * Toggles the ability for a player to see roofs in-game + */ + public static boolean enableRoofs = true; + + /** + * Used for change worlds button on login screen + */ + public static boolean worldSwitch = false; + + /** + * Enables extra frames in-between animations to give the animation a smooth + * look + */ + public static boolean enableTweening = true; + + /** + * Used to repack indexes Index 1 = Models Index 2 = Animations Index 3 = + * Sounds/Music Index 4 = Maps + */ + public static boolean repackIndexOne = false, repackIndexTwo = false, repackIndexThree = false, + repackIndexFour = false; + + /** + * Dump Indexes Index 1 = Models Index 2 = Animations Index 3 = Sounds/Music + * Index 4 = Maps + */ + public static boolean dumpIndexOne = false, dumpIndexTwo = false, dumpIndexThree = false, dumpIndexFour = false; + + /** + * Shows the ids of items, objects, and npcs on right click + */ + public static boolean enableIds = false; + + /** + * Used to merge all the OS Buddy XP Drops so the counter doesn't get too + * big if you are training a lot of different skills + */ + public static boolean xp_merge = true; + + /** + * Enables fog effects + */ + public static boolean enableFog = false; + + /** + * newDamage enables or disables fake constitution. + */ + public static boolean newDamage = true; + + /** + * npcBits can be changed to what your server's bits are set to. + */ + public static final int npcBits = 12; + + /** + * Enables the use of run energy + */ + public static boolean runEnergy = false; + + /** + * Displays health above entities heads + */ + public static boolean hpAboveHeads = false; + + /** + * Displays names above entities + */ + public static boolean namesAboveHeads = false; + + /** + * Displays OS Buddy orbs on HUD + */ + public static boolean enableOrbs = true; + + /** + * Enables/Disables Revision 554 hitmarks + */ + public static boolean hitmarks554 = false; + + /** + * Enables/Disables Revision 554 health bar + */ + public static boolean hpBar554 = false; + + /** + * Enables the HUD to display 10 X the amount of hitpoints + */ + public static boolean tenXHp = false; + +} diff --git a/src/main/java/org/rebotted/GameApplet.java b/src/main/java/org/rebotted/GameApplet.java new file mode 100644 index 0000000..d2b6f19 --- /dev/null +++ b/src/main/java/org/rebotted/GameApplet.java @@ -0,0 +1,641 @@ +package org.rebotted; + +import org.rebotted.cache.graphics.Widget; +import org.rebotted.draw.ProducingGraphicsBuffer; +import org.rebotted.ui.BotFrame; + +import javax.swing.*; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; + +public class GameApplet extends Applet implements Runnable, MouseListener, + MouseMotionListener, MouseWheelListener, KeyListener, FocusListener, + WindowListener { + + private static final long serialVersionUID = 1L; + public static int anInt34; + private static Client instance; + public final int LEFT = 0; + public final int RIGHT = 1; + public final int DRAG = 2; + public final int RELEASED = 3; + public final int MOVE = 4; + final int[] keyArray = new int[128]; + private final long[] aLongArray7 = new long[10]; + private final int[] charQueue = new int[128]; + public int mouseX; + public int mouseY; + public long aLong29; + public int clickMode3; + public int saveClickX; + public int saveClickY; + public boolean isLoading; + public boolean isApplet; + public boolean resized; + public int clickType; + public int releasedX; + public int releasedY; + public boolean mouseWheelDown; + public int mouseWheelX; + public int mouseWheelY; + protected int rotationGliding; + int minDelay; + int fps; + boolean shouldDebug; + int myWidth; + int myHeight; + Graphics graphics; + ProducingGraphicsBuffer fullGameScreen; + boolean awtFocus; + int idleTime; + int clickMode2; + int clickMode1; + private int anInt4; + private int delayTime; + private boolean shouldClearScreen; + private int clickX; + private int clickY; + private int readIndex; + private int writeIndex; + + GameApplet() { + delayTime = 20; + minDelay = 1; + shouldDebug = false; + shouldClearScreen = true; + awtFocus = true; + } + + public void refreshFrameSize(boolean undecorated, int width, int height, + boolean resizable, boolean full) { + SwingUtilities.invokeLater(() -> { + Client.botFrame.setResizable(true); + }); + } + + public boolean appletClient() { + return isApplet == true; + } + + public final void initClientFrame(int w, int h) { + isApplet = true; + myWidth = w; + myHeight = h; + graphics = getGameComponent().getGraphics(); + fullGameScreen = new ProducingGraphicsBuffer(myWidth, myHeight); + startRunnable(this, 1); + } + + public boolean badZoomPosition() { + return (mouseX > 0 && mouseY > 340 && mouseX < 510 && mouseY < 500) || + (mouseY > 210 && mouseY < 473 && mouseX > 514 && mouseX < 762); + } + + public void run() { + getGameComponent().addMouseListener(this); + getGameComponent().addMouseMotionListener(this); + getGameComponent().addKeyListener(this); + getGameComponent().addFocusListener(this); + getGameComponent().addMouseWheelListener(this); + if (Client.botFrame != null) { + Client.botFrame.addWindowListener(this); + } + drawLoadingText(0, "Loading..."); + startUp(); + int i = 0; + int j = 256; + int k = 1; + int l = 0; + int i1 = 0; + for (int j1 = 0; j1 < 10; j1++) { + aLongArray7[j1] = System.currentTimeMillis(); + } + do { + if (anInt4 < 0) { + break; + } + if (anInt4 > 0) { + anInt4--; + if (anInt4 == 0) { + exit(); + return; + } + } + int k1 = j; + int i2 = k; + j = 300; + k = 1; + long l2 = System.currentTimeMillis(); + if (aLongArray7[i] == 0L) { + j = k1; + k = i2; + } else if (l2 > aLongArray7[i]) { + j = (int) ((long) (2560 * delayTime) / (l2 - aLongArray7[i])); + } + if (j < 25) { + j = 25; + } + if (j > 256) { + j = 256; + k = (int) ((long) delayTime - (l2 - aLongArray7[i]) / 10L); + } + if (k > delayTime) { + k = delayTime; + } + aLongArray7[i] = l2; + i = (i + 1) % 10; + if (k > 1) { + for (int j2 = 0; j2 < 10; j2++) { + if (aLongArray7[j2] != 0L) { + aLongArray7[j2] += k; + } + } + + } + if (k < minDelay) { + k = minDelay; + } + try { + Thread.sleep(k); + } catch (InterruptedException interruptedexception) { + i1++; + } + for (; l < 256; l += j) { + clickMode3 = clickMode1; + saveClickX = clickX; + saveClickY = clickY; + clickMode1 = 0; + processGameLoop(); + readIndex = writeIndex; + } + + l &= 0xff; + if (delayTime > 0) { + fps = (1000 * j) / (delayTime * 256); + } + processDrawing(); + if (shouldDebug) { + System.out.println((new StringBuilder()).append("ntime:") + .append(l2).toString()); + for (int k2 = 0; k2 < 10; k2++) { + int i3 = ((i - k2 - 1) + 20) % 10; + System.out.println((new StringBuilder()).append("otim") + .append(i3).append(":").append(aLongArray7[i3]) + .toString()); + } + + System.out.println((new StringBuilder()).append("fps:") + .append(fps).append(" ratio:").append(j) + .append(" count:").append(l).toString()); + System.out.println((new StringBuilder()).append("del:") + .append(k).append(" deltime:").append(delayTime) + .append(" mindel:").append(minDelay).toString()); + System.out.println((new StringBuilder()).append("intex:") + .append(i1).append(" opos:").append(i).toString()); + shouldDebug = false; + i1 = 0; + } + } while (true); + if (anInt4 == -1) { + exit(); + } + } + + private void exit() { + anInt4 = -2; + cleanUpForQuit(); + if (Client.botFrame != null) { + try { + Thread.sleep(1000L); + } catch (Exception exception) { + } + try { + System.exit(0); + } catch (Throwable throwable) { + } + } + } + + final void method4(int i) { + delayTime = 1000 / i; + } + + public final void start() { + if (anInt4 >= 0) { + anInt4 = 0; + } + } + + public final void stop() { + if (anInt4 >= 0) { + anInt4 = 4000 / delayTime; + } + } + + public final void destroy() { + anInt4 = -1; + try { + Thread.sleep(5000L); + } catch (Exception exception) { + } + if (anInt4 == -1) { + exit(); + } + } + + public final void update(Graphics g) { + if (graphics == null) { + graphics = g; + } + shouldClearScreen = true; + raiseWelcomeScreen(); + } + + public final void paint(Graphics g) { + if (graphics == null) { + graphics = g; + } + shouldClearScreen = true; + raiseWelcomeScreen(); + } + + public void mouseWheelMoved(MouseWheelEvent event) { + int rotation = event.getWheelRotation(); + handleInterfaceScrolling(event); + if (mouseX > 0 && mouseX < 512 && mouseY > Client.frameHeight - 165 + && mouseY < Client.frameHeight - 25) { + int scrollPos = Client.anInt1089; + scrollPos -= rotation * 30; + if (scrollPos < 0) + scrollPos = 0; + if (scrollPos > Client.anInt1211 - 110) + scrollPos = Client.anInt1211 - 110; + if (Client.anInt1089 != scrollPos) { + Client.anInt1089 = scrollPos; + Client.updateChatbox = true; + } + } + } + + public void handleInterfaceScrolling(MouseWheelEvent event) { + int rotation = event.getWheelRotation(); + int positionX = 0; + int positionY = 0; + int width = 0; + int height = 0; + int offsetX = 0; + int offsetY = 0; + int childID = 0; + int tabInterfaceID = Client.tabInterfaceIDs[Client.tabId]; + if (tabInterfaceID != -1) { + Widget tab = Widget.interfaceCache[tabInterfaceID]; + offsetX = Client.frameMode == Client.ScreenMode.FIXED ? Client.frameWidth - 218 + : (Client.frameMode == Client.ScreenMode.FIXED ? 28 + : Client.frameWidth - 197); + offsetY = Client.frameMode == Client.ScreenMode.FIXED ? Client.frameHeight - 298 + : (Client.frameMode == Client.ScreenMode.FIXED ? 37 + : Client.frameHeight + - (Client.frameWidth >= 1000 ? 37 : 74) - 267); + for (int index = 0; index < tab.children.length; index++) { + if (Widget.interfaceCache[tab.children[index]].scrollMax > 0) { + childID = index; + positionX = tab.childX[index]; + positionY = tab.childY[index]; + width = Widget.interfaceCache[tab.children[index]].width; + height = Widget.interfaceCache[tab.children[index]].height; + break; + } + } + if (mouseX > offsetX + positionX && mouseY > offsetY + positionY + && mouseX < offsetX + positionX + width + && mouseY < offsetY + positionY + height) { + Widget.interfaceCache[tab.children[childID]].scrollPosition += rotation * 30; + } + } + if (Client.openInterfaceId != -1) { + Widget rsi = Widget.interfaceCache[Client.openInterfaceId]; + offsetX = Client.frameMode == Client.ScreenMode.FIXED ? 4 + : (Client.frameWidth / 2) - 356; + offsetY = Client.frameMode == Client.ScreenMode.FIXED ? 4 + : (Client.frameHeight / 2) - 230; + for (int index = 0; index < rsi.children.length; index++) { + if (Widget.interfaceCache[rsi.children[index]].scrollMax > 0) { + childID = index; + positionX = rsi.childX[index]; + positionY = rsi.childY[index]; + width = Widget.interfaceCache[rsi.children[index]].width; + height = Widget.interfaceCache[rsi.children[index]].height; + break; + } + } + if (mouseX > offsetX + positionX && mouseY > offsetY + positionY + && mouseX < offsetX + positionX + width + && mouseY < offsetY + positionY + height) { + Widget.interfaceCache[rsi.children[childID]].scrollPosition += rotation * 30; + } + } + } + + public final void mousePressed(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + int type = e.getButton(); + if (Client.botFrame != null) { + Insets insets = Client.botFrame.getInsets(); + x -= insets.left;// 4 + y -= insets.top;// 22 + } + idleTime = 0; + clickX = x; + clickY = y; + aLong29 = System.currentTimeMillis(); + if (type == 2) { + mouseWheelDown = true; + mouseWheelX = x; + mouseWheelY = y; + return; + } + if (e.isMetaDown()) { + clickType = RIGHT; + clickMode1 = 2; + clickMode2 = 2; + } else { + clickType = LEFT; + clickMode1 = 1; + clickMode2 = 1; + } + } + + public final void mouseReleased(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + if (Client.botFrame != null) { + Insets insets = Client.botFrame.getInsets(); + x -= insets.left;// 4 + y -= insets.top;// 22 + } + releasedX = x; + releasedY = y; + idleTime = 0; + clickMode2 = 0; + clickType = RELEASED; + mouseWheelDown = false; + } + + public final void mouseClicked(MouseEvent mouseevent) { + } + + public final void mouseEntered(MouseEvent mouseevent) { + } + + public final void mouseExited(MouseEvent mouseevent) { + idleTime = 0; + mouseX = -1; + mouseY = -1; + } + + public final void mouseDragged(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + if (Client.botFrame != null) { + Insets insets = Client.botFrame.getInsets(); + x -= insets.left;// 4 + y -= insets.top;// 22 + } + if (mouseWheelDown) { + y = mouseWheelX - e.getX(); + int k = mouseWheelY - e.getY(); + mouseWheelDragged(y, -k); + mouseWheelX = e.getX(); + mouseWheelY = e.getY(); + return; + } + idleTime = 0; + mouseX = x; + mouseY = y; + clickType = DRAG; + } + + void mouseWheelDragged(int param1, int param2) { + + } + + public final void mouseMoved(MouseEvent mouseevent) { + int x = mouseevent.getX(); + int y = mouseevent.getY(); + if (Client.botFrame != null) { + Insets insets = Client.botFrame.getInsets(); + x -= insets.left;// 4 + y -= insets.top;// 22 + } + idleTime = 0; + mouseX = x; + mouseY = y; + clickType = MOVE; + } + + public final void keyPressed(KeyEvent keyevent) { + idleTime = 0; + int i = keyevent.getKeyCode(); + int j = keyevent.getKeyChar(); + if (i == KeyEvent.VK_F1) { + Client.setTab(3); + } else if (i == KeyEvent.VK_ESCAPE) { + Client.setTab(10); + } else if (i == KeyEvent.VK_F2) { + Client.setTab(4); + } else if (i == KeyEvent.VK_F3) { + Client.setTab(5); + } else if (i == KeyEvent.VK_F4) { + Client.setTab(6); + } else if (i == KeyEvent.VK_F5) { + Client.setTab(0); + } + if (j < 30) + j = 0; + if (i == 37) + j = 1; + if (i == 39) + j = 2; + if (i == 38) + j = 3; + if (i == 40) + j = 4; + if (i == 17) + j = 5; + if (i == 8) + j = 8; + if (i == 127) + j = 8; + if (i == 9) + j = 9; + if (i == 10) + j = 10; + if (i >= 112 && i <= 123) + j = (1008 + i) - 112; + if (i == 36) + j = 1000; + if (i == 35) + j = 1001; + if (i == 33) + j = 1002; + if (i == 34) + j = 1003; + if (j > 0 && j < 128) + keyArray[j] = 1; + if (j > 4) { + charQueue[writeIndex] = j; + writeIndex = writeIndex + 1 & 0x7f; + } + } + + public final void keyReleased(KeyEvent keyevent) { + idleTime = 0; + int i = keyevent.getKeyCode(); + char c = keyevent.getKeyChar(); + if (c < '\036') + c = '\0'; + if (i == 37) + c = '\001'; + if (i == 39) + c = '\002'; + if (i == 38) + c = '\003'; + if (i == 40) + c = '\004'; + if (i == 17) + c = '\005'; + if (i == 8) + c = '\b'; + if (i == 127) + c = '\b'; + if (i == 9) + c = '\t'; + if (i == 10) + c = '\n'; + if (c > 0 && c < '\200') + keyArray[c] = 0; + } + + public final void keyTyped(KeyEvent keyevent) { + } + + final int readChar(int dummy) { + while (dummy >= 0) { + for (int j = 1; j > 0; j++) + ; + } + int k = -1; + if (writeIndex != readIndex) { + k = charQueue[readIndex]; + readIndex = readIndex + 1 & 0x7f; + } + return k; + } + + public final void focusGained(FocusEvent focusevent) { + awtFocus = true; + shouldClearScreen = true; + raiseWelcomeScreen(); + } + + public final void focusLost(FocusEvent focusevent) { + awtFocus = false; + for (int i = 0; i < 128; i++) { + keyArray[i] = 0; + } + + } + + public final void windowActivated(WindowEvent windowevent) { + } + + public final void windowClosed(WindowEvent windowevent) { + } + + public final void windowClosing(WindowEvent windowevent) { + destroy(); + + } + + public final void windowDeactivated(WindowEvent windowevent) { + } + + public final void windowDeiconified(WindowEvent windowevent) { + } + + public final void windowIconified(WindowEvent windowevent) { + } + + public final void windowOpened(WindowEvent windowevent) { + } + + void startUp() { + } + + void processGameLoop() { + } + + void cleanUpForQuit() { + } + + void processDrawing() { + } + + void raiseWelcomeScreen() { + } + + Component getGameComponent() { + if (!isApplet) { + return Client.botFrame; + } else { + return this; + } + } + + public void startRunnable(Runnable runnable, int i) { + Thread thread = new Thread(runnable); + thread.start(); + thread.setPriority(i); + } + + void drawLoadingText(int percentage, String loadingText) { + while (graphics == null) { + graphics = (isApplet ? this : Client.botFrame).getGraphics(); + try { + getGameComponent().repaint(); + } catch (Exception _ex) { + } + try { + Thread.sleep(1000L); + } catch (Exception _ex) { + } + } + Font font = new Font("Helvetica", 1, 13); + FontMetrics fontmetrics = getGameComponent().getFontMetrics(font); + Font font1 = new Font("Helvetica", 0, 13); + FontMetrics fontmetrics1 = getGameComponent().getFontMetrics(font1); + if (shouldClearScreen) { + graphics.setColor(Color.black); + graphics.fillRect(0, 0, Client.frameWidth, Client.frameHeight); + shouldClearScreen = false; + } + Color color = new Color(140, 17, 17); + int y = Client.frameHeight / 2 - 18; + graphics.setColor(color); + graphics.drawRect(Client.frameWidth / 2 - 152, y, 304, 34); + graphics.fillRect(Client.frameWidth / 2 - 150, y + 2, percentage * 3, 30); + graphics.setColor(Color.black); + graphics.fillRect((Client.frameWidth / 2 - 150) + percentage * 3, y + 2, + 300 - percentage * 3, 30); + graphics.setFont(font); + graphics.setColor(Color.white); + graphics.drawString(loadingText, + (Client.frameWidth - fontmetrics.stringWidth(loadingText)) / 2, + y + 22); + graphics.drawString("", + (Client.frameWidth - fontmetrics1.stringWidth("")) / 2, y - 8); + } + +} diff --git a/src/main/java/org/rebotted/cache/FileArchive.java b/src/main/java/org/rebotted/cache/FileArchive.java new file mode 100644 index 0000000..b607013 --- /dev/null +++ b/src/main/java/org/rebotted/cache/FileArchive.java @@ -0,0 +1,101 @@ +package org.rebotted.cache; + +import org.rebotted.cache.bzip.BZip2Decompressor; +import org.rebotted.io.Buffer; + +public final class FileArchive { + + /** + * The buffer containing the decompressed data in this Archive. + */ + private final byte[] buffer; + + /** + * The amount of entries in this Archive. + */ + private final int entries; + + /** + * The identifiers (i.e. hashed names) of each of the entries in this Archive. + */ + private final int[] identifiers; + + /** + * The raw (i.e. decompressed) sizes of each of the entries in this Archive. + */ + private final int[] extractedSizes; + + /** + * The compressed sizes of each of the entries in this Archive. + */ + private final int[] sizes; + private final int[] indices; + + /** + * Whether or not this Archive was compressed as a whole: if false, decompression will be performed on each of the + * individual entries. + */ + private final boolean extracted; + + public FileArchive(byte data[]) { + Buffer buffer = new Buffer(data); + + int decompressedLength = buffer.readTriByte(); + int compressedLength = buffer.readTriByte(); + + if (compressedLength != decompressedLength) { + + byte output[] = new byte[decompressedLength]; + + BZip2Decompressor.decompress(output, decompressedLength, data, compressedLength, 6); + + this.buffer = output; + + buffer = new Buffer(this.buffer); + extracted = true; + } else { + this.buffer = data; + extracted = false; + } + entries = buffer.readUShort(); + identifiers = new int[entries]; + extractedSizes = new int[entries]; + sizes = new int[entries]; + indices = new int[entries]; + int offset = buffer.currentPosition + entries * 10; + for (int file = 0; file < entries; file++) { + identifiers[file] = buffer.readInt(); + extractedSizes[file] = buffer.readTriByte(); + sizes[file] = buffer.readTriByte(); + indices[file] = offset; + offset += sizes[file]; + } + } + + public byte[] readFile(String name) { + byte output[] = null; + int hash = 0; + name = name.toUpperCase(); + for (int index = 0; index < name.length(); index++) { + hash = (hash * 61 + name.charAt(index)) - 32; + } + + for (int file = 0; file < entries; file++) { + if (identifiers[file] == hash) { + if (output == null) { + output = new byte[extractedSizes[file]]; + } + if (!extracted) { + BZip2Decompressor.decompress(output, extractedSizes[file], this.buffer, + sizes[file], indices[file]); + } else { + System.arraycopy(this.buffer, indices[file], output, + 0, extractedSizes[file]); + } + return output; + } + } + return null; + } + +} diff --git a/src/main/java/org/rebotted/cache/FileStore.java b/src/main/java/org/rebotted/cache/FileStore.java new file mode 100644 index 0000000..d8e4592 --- /dev/null +++ b/src/main/java/org/rebotted/cache/FileStore.java @@ -0,0 +1,239 @@ +package org.rebotted.cache; + +import java.io.*; + +public final class FileStore { + + public static enum Store { + + ARCHIVE(0), + + MODEL(1), + + ANIMATION(2), + + MUSIC(3), + + MAP(4); + + private int index; + + private Store(int index) { + this.index = index; + } + + public int getIndex() { + return this.index; + } + + } + + private static final byte[] buffer = new byte[520]; + private final RandomAccessFile dataFile; + private final RandomAccessFile indexFile; + private final int storeIndex; + + public FileStore(RandomAccessFile data, RandomAccessFile index, int storeIndex) { + this.storeIndex = storeIndex; + dataFile = data; + indexFile = index; + } + + public synchronized byte[] decompress(int id) { + try { + seek(indexFile, id * 6); + for (int in = 0, read = 0; read < 6; read += in) { + in = indexFile.read(buffer, read, 6 - read); + + if (in == -1) { + return null; + } + + } + + int size = ((buffer[0] & 0xff) << 16) + ((buffer[1] & 0xff) << 8) + (buffer[2] & 0xff); + int sector = ((buffer[3] & 0xff) << 16) + ((buffer[4] & 0xff) << 8) + (buffer[5] & 0xff); + + if (sector <= 0 || (long) sector > dataFile.length() / 520L) { + return null; + } + + byte buf[] = new byte[size]; + + int totalRead = 0; + + for (int part = 0; totalRead < size; part++) { + + if (sector == 0) { + return null; + } + + seek(dataFile, sector * 520); + + int unread = size - totalRead; + + if (unread > 512) { + unread = 512; + } + + for (int in = 0, read = 0; read < unread + 8; read += in) { + in = dataFile.read(buffer, read, (unread + 8) - read); + + if (in == -1) { + return null; + } + } + int currentIndex = ((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff); + int currentPart = ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff); + int nextSector = ((buffer[4] & 0xff) << 16) + ((buffer[5] & 0xff) << 8) + (buffer[6] & 0xff); + int currentFile = buffer[7] & 0xff; + + if (currentIndex != id || currentPart != part || currentFile != storeIndex) { + return null; + } + + if (nextSector < 0 || (long) nextSector > dataFile.length() / 520L) { + return null; + } + + for (int i = 0; i < unread; i++) { + buf[totalRead++] = buffer[i + 8]; + } + + sector = nextSector; + } + + return buf; + } catch (IOException _ex) { + return null; + } + } + + public synchronized boolean writeFile(int length, byte data[], int index) { + return writeFile(data, index, length, true) ? true : writeFile(data, index, length, false); + } + + private synchronized boolean writeFile(byte bytes[], int position, int length, boolean exists) { + try { + int sector; + if (exists) { + + seek(indexFile, position * 6); + + for (int in = 0, read = 0; read < 6; read += in) { + in = indexFile.read(buffer, read, 6 - read); + + if (in == -1) { + return false; + } + + } + sector = ((buffer[3] & 0xff) << 16) + ((buffer[4] & 0xff) << 8) + (buffer[5] & 0xff); + + if (sector <= 0 || (long) sector > dataFile.length() / 520L) { + return false; + } + + } else { + sector = (int) ((dataFile.length() + 519L) / 520L); + if (sector == 0) { + sector = 1; + } + } + buffer[0] = (byte) (length >> 16); + buffer[1] = (byte) (length >> 8); + buffer[2] = (byte) length; + buffer[3] = (byte) (sector >> 16); + buffer[4] = (byte) (sector >> 8); + buffer[5] = (byte) sector; + seek(indexFile, position * 6); + indexFile.write(buffer, 0, 6); + + for (int part = 0, written = 0; written < length; part++) { + + int nextSector = 0; + + if (exists) { + seek(dataFile, sector * 520); + + int read = 0; + + for (int in = 0; read < 8; read += in) { + + in = dataFile.read(buffer, read, 8 - read); + + if (in == -1) { + break; + } + } + + if (read == 8) { + int currentIndex = ((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff); + int currentPart = ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff); + nextSector = ((buffer[4] & 0xff) << 16) + ((buffer[5] & 0xff) << 8) + (buffer[6] & 0xff); + int currentFile = buffer[7] & 0xff; + + if (currentIndex != position || currentPart != part || currentFile != storeIndex) { + return false; + } + + if (nextSector < 0 || (long) nextSector > dataFile.length() / 520L) { + return false; + } + } + } + if (nextSector == 0) { + exists = false; + nextSector = (int) ((dataFile.length() + 519L) / 520L); + + if (nextSector == 0) { + nextSector++; + } + + if (nextSector == sector) { + nextSector++; + } + + } + + if (length - written <= 512) { + nextSector = 0; + } + + buffer[0] = (byte) (position >> 8); + buffer[1] = (byte) position; + buffer[2] = (byte) (part >> 8); + buffer[3] = (byte) part; + buffer[4] = (byte) (nextSector >> 16); + buffer[5] = (byte) (nextSector >> 8); + buffer[6] = (byte) nextSector; + buffer[7] = (byte) storeIndex; + seek(dataFile, sector * 520); + dataFile.write(buffer, 0, 8); + + int unwritten = length - written; + + if (unwritten > 512) { + unwritten = 512; + } + + dataFile.write(bytes, written, unwritten); + written += unwritten; + sector = nextSector; + } + + return true; + } catch (IOException ex) { + return false; + } + } + + private synchronized void seek(RandomAccessFile file, int position) throws IOException { + try { + file.seek(position); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/org/rebotted/cache/anim/Animation.java b/src/main/java/org/rebotted/cache/anim/Animation.java new file mode 100644 index 0000000..667f2f0 --- /dev/null +++ b/src/main/java/org/rebotted/cache/anim/Animation.java @@ -0,0 +1,150 @@ +package org.rebotted.cache.anim; + +import org.rebotted.cache.FileArchive; +import org.rebotted.io.Buffer; + +public final class Animation { + + public static void init(FileArchive streamLoader) { + Buffer buffer = new Buffer(streamLoader.readFile("seq.dat")); + + int length = buffer.readUShort(); + + if (animations == null) { + animations = new Animation[length]; + } + + for (int i = 0; i < length; i++) { + if (animations[i] == null) { + animations[i] = new Animation(); + } + + animations[i].decode(buffer); + } + + System.out.println("Loaded: " + length + " Animations"); + } + + public int duration(int index) { + int duration = durations[index]; + if (duration == 0) { + Frame frame = Frame.method531(primaryFrames[index]); + if (frame != null) { + duration = durations[index] = frame.duration; + } + } + + if (duration == 0) { + duration = 1; + } + return duration; + } + + private void decode(Buffer stream) { + int opcode; + while ((opcode = stream.readUnsignedByte()) != 0) { + + if (opcode == 1) { + frameCount = stream.readUShort(); + primaryFrames = new int[frameCount]; + secondaryFrames = new int[frameCount]; + durations = new int[frameCount]; + for (int i = 0; i < frameCount; i++) { + primaryFrames[i] = stream.readInt(); + secondaryFrames[i] = -1; + } + + for (int i = 0; i < frameCount; i++) { + durations[i] = stream.readUnsignedByte(); + } + + } else if (opcode == 2) { + loopOffset = stream.readUShort(); + } else if (opcode == 3) { + int length = stream.readUnsignedByte(); + interleaveOrder = new int[length + 1]; + for (int i = 0; i < length; i++) { + interleaveOrder[i] = stream.readUnsignedByte(); + } + interleaveOrder[length] = 9999999; + } else if (opcode == 4) { + stretches = true; + } else if (opcode == 5) { + forcedPriority = stream.readUnsignedByte(); + } else if (opcode == 6) { + rightHand = stream.readUShort(); + } else if (opcode == 7) { + leftHand = stream.readUShort(); + } else if (opcode == 8) { + maximumLoops = stream.readUnsignedByte(); + } else if (opcode == 9) { + animatingPrecedence = stream.readUnsignedByte(); + } else if (opcode == 10) { + priority = stream.readUnsignedByte(); + } else if (opcode == 11) { + replayMode = stream.readUnsignedByte(); + } else if (opcode == 12) { + stream.readInt(); + } else { + System.out.println("Error unrecognised seq config code: " + opcode); + } + + } + if (frameCount == 0) { + frameCount = 1; + primaryFrames = new int[1]; + primaryFrames[0] = -1; + secondaryFrames = new int[1]; + secondaryFrames[0] = -1; + durations = new int[1]; + durations[0] = -1; + } + if (animatingPrecedence == -1) + if (interleaveOrder != null) { + animatingPrecedence = 2; + } else { + animatingPrecedence = 0; + } + if (priority == -1) { + if (interleaveOrder != null) { + priority = 2; + return; + } + priority = 0; + } + } + + private Animation() { + + } + + public static Animation animations[]; + public int frameCount; + public int primaryFrames[]; + public int secondaryFrames[]; + public int[] durations; + public int loopOffset = -1; + public int interleaveOrder[]; + public boolean stretches; + public int forcedPriority = 5; + + /** + * Removes shield + */ + public int rightHand = -1; + + /** + * Removes weapon + */ + public int leftHand = -1; + public int maximumLoops = 99; + + /** + * Stops character from moving. + */ + public int animatingPrecedence = -1; + public int priority = -1; + public int replayMode = 1; + public static int anInt367; + +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/cache/anim/Frame.java b/src/main/java/org/rebotted/cache/anim/Frame.java new file mode 100644 index 0000000..5047cf0 --- /dev/null +++ b/src/main/java/org/rebotted/cache/anim/Frame.java @@ -0,0 +1,123 @@ +package org.rebotted.cache.anim; +import org.rebotted.Client; +import org.rebotted.io.Buffer; + +public final class Frame { + + public static Frame[][] animationlist; + + public static void load(int file, byte[] array) { + try { + final Buffer ay = new Buffer(array); + final FrameBase b2 = new FrameBase(ay); + final int n = ay.readUShort();; + animationlist[file] = new Frame[n * 3]; + final int[] array2 = new int[500]; + final int[] array3 = new int[500]; + final int[] array4 = new int[500]; + final int[] array5 = new int[500]; + for (int j = 0; j < n; ++j) { + final int k = ay.readUShort();; + final Frame[] array6 = animationlist[file]; + final int n2 = k; + final Frame q = new Frame(); + array6[n2] = q; + final Frame q2 = q; + q.base = b2; + final int f = ay.readUnsignedByte(); + int c2 = 0; + int n3 = -1; + for (int l = 0; l < f; ++l) { + final int f2; + if ((f2 = ay.readUnsignedByte()) > 0) { + if (b2.transformationType[l] != 0) { + for (int n4 = l - 1; n4 > n3; --n4) { + if (b2.transformationType[n4] == 0) { + array2[c2] = n4; + array3[c2] = 0; + array5[c2] = (array4[c2] = 0); + ++c2; + break; + } + } + } + array2[c2] = l; + int n4 = 0; + if (b2.transformationType[l] == 3) { + n4 = 128; + } + if ((f2 & 0x1) != 0x0) { + array3[c2] = ay.readShort2(); + } + else { + array3[c2] = n4; + } + if ((f2 & 0x2) != 0x0) { + array4[c2] = ay.readShort2(); + } + else { + array4[c2] = n4; + } + if ((f2 & 0x4) != 0x0) { + array5[c2] = ay.readShort2(); + } + else { + array5[c2] = n4; + } + n3 = l; + ++c2; + } + } + q2.transformationCount = c2; + q2.transformationIndices = new int[c2]; + q2.transformX = new int[c2]; + q2.transformY = new int[c2]; + q2.transformZ = new int[c2]; + for (int l = 0; l < c2; ++l) { + q2.transformationIndices[l] = array2[l]; + q2.transformX[l] = array3[l]; + q2.transformY[l] = array4[l]; + q2.transformZ[l] = array5[l]; + } + } + } catch (Exception ex) { + + //ex.printStackTrace(); + } + } + + public static Frame method531(int frame) { + try { + + int file = frame >> 16; + int k = frame & 0xffff; + + if (animationlist[file].length == 0) { + Client.instance.resourceProvider.provide(1, file); + return null; + } + + return animationlist[file][k]; + } + catch (Exception ex) { + ex.printStackTrace(); + return null; + } + } + + public static boolean noAnimationInProgress(int frame) { + return frame == -1; + } + + public static void clear() { + animationlist = null; + } + + public int duration; + public FrameBase base; + public int transformationCount; + public int transformationIndices[]; + public int transformX[]; + public int transformY[]; + public int transformZ[]; +} diff --git a/src/main/java/org/rebotted/cache/anim/FrameBase.java b/src/main/java/org/rebotted/cache/anim/FrameBase.java new file mode 100644 index 0000000..8a216a6 --- /dev/null +++ b/src/main/java/org/rebotted/cache/anim/FrameBase.java @@ -0,0 +1,35 @@ +package org.rebotted.cache.anim; +import org.rebotted.io.Buffer; + +public final class FrameBase { + + /** + * The type of each transformation. + */ + public final int[] transformationType; + + public final int[][] skinList; + + public FrameBase(Buffer stream) { + int count = stream.readUShort(); + + transformationType = new int[count]; + skinList = new int[count][]; + + for (int index = 0; index < count; index++) { + transformationType[index] = stream.readUShort(); + } + + for (int label = 0; label < count; label++) { + skinList[label] = new int[stream.readUShort()]; + } + + for (int label = 0; label < count; label++) { + for (int index = 0; index < skinList[label].length; index++) { + skinList[label][index] = stream.readUShort(); + } + } + + } + +} diff --git a/src/main/java/org/rebotted/cache/anim/Graphic.java b/src/main/java/org/rebotted/cache/anim/Graphic.java new file mode 100644 index 0000000..fc1fc0c --- /dev/null +++ b/src/main/java/org/rebotted/cache/anim/Graphic.java @@ -0,0 +1,98 @@ +package org.rebotted.cache.anim; +import org.rebotted.cache.FileArchive; +import org.rebotted.collection.ReferenceCache; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; + +public final class Graphic { + + public static void init(FileArchive archive) { + Buffer buffer = new Buffer(archive.readFile("spotanim.dat")); + final int length = buffer.readUShort(); + if (cache == null) { + cache = new Graphic[length]; + } + for (int i = 0; i < length; i++) { + if (cache[i] == null) { + cache[i] = new Graphic(); + } + cache[i].id = i; + cache[i].decode(buffer); + } + + System.out.println("Loaded: "+length+" Graphics"); + } + + public void decode(Buffer buffer) { + while(true) { + int opcode = buffer.readUnsignedByte(); + + if (opcode == 0) { + return; + } else if (opcode == 1) { + modelId = buffer.readUShort(); + } else if (opcode == 2) { + animationId = buffer.readUShort(); + if (Animation.animations != null) { + animationSequence = Animation.animations[animationId]; + } + } else if (opcode == 4) { + resizeXY = buffer.readUShort(); + } else if (opcode == 5) { + resizeZ = buffer.readUShort(); + } else if (opcode == 6) { + rotation = buffer.readUShort(); + } else if (opcode == 7) { + modelBrightness = buffer.readUShort(); + } else if (opcode == 8) { + modelShadow = buffer.readUShort(); + } else if (opcode == 40) { + int length = buffer.readUnsignedByte(); + for (int i = 0; i < length; i++) { + originalModelColours[i] = buffer.readUShort(); + modifiedModelColours[i] = buffer.readUShort(); + } + } else { + System.out.println("Error unrecognised spotanim config code: " + + opcode); + } + } + } + + public Model getModel() { + Model model = (Model) models.get(id); + if (model != null) + return model; + model = Model.getModel(modelId); + if (model == null) + return null; + for (int i = 0; i < 6; i++) + if (originalModelColours[0] != 0) + model.recolor(originalModelColours[i], modifiedModelColours[i]); + + models.put(model, id); + return model; + } + + private Graphic() { + animationId = -1; + originalModelColours = new int[6]; + modifiedModelColours = new int[6]; + resizeXY = 128; + resizeZ = 128; + } + + public static Graphic cache[]; + private int id; + private int modelId; + private int animationId; + public Animation animationSequence; + private final int[] originalModelColours; + private final int[] modifiedModelColours; + public int resizeXY; + public int resizeZ; + public int rotation; + public int modelBrightness; + public int modelShadow; + public static ReferenceCache models = new ReferenceCache(30); +} diff --git a/src/main/java/org/rebotted/cache/bzip/BZip2DecompressionState.java b/src/main/java/org/rebotted/cache/bzip/BZip2DecompressionState.java new file mode 100644 index 0000000..2b96378 --- /dev/null +++ b/src/main/java/org/rebotted/cache/bzip/BZip2DecompressionState.java @@ -0,0 +1,60 @@ +package org.rebotted.cache.bzip; + +final class BZip2DecompressionState { + + byte compressed[]; + int nextIn; + int decompressedLength; + int totalInLo32; + int totalInHi32; + byte decompressed[]; + int nextOut; + int length; + int totalOutLo32; + int totalOutHigh32; + byte aByte573; + int anInt574; + boolean aBoolean575; + int bsBuff; + int bsLive; + int anInt578; + int currentBlock; + int randomised; + int anInt581; + int anInt582; + final int[] unzftab; + int anInt584; + final int[] cftab; + public static int tt[]; + int nInUse; + final boolean[] inUse; + final boolean[] inUse16; + final byte[] seqToUnseq; + final byte[] mtfa; + final int[] mtfbase; + final byte[] selector; + final byte[] selectorMtf; + final byte[][] len; + final int[][] limit; + final int[][] base; + final int[][] perm; + final int[] minLens; + int anInt601; + + BZip2DecompressionState() { + unzftab = new int[256]; + cftab = new int[257]; + inUse = new boolean[256]; + inUse16 = new boolean[16]; + seqToUnseq = 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/src/main/java/org/rebotted/cache/bzip/BZip2Decompressor.java b/src/main/java/org/rebotted/cache/bzip/BZip2Decompressor.java new file mode 100644 index 0000000..e36a932 --- /dev/null +++ b/src/main/java/org/rebotted/cache/bzip/BZip2Decompressor.java @@ -0,0 +1,500 @@ +package org.rebotted.cache.bzip; + +public final class BZip2Decompressor { + + public static int decompress(byte output[], int length, byte compressed[], int decompressedLength, int minLen) { + synchronized (state) { + state.compressed = compressed; + state.nextIn = minLen; + state.decompressed = output; + state.nextOut = 0; + state.decompressedLength = decompressedLength; + state.length = length; + state.bsLive = 0; + state.bsBuff = 0; + state.totalInLo32 = 0; + state.totalInHi32 = 0; + state.totalOutLo32 = 0; + state.totalOutHigh32 = 0; + state.currentBlock = 0; + decompress(state); + length -= state.length; + return length; + } + } + + private static void method226(BZip2DecompressionState state) { + byte byte4 = state.aByte573; + int i = state.anInt574; + int j = state.anInt584; + int k = state.anInt582; + int ai[] = BZip2DecompressionState.tt; + int l = state.anInt581; + byte abyte0[] = state.decompressed; + int i1 = state.nextOut; + int j1 = state.length; + int k1 = j1; + int l1 = state.anInt601 + 1; + label0: do { + if (i > 0) { + do { + if (j1 == 0) + break label0; + if (i == 1) + break; + abyte0[i1] = byte4; + i--; + i1++; + j1--; + } while (true); + if (j1 == 0) { + i = 1; + break; + } + abyte0[i1] = byte4; + i1++; + j1--; + } + boolean flag = true; + while (flag) { + flag = false; + if (j == l1) { + i = 0; + break label0; + } + byte4 = (byte) k; + l = ai[l]; + byte byte0 = (byte) (l & 0xff); + l >>= 8; + j++; + if (byte0 != k) { + k = byte0; + if (j1 == 0) { + i = 1; + } else { + abyte0[i1] = byte4; + i1++; + j1--; + flag = true; + continue; + } + break label0; + } + if (j != l1) + continue; + if (j1 == 0) { + i = 1; + break label0; + } + abyte0[i1] = byte4; + i1++; + j1--; + flag = true; + } + i = 2; + l = ai[l]; + byte byte1 = (byte) (l & 0xff); + l >>= 8; + if (++j != l1) + if (byte1 != k) { + k = byte1; + } else { + i = 3; + l = ai[l]; + byte byte2 = (byte) (l & 0xff); + l >>= 8; + if (++j != l1) + if (byte2 != k) { + k = byte2; + } else { + l = ai[l]; + byte byte3 = (byte) (l & 0xff); + l >>= 8; + j++; + i = (byte3 & 0xff) + 4; + l = ai[l]; + k = (byte) (l & 0xff); + l >>= 8; + j++; + } + } + } while (true); + int i2 = state.totalOutLo32; + state.totalOutLo32 += k1 - j1; + if (state.totalOutLo32 < i2) + state.totalOutHigh32++; + state.aByte573 = byte4; + state.anInt574 = i; + state.anInt584 = j; + state.anInt582 = k; + BZip2DecompressionState.tt = ai; + state.anInt581 = l; + state.decompressed = abyte0; + state.nextOut = i1; + state.length = j1; + } + + private static void decompress(BZip2DecompressionState state) { + int gMinLen = 0; + int gLimit[] = null; + int gBase[] = null; + int gPerm[] = null; + state.anInt578 = 1; + if (BZip2DecompressionState.tt == null) + BZip2DecompressionState.tt = new int[state.anInt578 * 0x186a0]; + boolean flag19 = true; + while (flag19) { + byte uc = getUnsignedChar(state); + if (uc == 23) + return; + uc = getUnsignedChar(state); + uc = getUnsignedChar(state); + uc = getUnsignedChar(state); + uc = getUnsignedChar(state); + uc = getUnsignedChar(state); + state.currentBlock++; + uc = getUnsignedChar(state); + uc = getUnsignedChar(state); + uc = getUnsignedChar(state); + uc = getUnsignedChar(state); + uc = getBit(state); + state.aBoolean575 = uc != 0; + state.randomised = 0; + uc = getUnsignedChar(state); + state.randomised = state.randomised << 8 | uc & 0xff; + uc = getUnsignedChar(state); + state.randomised = state.randomised << 8 | uc & 0xff; + uc = getUnsignedChar(state); + state.randomised = state.randomised << 8 | uc & 0xff; + for (int j = 0; j < 16; j++) { + byte bit = getBit(state); + state.inUse16[j] = bit == 1; + } + + for (int k = 0; k < 256; k++) + state.inUse[k] = false; + + for (int l = 0; l < 16; l++) + if (state.inUse16[l]) { + for (int i3 = 0; i3 < 16; i3++) { + byte byte2 = getBit(state); + if (byte2 == 1) + state.inUse[l * 16 + i3] = true; + } + + } + + makeMaps(state); + int alphabetSize = state.nInUse + 2; + /* + * number of different Huffman tables in use + */ + int huffmanTableCount = getBits(3, state); + /* + * number of times that the Huffman tables are swapped (each 50 bytes) + */ + int swapCount = getBits(15, state); + for (int i1 = 0; i1 < swapCount; i1++) { + int count = 0; + do { + byte byte3 = getBit(state); + if (byte3 == 0) + break; + count++; + } while (true); + state.selectorMtf[i1] = (byte) count; + } + + byte pos[] = new byte[6]; + for (byte v = 0; v < huffmanTableCount; v++) + pos[v] = v; + + for (int j1 = 0; j1 < swapCount; j1++) { + byte v = state.selectorMtf[j1]; + byte tmp = pos[v]; + for (; v > 0; v--) + pos[v] = pos[v - 1]; + + pos[0] = tmp; + state.selector[j1] = tmp; + } + + for (int k3 = 0; k3 < huffmanTableCount; k3++) { + int l6 = getBits(5, state); + for (int k1 = 0; k1 < alphabetSize; k1++) { + do { + byte byte4 = getBit(state); + if (byte4 == 0) + break; + byte4 = getBit(state); + if (byte4 == 0) + l6++; + else + l6--; + } while (true); + state.len[k3][k1] = (byte) l6; + } + + } + + for (int l3 = 0; l3 < huffmanTableCount; l3++) { + byte byte8 = 32; + int i = 0; + for (int l1 = 0; l1 < alphabetSize; l1++) { + if (state.len[l3][l1] > i) + i = state.len[l3][l1]; + if (state.len[l3][l1] < byte8) + byte8 = state.len[l3][l1]; + } + + createDecodeTables(state.limit[l3], state.base[l3], state.perm[l3], state.len[l3], byte8, i, alphabetSize); + state.minLens[l3] = byte8; + } + + int l4 = state.nInUse + 1; + int i5 = -1; + int j5 = 0; + for (int i2 = 0; i2 <= 255; i2++) + state.unzftab[i2] = 0; + + int j9 = 4095; + for (int l8 = 15; l8 >= 0; l8--) { + for (int i9 = 15; i9 >= 0; i9--) { + state.mtfa[j9] = (byte) (l8 * 16 + i9); + j9--; + } + + state.mtfbase[l8] = j9 + 1; + } + + int i6 = 0; + if (j5 == 0) { + i5++; + j5 = 50; + byte byte12 = state.selector[i5]; + gMinLen = state.minLens[byte12]; + gLimit = state.limit[byte12]; + gPerm = state.perm[byte12]; + gBase = state.base[byte12]; + } + j5--; + int i7 = gMinLen; + int l7; + byte byte9; + for (l7 = getBits(i7, state); l7 > gLimit[i7]; l7 = l7 << 1 | byte9) { + i7++; + byte9 = getBit(state); + } + + for (int k5 = gPerm[l7 - gBase[i7]]; k5 != l4;) + if (k5 == 0 || k5 == 1) { + int j6 = -1; + int k6 = 1; + do { + if (k5 == 0) + j6 += k6; + else if (k5 == 1) + j6 += 2 * k6; + k6 *= 2; + if (j5 == 0) { + i5++; + j5 = 50; + byte byte13 = state.selector[i5]; + gMinLen = state.minLens[byte13]; + gLimit = state.limit[byte13]; + gPerm = state.perm[byte13]; + gBase = state.base[byte13]; + } + j5--; + int j7 = gMinLen; + int i8; + byte byte10; + for (i8 = getBits(j7, state); i8 > gLimit[j7]; i8 = i8 << 1 | byte10) { + j7++; + byte10 = getBit(state); + } + + k5 = gPerm[i8 - gBase[j7]]; + } while (k5 == 0 || k5 == 1); + j6++; + byte byte5 = state.seqToUnseq[state.mtfa[state.mtfbase[0]] & 0xff]; + state.unzftab[byte5 & 0xff] += j6; + for (; j6 > 0; j6--) { + BZip2DecompressionState.tt[i6] = byte5 & 0xff; + i6++; + } + + } else { + int j11 = k5 - 1; + byte byte6; + if (j11 < 16) { + int j10 = state.mtfbase[0]; + byte6 = state.mtfa[j10 + j11]; + for (; j11 > 3; j11 -= 4) { + int k11 = j10 + j11; + state.mtfa[k11] = state.mtfa[k11 - 1]; + state.mtfa[k11 - 1] = state.mtfa[k11 - 2]; + state.mtfa[k11 - 2] = state.mtfa[k11 - 3]; + state.mtfa[k11 - 3] = state.mtfa[k11 - 4]; + } + + for (; j11 > 0; j11--) + state.mtfa[j10 + j11] = state.mtfa[(j10 + j11) - 1]; + + state.mtfa[j10] = byte6; + } else { + int l10 = j11 / 16; + int i11 = j11 % 16; + int k10 = state.mtfbase[l10] + i11; + byte6 = state.mtfa[k10]; + for (; k10 > state.mtfbase[l10]; k10--) + state.mtfa[k10] = state.mtfa[k10 - 1]; + + state.mtfbase[l10]++; + for (; l10 > 0; l10--) { + state.mtfbase[l10]--; + state.mtfa[state.mtfbase[l10]] = state.mtfa[(state.mtfbase[l10 - 1] + 16) - 1]; + } + + state.mtfbase[0]--; + state.mtfa[state.mtfbase[0]] = byte6; + if (state.mtfbase[0] == 0) { + int i10 = 4095; + for (int k9 = 15; k9 >= 0; k9--) { + for (int l9 = 15; l9 >= 0; l9--) { + state.mtfa[i10] = state.mtfa[state.mtfbase[k9] + l9]; + i10--; + } + + state.mtfbase[k9] = i10 + 1; + } + + } + } + state.unzftab[state.seqToUnseq[byte6 & 0xff] & 0xff]++; + BZip2DecompressionState.tt[i6] = state.seqToUnseq[byte6 & 0xff] & 0xff; + i6++; + if (j5 == 0) { + i5++; + j5 = 50; + byte byte14 = state.selector[i5]; + gMinLen = state.minLens[byte14]; + gLimit = state.limit[byte14]; + gPerm = state.perm[byte14]; + gBase = state.base[byte14]; + } + j5--; + int k7 = gMinLen; + int j8; + byte byte11; + for (j8 = getBits(k7, state); j8 > gLimit[k7]; j8 = j8 << 1 | byte11) { + k7++; + byte11 = getBit(state); + } + + k5 = gPerm[j8 - gBase[k7]]; + } + + state.anInt574 = 0; + state.aByte573 = 0; + state.cftab[0] = 0; + for (int j2 = 1; j2 <= 256; j2++) + state.cftab[j2] = state.unzftab[j2 - 1]; + + for (int k2 = 1; k2 <= 256; k2++) + state.cftab[k2] += state.cftab[k2 - 1]; + + for (int l2 = 0; l2 < i6; l2++) { + byte byte7 = (byte) (BZip2DecompressionState.tt[l2] & 0xff); + BZip2DecompressionState.tt[state.cftab[byte7 & 0xff]] |= l2 << 8; + state.cftab[byte7 & 0xff]++; + } + + state.anInt581 = BZip2DecompressionState.tt[state.randomised] >> 8; + state.anInt584 = 0; + state.anInt581 = BZip2DecompressionState.tt[state.anInt581]; + state.anInt582 = (byte) (state.anInt581 & 0xff); + state.anInt581 >>= 8; + state.anInt584++; + state.anInt601 = i6; + method226(state); + flag19 = state.anInt584 == state.anInt601 + 1 && state.anInt574 == 0; + } + } + + private static byte getUnsignedChar(BZip2DecompressionState state) { + return (byte) getBits(8, state); + } + + private static byte getBit(BZip2DecompressionState state) { + return (byte) getBits(1, state); + } + + private static int getBits(int i, BZip2DecompressionState state) { + int j; + do { + if (state.bsLive >= i) { + int k = state.bsBuff >> state.bsLive - i & (1 << i) - 1; + state.bsLive -= i; + j = k; + break; + } + state.bsBuff = state.bsBuff << 8 | state.compressed[state.nextIn] & 0xff; + state.bsLive += 8; + state.nextIn++; + state.decompressedLength--; + state.totalInLo32++; + if (state.totalInLo32 == 0) + state.totalInHi32++; + } while (true); + return j; + } + + private static void makeMaps(BZip2DecompressionState state) { + state.nInUse = 0; + for (int i = 0; i < 256; i++) + if (state.inUse[i]) { + state.seqToUnseq[state.nInUse] = (byte) i; + state.nInUse++; + } + + } + + private static void createDecodeTables(int limit[], int base[], int perm[], byte length[], int i, int maxLength, int alphabetSize) { + int pp = 0; + for (int i1 = i; i1 <= maxLength; i1++) { + for (int l2 = 0; l2 < alphabetSize; l2++) { + if (length[l2] == i1) { + perm[pp] = l2; + pp++; + } + } + } + + for (int j1 = 0; j1 < 23; j1++) + base[j1] = 0; + + for (int k1 = 0; k1 < alphabetSize; k1++) + base[length[k1] + 1]++; + + for (int l1 = 1; l1 < 23; l1++) + base[l1] += base[l1 - 1]; + + for (int i2 = 0; i2 < 23; i2++) + limit[i2] = 0; + + int vec = 0; + for (int j2 = i; j2 <= maxLength; j2++) { + vec += base[j2 + 1] - base[j2]; + limit[j2] = vec - 1; + vec <<= 1; + } + + for (int k2 = i + 1; k2 <= maxLength; k2++) + base[k2] = (limit[k2 - 1] + 1 << 1) - base[k2]; + + } + + private static final BZip2DecompressionState state = new BZip2DecompressionState(); + +} diff --git a/src/main/java/org/rebotted/cache/config/Varbit.java b/src/main/java/org/rebotted/cache/config/Varbit.java new file mode 100644 index 0000000..7e89316 --- /dev/null +++ b/src/main/java/org/rebotted/cache/config/Varbit.java @@ -0,0 +1,89 @@ +package org.rebotted.cache.config; + +import org.rebotted.cache.FileArchive; +import org.rebotted.io.Buffer; + +public final class Varbit { + + public static Varbit varbits[]; + public int setting = -1; + public int low = -1; + public int high = -1; + private boolean aBoolean651; + + public static void init(FileArchive streamLoader) { + Buffer datBuf = new Buffer(streamLoader.readFile("varbit.dat")); + + final int size = datBuf.readUShort(); + + if (varbits == null) { + varbits = new Varbit[size]; + } + + for (int index = 0; index < size; index++) { + + if (varbits[index] == null) { + varbits[index] = new Varbit(); + } + + varbits[index].decode(datBuf); + + if (varbits[index].aBoolean651) { + Varp.variables[varbits[index].setting].aBoolean713 = true; + } + + } + + if (datBuf.currentPosition != datBuf.payload.length) { + System.out.println("varbit load mismatch"); + } + + } + +/* private void decode(Buffer stream) { + setting = stream.readUShort(); + low = stream.readUnsignedByte(); + high = stream.readUnsignedByte(); + + }*/ + private void decode(Buffer stream) { + do { + int j = stream.readUnsignedByte(); + if (j == 0) { + return; + } + if (j == 1) { + setting = stream.readUShort(); + low = stream.readUnsignedByte(); + high = stream.readUnsignedByte(); + } else if (j == 10) { + stream.readString(); + } else if (j == 2) { + aBoolean651 = true; + } else if (j == 3) { + stream.readDWord(); + } else if (j == 4) { + stream.readDWord(); + } else { + System.out.println("Error unrecognised config code: " + j); + } + } while (true); + } + + private Varbit() { + aBoolean651 = false; + } + + public int getSetting() { + return setting; + } + + public int getLow() { + return low; + } + + public int getHigh() { + return high; + } + +} diff --git a/src/main/java/org/rebotted/cache/config/Varp.java b/src/main/java/org/rebotted/cache/config/Varp.java new file mode 100644 index 0000000..4c20bfa --- /dev/null +++ b/src/main/java/org/rebotted/cache/config/Varp.java @@ -0,0 +1,108 @@ +package org.rebotted.cache.config; + +import org.rebotted.cache.FileArchive; +import org.rebotted.io.Buffer; + +/** + * Varps are used for inteface configuration ids and their functions, out of the current 725 config ids, only 9 or so of them are used. + * + */ +public final class Varp { + + public static Varp[] variables; + + private static int currentIndex; + private static int[] configIds; + public int actionId; + public boolean aBoolean713; + + private Varp() { + aBoolean713 = false; + } + + public static void init(FileArchive archive) { + Buffer buffer = new Buffer(archive.readFile("varp.dat")); + + currentIndex = 0; + + int length = buffer.readUShort(); + + if (variables == null) { + variables = new Varp[length]; + } + + if (configIds == null) { + configIds = new int[length]; + } + + for (int index = 0; index < length; index++) { + if (variables[index] == null) { + variables[index] = new Varp(); + } + + variables[index].decode(buffer, index); + + } + + if (buffer.currentPosition != buffer.payload.length) { + System.out.println("varptype load mismatch"); + } + + } + + private void decode(Buffer buffer, int index) { + do { + int opcode = buffer.readUnsignedByte(); + + if (opcode == 0) { + return; + } + + if (opcode == 1) { + buffer.readUnsignedByte(); + } else if (opcode == 2) { + buffer.readUnsignedByte(); + } else if (opcode == 3) { + configIds[currentIndex++] = index; + } else if (opcode == 4) { + } else if (opcode == 5) { + actionId = buffer.readUShort(); + } else if (opcode == 6) { + } else if (opcode == 7) { + buffer.readInt(); + } else if (opcode == 8) { + aBoolean713 = true; + } else if (opcode == 10) { + buffer.readString(); + } else if (opcode == 11) { + aBoolean713 = true; + } else if (opcode == 12) { + buffer.readInt(); + } else if (opcode == 13) { + } else { + System.out.println("Error unrecognised config code: " + opcode); + } + } while (true); + } + + public static Varp[] getVariables() { + return variables; + } + + public static int getCurrentIndex() { + return currentIndex; + } + + public static int[] getConfigIds() { + return configIds; + } + + public int getActionId() { + return actionId; + } + + public boolean isaBoolean713() { + return aBoolean713; + } + +} diff --git a/src/main/java/org/rebotted/cache/def/FileOperations.java b/src/main/java/org/rebotted/cache/def/FileOperations.java new file mode 100644 index 0000000..bce41d9 --- /dev/null +++ b/src/main/java/org/rebotted/cache/def/FileOperations.java @@ -0,0 +1,47 @@ +package org.rebotted.cache.def; +import java.io.*; + +public class FileOperations { + + public FileOperations() { + } + + public static final byte[] ReadFile(String s) { + try { + File file = new File(s); + int i = (int) file.length(); + byte abyte0[] = new byte[i]; + DataInputStream datainputstream = new DataInputStream( + new BufferedInputStream(new FileInputStream(s))); + datainputstream.readFully(abyte0, 0, i); + datainputstream.close(); + TotalRead++; + return abyte0; + } catch (Exception exception) { + } + return null; + } + + public static final void WriteFile(String s, byte abyte0[]) { + try { + (new File((new File(s)).getParent())).mkdirs(); + FileOutputStream fileoutputstream = new FileOutputStream(s); + fileoutputstream.write(abyte0, 0, abyte0.length); + fileoutputstream.close(); + TotalWrite++; + CompleteWrite++; + } catch (Throwable throwable) { + System.out.println((new StringBuilder()).append("Write Error: ") + .append(s).toString()); + } + } + + public static boolean FileExists(String file) { + File f = new File(file); + return f.exists(); + } + + public static int TotalRead = 0; + public static int TotalWrite = 0; + public static int CompleteWrite = 0; +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/cache/def/FloorDefinition.java b/src/main/java/org/rebotted/cache/def/FloorDefinition.java new file mode 100644 index 0000000..e806fe4 --- /dev/null +++ b/src/main/java/org/rebotted/cache/def/FloorDefinition.java @@ -0,0 +1,178 @@ +package org.rebotted.cache.def; + +import java.nio.ByteBuffer; + +import org.rebotted.cache.FileArchive; + + +public class FloorDefinition { + + public static FloorDefinition[] overlays; + public static FloorDefinition[] underlays; + + public int texture; + public int rgb; + public boolean occlude; + public int anotherRgb; + + public int hue; + public int saturation; + public int luminance; + + public int anotherHue; + public int anotherSaturation; + public int anotherLuminance; + + public int blendHue; + public int blendHueMultiplier; + public int hsl16; + + private FloorDefinition() { + texture = -1; + occlude = true; + } + + public static void unpackConfig(FileArchive streamLoader) { + ByteBuffer buffer = ByteBuffer.wrap(streamLoader.readFile("flo.dat")); + int underlayAmount = buffer.getShort(); + System.out.println("Underlay Floors Loaded: "+underlayAmount); + underlays = new FloorDefinition[underlayAmount]; + for (int i = 0; i < underlayAmount; i++) { + if (underlays[i] == null) { + underlays[i] = new FloorDefinition(); + } + underlays[i].readValuesUnderlay(buffer); + underlays[i].generateHsl(); + } + int overlayAmount = buffer.getShort(); + System.out.println("Overlay Floors Loaded: "+overlayAmount); + overlays = new FloorDefinition[overlayAmount]; + for (int i = 0; i < overlayAmount; i++) { + if (overlays[i] == null) { + overlays[i] = new FloorDefinition(); + } + overlays[i].readValuesOverlay(buffer); + overlays[i].generateHsl(); + } + } + + private void generateHsl() { + if (anotherRgb != -1) { + rgbToHsl(anotherRgb); + anotherHue = hue; + anotherSaturation = saturation; + anotherLuminance = luminance; + } + rgbToHsl(rgb); + } + + private void readValuesUnderlay(ByteBuffer buffer) { + for (;;) { + int opcode = buffer.get(); + if (opcode == 0) { + break; + } else if (opcode == 1) { + rgb = ((buffer.get() & 0xff) << 16) + ((buffer.get() & 0xff) << 8) + (buffer.get() & 0xff); + } else { + System.out.println("Error unrecognised underlay code: " + opcode); + } + } + } + + private void readValuesOverlay(ByteBuffer buffer) { + for (;;) { + int opcode = buffer.get(); + if (opcode == 0) { + break; + } else if (opcode == 1) { + rgb = ((buffer.get() & 0xff) << 16) + ((buffer.get() & 0xff) << 8) + (buffer.get() & 0xff); + } else if (opcode == 2) { + texture = buffer.get() & 0xff; + } else if (opcode == 5) { + occlude = false; + } else if (opcode == 7) { + anotherRgb = ((buffer.get() & 0xff) << 16) + ((buffer.get() & 0xff) << 8) + (buffer.get() & 0xff); + } else { + System.out.println("Error unrecognised overlay code: " + opcode); + } + } + } + + private void rgbToHsl(int rgb) { + double r = (rgb >> 16 & 0xff) / 256.0; + double g = (rgb >> 8 & 0xff) / 256.0; + double b = (rgb & 0xff) / 256.0; + double min = r; + if (g < min) { + min = g; + } + if (b < min) { + min = b; + } + double max = r; + if (g > max) { + max = g; + } + if (b > max) { + max = b; + } + double h = 0.0; + double s = 0.0; + double l = (min + max) / 2.0; + if (min != max) { + if (l < 0.5) { + s = (max - min) / (max + min); + } + if (l >= 0.5) { + s = (max - min) / (2.0 - max - min); + } + if (r == max) { + h = (g - b) / (max - min); + } else if (g == max) { + h = 2.0 + (b - r) / (max - min); + } else if (b == max) { + h = 4.0 + (r - g) / (max - min); + } + } + h /= 6.0; + hue = (int) (h * 256.0); + saturation = (int) (s * 256.0); + luminance = (int) (l * 256.0); + if (saturation < 0) { + saturation = 0; + } else if (saturation > 255) { + saturation = 255; + } + if (luminance < 0) { + luminance = 0; + } else if (luminance > 255) { + luminance = 255; + } + if (l > 0.5) { + blendHueMultiplier = (int) ((1.0 - l) * s * 512.0); + } else { + blendHueMultiplier = (int) (l * s * 512.0); + } + if (blendHueMultiplier < 1) { + blendHueMultiplier = 1; + } + blendHue = (int) (h * blendHueMultiplier); + hsl16 = hsl24to16(hue, saturation, luminance); + } + + final static int hsl24to16(int h, int s, int l) { + if (l > 179) { + s /= 2; + } + if (l > 192) { + s /= 2; + } + if (l > 217) { + s /= 2; + } + if (l > 243) { + s /= 2; + } + return (h / 4 << 10) + (s / 32 << 7) + l / 2; + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/cache/def/ItemDefinition.java b/src/main/java/org/rebotted/cache/def/ItemDefinition.java new file mode 100644 index 0000000..f8826a4 --- /dev/null +++ b/src/main/java/org/rebotted/cache/def/ItemDefinition.java @@ -0,0 +1,556 @@ +package org.rebotted.cache.def; + +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.graphics.Sprite; +import org.rebotted.collection.ReferenceCache; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.draw.Rasterizer3D; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; + +public final class ItemDefinition { + + public static void init(FileArchive archive) { + dataBuf = new Buffer(archive.readFile("obj.dat")); + Buffer idxBuf = new Buffer(archive.readFile("obj.idx")); + + itemCount = idxBuf.readUShort(); + streamIndices = new int[itemCount]; + + int offset = 2; + + for (int i = 0; i < itemCount; i++) { + streamIndices[i] = offset; + offset += idxBuf.readUShort(); + } + + cache = new ItemDefinition[10]; + + for (int i = 0; i < 10; i++) { + cache[i] = new ItemDefinition(); + } + + System.out.println("Loaded: " + itemCount + " Items"); + + } + + private void decode(Buffer buffer) { + do { + int opcode = buffer.readUnsignedByte(); + + if (opcode == 0) { + return; + } else if (opcode == 1) { + inventoryModel = buffer.readUShort(); + } else if (opcode == 2) { + name = buffer.readString(); + } else if (opcode == 3) { + description = buffer.readString(); + } else if (opcode == 4) { + modelZoom = buffer.readUShort(); + } else if (opcode == 5) { + rotationY = buffer.readUShort(); + } else if (opcode == 6) { + rotationX = buffer.readUShort(); + } else if (opcode == 7) { + translateX = buffer.readUShort(); + if (translateX > 32767) + translateX -= 0x10000; + } else if (opcode == 8) { + translateYZ = buffer.readUShort(); + if (translateYZ > 32767) + translateYZ -= 0x10000; + } else if (opcode == 10) { + buffer.readUShort(); + } else if (opcode == 11) { + stackable = true; + } else if (opcode == 12) { + value = buffer.readInt(); + } else if (opcode == 16) { + members = true; + } else if (opcode == 23) { + equippedMaleModel1 = buffer.readUShort(); + equippedMaleModelTranslationY = buffer.readSignedByte(); + } else if (opcode == 24) { + equippedMaleModel2 = buffer.readUShort(); + } else if (opcode == 25) { + equippedFemaleModel1 = buffer.readUShort(); + equippedFemaleModelTranslationY = buffer.readSignedByte(); + } else if (opcode == 26) { + equippedFemaleModel2 = buffer.readUShort(); + } else if (opcode >= 30 && opcode < 35) { + if (groundActions == null) { + groundActions = new String[5]; + } + groundActions[opcode - 30] = buffer.readString(); + if (groundActions[opcode - 30].equalsIgnoreCase("hidden")) { + groundActions[opcode - 30] = null; + } + } else if (opcode >= 35 && opcode < 40) { + if (actions == null) { + actions = new String[5]; + } + actions[opcode - 35] = buffer.readString(); + } else if (opcode == 40) { + + int colors = buffer.readUnsignedByte(); + modifiedModelColors = new int[colors]; + originalModelColors = new int[colors]; + for (int i = 0; i < colors; i++) { + modifiedModelColors[i] = buffer.readUShort(); + originalModelColors[i] = buffer.readUShort(); + } + } else if (opcode == 78) { + equippedMaleModel3 = buffer.readUShort(); + } else if (opcode == 79) { + equippedFemaleModel3 = buffer.readUShort(); + } else if (opcode == 90) { + equippedMaleModelDialogue1 = buffer.readUShort(); + } else if (opcode == 91) { + equippedFemaleModelDialogue1 = buffer.readUShort(); + } else if (opcode == 92) { + equippedMaleModelDialogue2 = buffer.readUShort(); + } else if (opcode == 93) { + equippedFemaleModelDialogue2 = buffer.readUShort(); + } else if (opcode == 95) { + rotationZ = buffer.readUShort(); + } else if (opcode == 97) { + unnotedItemId = buffer.readUShort(); + } else if (opcode == 98) { + notedItemId = buffer.readUShort(); + } else if (opcode >= 100 && opcode < 110) { + if (stackVariantId == null) { + stackVariantId = new int[10]; + stackVariantSize = new int[10]; + } + stackVariantId[opcode - 100] = buffer.readUShort(); + stackVariantSize[opcode - 100] = buffer.readUShort(); + } else if (opcode == 110) { + modelScaleX = buffer.readUShort(); + } else if (opcode == 111) { + modelScaleY = buffer.readUShort(); + } else if (opcode == 112) { + modelScaleZ = buffer.readUShort(); + } else if (opcode == 113) { + lightIntensity = buffer.readSignedByte(); + } else if (opcode == 114) { + lightMag = buffer.readSignedByte() * 5; + } else if (opcode == 115) { + team = buffer.readUnsignedByte(); + } + } while (true); + } + + public Model getChatEquipModel(int gender) { + int dialogueModel = equippedMaleModelDialogue1; + int dialogueHatModel = equippedMaleModelDialogue2; + if (gender == 1) { + dialogueModel = equippedFemaleModelDialogue1; + dialogueHatModel = equippedFemaleModelDialogue2; + } + if (dialogueModel == -1) + return null; + Model dialogueModel_ = Model.getModel(dialogueModel); + if (dialogueHatModel != -1) { + Model hatModel_ = Model.getModel(dialogueHatModel); + Model models[] = { dialogueModel_, hatModel_ }; + dialogueModel_ = new Model(2, models); + } + if (modifiedModelColors != null) { + for (int i1 = 0; i1 < modifiedModelColors.length; i1++) + dialogueModel_.recolor(modifiedModelColors[i1], originalModelColors[i1]); + + } + return dialogueModel_; + } + + public boolean isEquippedModelCached(int gender) { + int primaryModel = equippedMaleModel1; + int secondaryModel = equippedMaleModel2; + int emblem = equippedMaleModel3; + if (gender == 1) { + primaryModel = equippedFemaleModel1; + secondaryModel = equippedFemaleModel2; + emblem = equippedFemaleModel3; + } + if (primaryModel == -1) + return true; + boolean cached = true; + if (!Model.isCached(primaryModel)) + cached = false; + if (secondaryModel != -1 && !Model.isCached(secondaryModel)) + cached = false; + if (emblem != -1 && !Model.isCached(emblem)) + cached = false; + return cached; + } + + public Model getEquippedModel(int gender) { + int primaryModel = equippedMaleModel1; + int secondaryModel = equippedMaleModel2; + int emblem = equippedMaleModel3; + if (gender == 1) { + primaryModel = equippedFemaleModel1; + secondaryModel = equippedFemaleModel2; + emblem = equippedFemaleModel3; + } + if (primaryModel == -1) + return null; + Model primaryModel_ = Model.getModel(primaryModel); + if (secondaryModel != -1) + if (emblem != -1) { + Model secondaryModel_ = Model.getModel(secondaryModel); + Model emblemModel = Model.getModel(emblem); + Model models[] = { primaryModel_, secondaryModel_, emblemModel }; + primaryModel_ = new Model(3, models); + } else { + Model model_2 = Model.getModel(secondaryModel); + Model models[] = { primaryModel_, model_2 }; + primaryModel_ = new Model(2, models); + } + if (gender == 0 && equippedMaleModelTranslationY != 0) + primaryModel_.translate(0, equippedMaleModelTranslationY, 0); + if (gender == 1 && equippedFemaleModelTranslationY != 0) + primaryModel_.translate(0, equippedFemaleModelTranslationY, 0); + if (modifiedModelColors != null) { + for (int i1 = 0; i1 < modifiedModelColors.length; i1++) + primaryModel_.recolor(modifiedModelColors[i1], originalModelColors[i1]); + + } + return primaryModel_; + } + + private void setDefaults() { + inventoryModel = 0; + name = "Dwarf Remains"; + description = null; + modifiedModelColors = null; + originalModelColors = null; + modelZoom = 2000; + rotationY = 0; + rotationX = 0; + rotationZ = 0; + translateX = 0; + translateYZ = 0; + stackable = false; + value = 1; + members = false; + groundActions = null; + actions = null; + equippedMaleModel1 = -1; + equippedMaleModel2 = -1; + equippedMaleModelTranslationY = 0; + equippedFemaleModel1 = -1; + equippedFemaleModel2 = -1; + equippedFemaleModelTranslationY = 0; + equippedMaleModel3 = -1; + equippedFemaleModel3 = -1; + equippedMaleModelDialogue1 = -1; + equippedMaleModelDialogue2 = -1; + equippedFemaleModelDialogue1 = -1; + equippedFemaleModelDialogue2 = -1; + stackVariantId = null; + stackVariantSize = null; + unnotedItemId = -1; + notedItemId = -1; + modelScaleX = 128; + modelScaleY = 128; + modelScaleZ = 128; + lightIntensity = 0; + lightMag = 0; + team = 0; + } + + public static ItemDefinition lookup(int itemId) { + for (int count = 0; count < 10; count++) { + if (cache[count].id == itemId) { + return cache[count]; + } + } + + cacheIndex = (cacheIndex + 1) % 10; + ItemDefinition itemDef = cache[cacheIndex]; + dataBuf.currentPosition = streamIndices[itemId]; + itemDef.id = itemId; + itemDef.setDefaults(); + itemDef.decode(dataBuf); + + if (itemDef.notedItemId != -1) { + itemDef.toNote(); + } + + return itemDef; + } + + private void toNote() { + ItemDefinition itemDef = lookup(notedItemId); + inventoryModel = itemDef.inventoryModel; + modelZoom = itemDef.modelZoom; + rotationY = itemDef.rotationY; + rotationX = itemDef.rotationX; + + rotationZ = itemDef.rotationZ; + translateX = itemDef.translateX; + translateYZ = itemDef.translateYZ; + modifiedModelColors = itemDef.modifiedModelColors; + originalModelColors = itemDef.originalModelColors; + ItemDefinition itemDef_1 = lookup(unnotedItemId); + name = itemDef_1.name; + members = itemDef_1.members; + value = itemDef_1.value; + String s = "a"; + char c = itemDef_1.name.charAt(0); + if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') + s = "an"; + description = ("Swap this note at any bank for " + s + " " + itemDef_1.name + "."); + stackable = true; + } + + public static Sprite getSprite(int itemId, int stackSize, int outlineColor) { + if (outlineColor == 0) { + Sprite sprite = (Sprite) sprites.get(itemId); + if (sprite != null && sprite.getMaxHeight() != stackSize && sprite.getMaxHeight() != -1) { + + sprite.unlink(); + sprite = null; + } + if (sprite != null) + return sprite; + } + ItemDefinition itemDef = lookup(itemId); + if (itemDef.stackVariantId == null) + stackSize = -1; + if (stackSize > 1) { + int stack_item_id = -1; + for (int j1 = 0; j1 < 10; j1++) + if (stackSize >= itemDef.stackVariantSize[j1] && itemDef.stackVariantSize[j1] != 0) + stack_item_id = itemDef.stackVariantId[j1]; + + if (stack_item_id != -1) + itemDef = lookup(stack_item_id); + } + Model model = itemDef.getModel(1); + if (model == null) + return null; + Sprite sprite = null; + if (itemDef.notedItemId != -1) { + sprite = getSprite(itemDef.unnotedItemId, 10, -1); + if (sprite == null) + return null; + } + Sprite enabledSprite = new Sprite(32, 32); + int centerX = Rasterizer3D.originViewX; + int centerY = Rasterizer3D.originViewY; + int lineOffsets[] = Rasterizer3D.scanOffsets; + int pixels[] = Rasterizer2D.pixels; + float depthBuffer[] = Rasterizer2D.depthBuffer; + int width = Rasterizer2D.width; + int height = Rasterizer2D.height; + int vp_left = Rasterizer2D.leftX; + int vp_right = Rasterizer2D.bottomX; + int vp_top = Rasterizer2D.topY; + int vp_bottom = Rasterizer2D.bottomY; + Rasterizer3D.aBoolean1464 = false; + Rasterizer2D.initDrawingArea(32, 32, enabledSprite.getMyPixels(), new float[32 * 32]); + Rasterizer2D.drawBox(0, 0, 32, 32, 0); + Rasterizer3D.useViewport(); + int k3 = itemDef.modelZoom; + if (outlineColor == -1) + k3 = (int) ((double) k3 * 1.5D); + if (outlineColor > 0) + k3 = (int) ((double) k3 * 1.04D); + int l3 = Rasterizer3D.anIntArray1470[itemDef.rotationY] * k3 >> 16; + int i4 = Rasterizer3D.COSINE[itemDef.rotationY] * k3 >> 16; + model.method482(itemDef.rotationX, itemDef.rotationZ, itemDef.rotationY, itemDef.translateX, + l3 + model.modelBaseY / 2 + itemDef.translateYZ, i4 + itemDef.translateYZ); + for (int i5 = 31; i5 >= 0; i5--) { + for (int j4 = 31; j4 >= 0; j4--) + if (enabledSprite.getMyPixels()[i5 + j4 * 32] == 0) + if (i5 > 0 && enabledSprite.getMyPixels()[(i5 - 1) + j4 * 32] > 1) + enabledSprite.getMyPixels()[i5 + j4 * 32] = 1; + else if (j4 > 0 && enabledSprite.getMyPixels()[i5 + (j4 - 1) * 32] > 1) + enabledSprite.getMyPixels()[i5 + j4 * 32] = 1; + else if (i5 < 31 && enabledSprite.getMyPixels()[i5 + 1 + j4 * 32] > 1) + enabledSprite.getMyPixels()[i5 + j4 * 32] = 1; + else if (j4 < 31 && enabledSprite.getMyPixels()[i5 + (j4 + 1) * 32] > 1) + enabledSprite.getMyPixels()[i5 + j4 * 32] = 1; + + } + + if (outlineColor > 0) { + for (int j5 = 31; j5 >= 0; j5--) { + for (int k4 = 31; k4 >= 0; k4--) + if (enabledSprite.getMyPixels()[j5 + k4 * 32] == 0) + if (j5 > 0 && enabledSprite.getMyPixels()[(j5 - 1) + k4 * 32] == 1) + enabledSprite.getMyPixels()[j5 + k4 * 32] = outlineColor; + else if (k4 > 0 && enabledSprite.getMyPixels()[j5 + (k4 - 1) * 32] == 1) + enabledSprite.getMyPixels()[j5 + k4 * 32] = outlineColor; + else if (j5 < 31 && enabledSprite.getMyPixels()[j5 + 1 + k4 * 32] == 1) + enabledSprite.getMyPixels()[j5 + k4 * 32] = outlineColor; + else if (k4 < 31 && enabledSprite.getMyPixels()[j5 + (k4 + 1) * 32] == 1) + enabledSprite.getMyPixels()[j5 + k4 * 32] = outlineColor; + + } + + } else if (outlineColor == 0) { + for (int k5 = 31; k5 >= 0; k5--) { + for (int l4 = 31; l4 >= 0; l4--) + if (enabledSprite.getMyPixels()[k5 + l4 * 32] == 0 && k5 > 0 && l4 > 0 + && enabledSprite.getMyPixels()[(k5 - 1) + (l4 - 1) * 32] > 0) + enabledSprite.getMyPixels()[k5 + l4 * 32] = 0x302020; + + } + + } + if (itemDef.notedItemId != -1) { + int old_w = sprite.getMaxWidth(); + int old_h = sprite.getMaxHeight(); + sprite.setMaxWidth(32); + sprite.setMaxHeight(32); + sprite.drawSprite(0, 0); + sprite.setMaxWidth(old_w); + sprite.setMaxHeight(old_h); + } + if (outlineColor == 0) + sprites.put(enabledSprite, itemId); + Rasterizer2D.initDrawingArea(height, width, pixels, depthBuffer); + Rasterizer2D.setDrawingArea(vp_bottom, vp_left, vp_right, vp_top); + Rasterizer3D.originViewX = centerX; + Rasterizer3D.originViewY = centerY; + Rasterizer3D.scanOffsets = lineOffsets; + Rasterizer3D.aBoolean1464 = true; + if (itemDef.stackable) + enabledSprite.setMaxWidth(33); + else + enabledSprite.setMaxWidth(32); + enabledSprite.setMaxHeight(stackSize); + return enabledSprite; + } + + public Model getModel(int stack_size) { + if (stackVariantId != null && stack_size > 1) { + int stack_item_id = -1; + for (int k = 0; k < 10; k++) + if (stack_size >= stackVariantSize[k] && stackVariantSize[k] != 0) + stack_item_id = stackVariantId[k]; + + if (stack_item_id != -1) + return lookup(stack_item_id).getModel(1); + } + Model model = (Model) models.get(id); + if (model != null) + return model; + model = Model.getModel(inventoryModel); + if (model == null) + return null; + if (modelScaleX != 128 || modelScaleY != 128 || modelScaleZ != 128) + model.scale(modelScaleX, modelScaleZ, modelScaleY); + if (modifiedModelColors != null) { + for (int l = 0; l < modifiedModelColors.length; l++) + model.recolor(modifiedModelColors[l], originalModelColors[l]); + + } + model.light(64 + lightIntensity, 768 + lightMag, -50, -10, -50, true); + model.fits_on_single_square = true; + models.put(model, id); + return model; + } + + public Model getUnshadedModel(int stack_size) { + if (stackVariantId != null && stack_size > 1) { + int stack_item_id = -1; + for (int count = 0; count < 10; count++) + if (stack_size >= stackVariantSize[count] && stackVariantSize[count] != 0) + stack_item_id = stackVariantId[count]; + + if (stack_item_id != -1) + return lookup(stack_item_id).getUnshadedModel(1); + } + Model model = Model.getModel(inventoryModel); + if (model == null) + return null; + if (modifiedModelColors != null) { + for (int colorPtr = 0; colorPtr < modifiedModelColors.length; colorPtr++) + model.recolor(modifiedModelColors[colorPtr], originalModelColors[colorPtr]); + + } + return model; + } + + public static void clear() { + models = null; + sprites = null; + streamIndices = null; + cache = null; + dataBuf = null; + } + + public boolean isDialogueModelCached(int gender) { + int model_1 = equippedMaleModelDialogue1; + int model_2 = equippedMaleModelDialogue2; + if (gender == 1) { + model_1 = equippedFemaleModelDialogue1; + model_2 = equippedFemaleModelDialogue2; + } + if (model_1 == -1) + return true; + boolean cached = true; + if (!Model.isCached(model_1)) + cached = false; + if (model_2 != -1 && !Model.isCached(model_2)) + cached = false; + return cached; + } + + private ItemDefinition() { + id = -1; + } + + private byte equippedFemaleModelTranslationY; + public int value; + public int[] modifiedModelColors; + public int id; + public static ReferenceCache sprites = new ReferenceCache(100); + public static ReferenceCache models = new ReferenceCache(50); + public int[] originalModelColors; + public boolean members; + private int equippedFemaleModel3; + private int notedItemId; + public int equippedFemaleModel2; + public int equippedMaleModel1; + private int equippedMaleModelDialogue2; + private int modelScaleX; + public String groundActions[]; + public int translateX; + public String name; + private static ItemDefinition[] cache; + private int equippedFemaleModelDialogue2; + public int inventoryModel; + public int equippedMaleModelDialogue1; + public boolean stackable; + public String description; + public int unnotedItemId; + private static int cacheIndex; + public int modelZoom; + public static boolean isMembers = true; + private static Buffer dataBuf; + private int lightMag; + private int equippedMaleModel3; + public int equippedMaleModel2; + public String actions[]; + public int rotationY; + private int modelScaleZ; + private int modelScaleY; + public int[] stackVariantId; + public int translateYZ;// + private static int[] streamIndices; + private int lightIntensity; + public int equippedFemaleModelDialogue1; + public int rotationX; + public int equippedFemaleModel1; + public int[] stackVariantSize; + public int team; + public static int itemCount; + public int rotationZ; + private byte equippedMaleModelTranslationY; +} diff --git a/src/main/java/org/rebotted/cache/def/NpcDefinition.java b/src/main/java/org/rebotted/cache/def/NpcDefinition.java new file mode 100644 index 0000000..23bd77d --- /dev/null +++ b/src/main/java/org/rebotted/cache/def/NpcDefinition.java @@ -0,0 +1,544 @@ +package org.rebotted.cache.def; + +import org.rebotted.Client; +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.config.Varbit; +import org.rebotted.collection.ReferenceCache; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; + +/** + * Refactored reference: + * http://www.rune-server.org/runescape-development/rs2-client/downloads/575183-almost-fully-refactored-317-client.html + */ +public final class NpcDefinition { + + public int turn90CCWAnimIndex; + public static int anInt56; + public int varBitID; + public int turn180AnimIndex; + public int settingId; + public static Buffer dataBuf; + public int combatLevel; + public final int anInt64; + public String name; + public String actions[]; + public int walkAnim; + public byte size; + public int[] recolourTarget; + public static int[] offsets; + public int[] aditionalModels; + public int headIcon; + public int[] recolourOriginal; + public int standAnim; + public long interfaceType; + public int degreesToTurn; + public static NpcDefinition[] cache; + public static Client clientInstance; + public int turn90CWAnimIndex; + public boolean clickable; + public int lightModifier; + public int scaleY; + public boolean drawMinimapDot; + public int childrenIDs[]; + public byte description[]; + public int scaleXZ; + public int shadowModifier; + public boolean priorityRender; + public int[] modelId; + public static ReferenceCache modelCache = new ReferenceCache(30); + + public int id; + + /** + * Lookup an NpcDefinition by its id + * @param id + */ + public static NpcDefinition lookup(int id) { + for (int index = 0; index < 20; index++) + if (cache[index].interfaceType == (long) id) + return cache[index]; + + anInt56 = (anInt56 + 1) % 20; + NpcDefinition definition = cache[anInt56] = new NpcDefinition(); + dataBuf.currentPosition = offsets[id]; + definition.interfaceType = id; + definition.id = id; + definition.readValues(dataBuf); + switch(id) { + //Pets + case 495: //Venenatis pet + case 2055: //Chaos ele pet + case 5536: //Vetion pet + case 5537: //Vetion pet + case 497: //Callisto pet + case 5561: //Scorpia pet + case 6626: + case 6627: + case 6628: + case 6629: + case 6630: + case 6631: + case 6632: + case 6633: + case 6634: + case 6635: + definition.actions = new String[] {"Pick-up", null, null, null, null, null, null}; + + //Fix "slide" anim issue + definition.fixSlide(); + + //Callisto size adjust + if(id == 497) { + definition.scaleXZ = 45; + definition.size = 2; + } + + break; + case 2054: + case 6504: + case 6609: + //Fix "slide" anim issue + definition.fixSlide(); + + //Callisto size adjust + if(id == 6609) { + definition.size = 4; + } + + break; + case 995: + definition.recolourOriginal = new int[2]; + definition.recolourTarget = new int[2]; + definition.recolourOriginal[0] = 528; + definition.recolourTarget[0] = 926; + break; + case 7456: + definition.actions = new String[] {"Repairs", null, null, null, null, null, null}; + break; + case 1274: + definition.combatLevel = 35; + break; + case 2660: + definition.combatLevel = 0; + definition.actions = new String[] {"Trade", null, null, null, null, null, null}; + definition.name = "Pker"; + break; + case 6477: + definition.combatLevel = 210; + break; + case 6471: + definition.combatLevel = 131; + break; + case 5816: + definition.combatLevel = 38; + break; + case 100: + definition.drawMinimapDot = true; + break; + case 1306: + definition.actions = new String[] {"Make-over", null, null, null, null, null, null}; + break; + case 3309: + definition.name = "Mage"; + definition.actions = new String[] {"Trade", null, "Equipment", "Runes", null, null, null}; + break; + case 1158: + definition.name = "@or1@Maxed bot"; + definition.combatLevel = 126; + definition.actions = new String[] {null, "Attack", null, null, null, null, null}; + definition.modelId[5] = 268; //platelegs rune + definition.modelId[0] = 18954; //Str cape + definition.modelId[1] = 21873; //Head - neitznot + definition.modelId[8] = 15413; //Shield rune defender + definition.modelId[7] = 5409; // weapon whip + definition.modelId[4] = 13307; //Gloves barrows + definition.modelId[6] = 3704; // boots climbing + definition.modelId[9] = 290; //amulet glory + break; + case 1200: + definition.copy(lookup(1158)); + definition.modelId[7] = 539; // weapon dds + break; + case 4096: + definition.name = "@or1@Archer bot"; + definition.combatLevel = 90; + definition.actions = new String[] {null, "Attack", null, null, null, null, null}; + definition.modelId[0] = 20423; //cape avas + definition.modelId[1] = 21873; //Head - neitznot + definition.modelId[7] = 31237; // weapon crossbow + definition.modelId[4] = 13307; //Gloves barrows + definition.modelId[6] = 3704; // boots climbing + definition.modelId[5] = 20139; //platelegs zammy hides + definition.modelId[2] = 20157; //platebody zammy hides + definition.standAnim = 7220; + definition.walkAnim = 7223; + definition.turn180AnimIndex = 7220; + definition.turn90CCWAnimIndex = 7220; + definition.turn90CWAnimIndex = 7220; + break; + case 1576: + definition.actions = new String[] {"Trade", null, "Equipment", "Ammunition", null, null, null}; + break; + case 3343: + definition.actions = new String[] {"Trade", null, "Heal", null, null, null, null}; + break; + case 506: + case 526: + definition.actions = new String[] {"Trade", null, null, null, null, null, null}; + break; + case 315: + definition.actions = new String[] {"Talk-to", null, "Trade", "Sell Emblems", "Request Skull", null, null}; + break; + + + } + return definition; + } + + private void copy(NpcDefinition copy) { + size = copy.size; + degreesToTurn = copy.degreesToTurn; + walkAnim = copy.walkAnim; + turn180AnimIndex = copy.turn180AnimIndex; + turn90CWAnimIndex = copy.turn90CWAnimIndex; + turn90CCWAnimIndex = copy.turn90CCWAnimIndex; + varBitID = copy.varBitID; + settingId = copy.settingId; + combatLevel = copy.combatLevel; + name = copy.name; + description = copy.description; + headIcon = copy.headIcon; + clickable = copy.clickable; + lightModifier = copy.lightModifier; + scaleY = copy.scaleY; + scaleXZ = copy.scaleXZ; + drawMinimapDot = copy.drawMinimapDot; + shadowModifier = copy.shadowModifier; + actions = new String[copy.actions.length]; + for(int i = 0; i < actions.length; i++) { + actions[i] = copy.actions[i]; + } + modelId = new int[copy.modelId.length]; + for(int i = 0; i < modelId.length; i++) { + modelId[i] = copy.modelId[i]; + } + priorityRender = copy.priorityRender; + } + + private void fixSlide() { + //Fix "slide" anim issue + turn180AnimIndex = walkAnim; + turn90CCWAnimIndex = walkAnim; + turn90CWAnimIndex = walkAnim; + } + + public Model model() { + if (childrenIDs != null) { + NpcDefinition entityDef = morph(); + if (entityDef == null) + return null; + else + return entityDef.model(); + } + if (aditionalModels == null) + return null; + boolean flag1 = false; + for (int index = 0; index < aditionalModels.length; index++) + if (!Model.isCached(aditionalModels[index])) + flag1 = true; + + if (flag1) + return null; + Model models[] = new Model[aditionalModels.length]; + for (int index = 0; index < aditionalModels.length; index++) + models[index] = Model.getModel(aditionalModels[index]); + + Model model; + if (models.length == 1) + model = models[0]; + else + model = new Model(models.length, models); + if (recolourOriginal != null) { + for (int index = 0; index < recolourOriginal.length; index++) + model.recolor(recolourOriginal[index], recolourTarget[index]); + + } + return model; + } + + public NpcDefinition morph() { + int child = -1; + if (varBitID != -1) { + Varbit varBit = Varbit.varbits[varBitID]; + int variable = varBit.getSetting(); + int low = varBit.getLow(); + int high = varBit.getHigh(); + int mask = Client.BIT_MASKS[high - low]; + child = clientInstance.settings[variable] >> low & mask; + } else if (settingId != -1) + child = clientInstance.settings[settingId]; + if (child < 0 || child >= childrenIDs.length + || childrenIDs[child] == -1) + return null; + else + return lookup(childrenIDs[child]); + } + + public static void init(FileArchive archive) { + dataBuf = new Buffer(archive.readFile("npc.dat")); + Buffer idxBuf = new Buffer(archive.readFile("npc.idx")); + + int size = idxBuf.readUShort(); + + offsets = new int[size]; + + int offset = 2; + + for (int count = 0; count < size; count++) { + offsets[count] = offset; + offset += idxBuf.readUShort(); + } + + cache = new NpcDefinition[20]; + + for (int count = 0; count < 20; count++) { + cache[count] = new NpcDefinition(); + } + + System.out.println("Loaded: " + size + " Npcs"); + } + + public static void clear() { + modelCache = null; + offsets = null; + cache = null; + dataBuf = null; + } + + public Model method164(int j, int somethingCurrentAnimsFrameNumber, int ai[], int nextFrame, int idk, + int idk2) { + if (childrenIDs != null) { + NpcDefinition entityDef = morph(); + if (entityDef == null) + return null; + else + return entityDef.method164(j, somethingCurrentAnimsFrameNumber, ai, nextFrame, idk, idk2); + } + Model model = (Model) modelCache.get(interfaceType); + if (model == null) { + boolean flag = false; + for (int i1 = 0; i1 < modelId.length; i1++) + if (!Model.isCached(modelId[i1])) + flag = true; + + if (flag) + return null; + Model models[] = new Model[modelId.length]; + for (int j1 = 0; j1 < modelId.length; j1++) + models[j1] = Model.getModel(modelId[j1]); + + if (models.length == 1) + model = models[0]; + else + model = new Model(models.length, models); + if (recolourOriginal != null) { + for (int k1 = 0; k1 < recolourOriginal.length; k1++) + model.recolor(recolourOriginal[k1], recolourTarget[k1]); + + } + model.skin(); + model.scale(132, 132, 132); + model.light(84 + lightModifier, 1000 + shadowModifier, -90, -580, + -90, true); + modelCache.put(model, interfaceType); + } + Model empty = Model.EMPTY_MODEL; + empty.method464(model, + Frame.noAnimationInProgress(somethingCurrentAnimsFrameNumber) & Frame.noAnimationInProgress(j) + & Frame.noAnimationInProgress(nextFrame)); + if (somethingCurrentAnimsFrameNumber != -1 && j != -1) + empty.applyAnimationFrames(ai, j, somethingCurrentAnimsFrameNumber); + else if (somethingCurrentAnimsFrameNumber != -1 && nextFrame != -1) + empty.applyAnimationFrame(somethingCurrentAnimsFrameNumber, nextFrame, idk, idk2); + else if (somethingCurrentAnimsFrameNumber != -1) + empty.applyTransform(somethingCurrentAnimsFrameNumber); + if (scaleXZ != 128 || scaleY != 128) + empty.scale(scaleXZ, scaleXZ, scaleY); + empty.calculateDistances(); + empty.faceGroups = null; + empty.vertexGroups = null; + if (size == 1) + empty.fits_on_single_square = true; + return empty; + } + + public Model getAnimatedModel(int primaryFrame, int secondaryFrame, + int interleaveOrder[]) { + if (childrenIDs != null) { + NpcDefinition definition = morph(); + if (definition == null) + return null; + else + return definition.getAnimatedModel(primaryFrame, + secondaryFrame, interleaveOrder); + } + Model model = (Model) modelCache.get(interfaceType); + if (model == null) { + boolean flag = false; + for (int index = 0; index < modelId.length; index++) + if (!Model.isCached(modelId[index])) + flag = true; + if (flag) { + return null; + } + Model models[] = new Model[modelId.length]; + for (int index = 0; index < modelId.length; index++) + models[index] = Model.getModel(modelId[index]); + + if (models.length == 1) + model = models[0]; + else + model = new Model(models.length, models); + if (recolourOriginal != null) { + for (int index = 0; index < recolourOriginal.length; index++) + model.recolor(recolourOriginal[index], + recolourTarget[index]); + + } + model.skin(); + model.light(64 + lightModifier, 850 + shadowModifier, -30, -50, + -30, true); + modelCache.put(model, interfaceType); + } + Model model_1 = Model.EMPTY_MODEL; + model_1.method464(model, Frame.noAnimationInProgress(secondaryFrame) + & Frame.noAnimationInProgress(primaryFrame)); + if (secondaryFrame != -1 && primaryFrame != -1) + model_1.applyAnimationFrames(interleaveOrder, primaryFrame, secondaryFrame); + else if (secondaryFrame != -1) + model_1.applyTransform(secondaryFrame); + if (scaleXZ != 128 || scaleY != 128) + model_1.scale(scaleXZ, scaleXZ, scaleY); + model_1.calculateDistances(); + model_1.faceGroups = null; + model_1.vertexGroups = null; + if (size == 1) + model_1.fits_on_single_square = true; + return model_1; + } + + public void readValues(Buffer stream) { + do { + int opcode = stream.readUnsignedByte(); + + if (opcode == 0) + return; + if (opcode == 1) { + int j = stream.readUnsignedByte(); + modelId = new int[j]; + for (int j1 = 0; j1 < j; j1++) + modelId[j1] = stream.readUShort(); + + } else if (opcode == 2) + name = stream.readString(); + else if (opcode == 3) + description = stream.readBytes(); + else if (opcode == 12) + size = stream.readSignedByte(); + else if (opcode == 13) + standAnim = stream.readUShort(); + else if (opcode == 14) + walkAnim = stream.readUShort(); + else if (opcode == 17) { + walkAnim = stream.readUShort(); + turn180AnimIndex = stream.readUShort(); + turn90CWAnimIndex = stream.readUShort(); + turn90CCWAnimIndex = stream.readUShort(); + } else if (opcode >= 30 && opcode < 40) { + if (actions == null) + actions = new String[5]; + actions[opcode - 30] = stream.readString(); + if (actions[opcode - 30].equalsIgnoreCase("hidden")) + actions[opcode - 30] = null; + } else if (opcode == 40) { + int colours = stream.readUnsignedByte(); + recolourOriginal = new int[colours]; + recolourTarget = new int[colours]; + for (int k1 = 0; k1 < colours; k1++) { + recolourOriginal[k1] = stream.readUShort(); + recolourTarget[k1] = stream.readUShort(); + } + + } else if (opcode == 60) { + int additionalModelLen = stream.readUnsignedByte(); + aditionalModels = new int[additionalModelLen]; + for (int l1 = 0; l1 < additionalModelLen; l1++) + aditionalModels[l1] = stream.readUShort(); + + } else if (opcode == 90) + stream.readUShort(); + else if (opcode == 91) + stream.readUShort(); + else if (opcode == 92) + stream.readUShort(); + else if (opcode == 93) + drawMinimapDot = false; + else if (opcode == 95) + combatLevel = stream.readUShort(); + else if (opcode == 97) + scaleXZ = stream.readUShort(); + else if (opcode == 98) + scaleY = stream.readUShort(); + else if (opcode == 99) + priorityRender = true; + else if (opcode == 100) + lightModifier = stream.readSignedByte(); + else if (opcode == 101) + shadowModifier = stream.readSignedByte() * 5; + else if (opcode == 102) + headIcon = stream.readUShort(); + else if (opcode == 103) + degreesToTurn = stream.readUShort(); + else if (opcode == 106) { + varBitID = stream.readUShort(); + if (varBitID == 65535) + varBitID = -1; + settingId = stream.readUShort(); + if (settingId == 65535) + settingId = -1; + int childCount = stream.readUnsignedByte(); + childrenIDs = new int[childCount + 1]; + for (int i2 = 0; i2 <= childCount; i2++) { + childrenIDs[i2] = stream.readUShort(); + if (childrenIDs[i2] == 65535) + childrenIDs[i2] = -1; + } + + } else if (opcode == 107) + clickable = false; + } while (true); + } + + public NpcDefinition() { + turn90CCWAnimIndex = -1; + varBitID = -1; + turn180AnimIndex = -1; + settingId = -1; + combatLevel = -1; + anInt64 = 1834; + walkAnim = -1; + size = 1; + headIcon = -1; + standAnim = -1; + interfaceType = -1L; + degreesToTurn = 32; + turn90CWAnimIndex = -1; + clickable = true; + scaleY = 128; + drawMinimapDot = true; + scaleXZ = 128; + priorityRender = false; + } +} diff --git a/src/main/java/org/rebotted/cache/def/ObjectDefBack.java b/src/main/java/org/rebotted/cache/def/ObjectDefBack.java new file mode 100644 index 0000000..ed7c23a --- /dev/null +++ b/src/main/java/org/rebotted/cache/def/ObjectDefBack.java @@ -0,0 +1,505 @@ +package org.rebotted.cache.def; + +import org.rebotted.Client; +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.config.Varbit; +import org.rebotted.collection.ReferenceCache; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; +import org.rebotted.net.requester.ResourceProvider; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; + +public final class ObjectDefBack { + + public static final Model[] aModelArray741s = new Model[4]; + public static boolean lowMemory; + public static Buffer dataBuf; + public static int[] streamIndices; + public static Client clientInstance; + public static int cacheIndex; + public static ReferenceCache models = new ReferenceCache(30); + public static ObjectDefinition[] cache; + public static ReferenceCache baseModels = new ReferenceCache(500); + private static int totalObjects; + public boolean obstructsGround; + public byte ambientLighting; + public int translateX; + public String name; + public int scaleZ; + public byte lightDiffusion; + public int objectSizeX; + public int translateY; + public int minimapFunction; + public int[] originalModelColors; + public int scaleX; + public int varp; + public boolean inverted; + public int type; + public boolean impenetrable; + public int mapscene; + public int[] childrenIDs; + public int supportItems; + public int objectSizeY; + public boolean contouredGround; + public boolean occludes; + public boolean hollow; + public boolean solid; + public int surroundings; + public boolean delayShading; + public int scaleY; + public int[] modelIds; + public int varbit; + public int decorDisplacement; + public int[] modelTypes; + public byte[] description; + public boolean isInteractive; + public boolean castsShadow; + public int animation; + public int translateZ; + public int[] modifiedModelColors; + public String[] interactions; + private short[] originalTexture; + private short[] modifiedTexture; + + + public static void init(FileArchive streamLoader) throws IOException { + dataBuf = new Buffer(streamLoader.readFile("loc.dat")); + Buffer idxBuf = new Buffer(streamLoader.readFile("loc.idx")); + totalObjects = idxBuf.readUShort(); + streamIndices = new int[totalObjects]; + int offset = 2; + for (int index = 0; index < totalObjects; index++) { + streamIndices[index] = offset; + offset += idxBuf.readUShort(); + } + cache = new ObjectDefinition[20]; + for (int index = 0; index < 20; index++) { + cache[index] = new ObjectDefinition(); + } + +// for(int i = 0; i < totalObjects; i++) { +// ObjectDefinition def = ObjectDefinition.lookup(i); +// +// if (def == null || def.name == null) { +// continue; +// } +// +// System.out.println(i + " " + def.name); +// +// } + + System.out.println("Loaded: " + totalObjects + " Objects"); + } + + public static void dumpNames() throws Exception { + BufferedWriter writer = new BufferedWriter(new FileWriter("./Cache/object_names.txt")); + for (int i = 0; i < totalObjects; i++) { + ObjectDefinition def = lookup(i); + String name = def == null ? "null" : def.name; + writer.write("ID: " + i + ", name: " + name + ""); + writer.newLine(); + } + writer.close(); + } + + public static ObjectDefinition lookup(int id) { + if (id > streamIndices.length) { + id = streamIndices.length - 1; + } + for (int index = 0; index < 20; index++) { + if (cache[index].type == id) { + return cache[index]; + } + } + + cacheIndex = (cacheIndex + 1) % 20; + ObjectDefinition def = cache[cacheIndex]; + dataBuf.currentPosition = streamIndices[id]; + def.type = id; + def.reset(); + //def.decode(dataBuf); + + //Disable delayed shading. + //Cheap fix for: edgeville ditch, raids, wintertodt fire etc + //Fixes black square on the model + def.delayShading = false; + return def; + } + + public static void clear() { + baseModels = null; + models = null; + streamIndices = null; + cache = null; + dataBuf = null; + } + + private void decode(Buffer stream) { + while (true) { + int flag = -1; + + int type = stream.readUnsignedByte(); + + if (type == 0) { + break; + } else if (type == 1) { + int length = stream.readUnsignedByte(); + if (length > 0) { + if (modelIds == null || lowMemory) { + modelTypes = new int[length]; + modelIds = new int[length]; + for (int i = 0; i < length; i++) { + modelIds[i] = stream.readUShort(); + modelTypes[i] = stream.readUnsignedByte(); + } + } else { + stream.currentPosition += length * 3; + } + } + } else if (type == 2) { + name = stream.readString(); + } else if (type == 3) { + description = stream.readBytes(); + } else if (type == 5) { + int len = stream.readUnsignedByte(); + if (len > 0) { + if (modelIds == null || lowMemory) { + modelTypes = null; + modelIds = new int[len]; + for (int l1 = 0; l1 < len; l1++) + modelIds[l1] = stream.readUShort(); + } else { + stream.currentPosition += len * 2; + } + } + } else if (type == 14) { + objectSizeX = stream.readUnsignedByte(); + } else if (type == 15) { + objectSizeY = stream.readUnsignedByte(); + } else if (type == 17) { + solid = false; + } else if (type == 18) { + impenetrable = false; + } else if (type == 19) { + isInteractive = (stream.readUnsignedByte() == 1); + } else if (type == 21) { + contouredGround = true; + } else if (type == 22) { + delayShading = false; + } else if (type == 23) { + occludes = true; + } else if (type == 24) { + animation = stream.readUShort(); + if (animation == 65535) + animation = -1; + } else if (type == 28) { + decorDisplacement = stream.readUnsignedByte(); + } else if (type == 29) { + ambientLighting = stream.readSignedByte(); + } else if (type == 39) { + lightDiffusion = stream.readSignedByte(); + } else if (type >= 30 && type < 39) { + if (interactions == null) { + interactions = new String[5]; + } + if(type - 30 < 6) { + interactions[type - 30] = stream.readString(); + if (interactions[type - 30].equalsIgnoreCase("hidden")) { + interactions[type - 30] = null; + } + } + + } else if (type == 40) { + int i1 = stream.readUnsignedByte(); + modifiedModelColors = new int[i1]; + originalModelColors = new int[i1]; + for (int i2 = 0; i2 < i1; i2++) { + modifiedModelColors[i2] = stream.readUShort(); + originalModelColors[i2] = stream.readUShort(); + } + } else if (type == 60) { + minimapFunction = stream.readUShort(); + } else if (type == 62) { + inverted = true; + } else if (type == 64) { + castsShadow = false; + } else if (type == 65) { + scaleX = stream.readUShort(); + } else if (type == 66) { + scaleY = stream.readUShort(); + } else if (type == 67) { + scaleZ = stream.readUShort(); + } else if (type == 68) { + mapscene = stream.readUShort(); + } else if (type == 69) { + surroundings = stream.readUnsignedByte(); + } else if (type == 70) { + translateX = stream.readSignedWord(); + } else if (type == 71) { + translateY = stream.readSignedWord(); + } else if (type == 72) { + translateZ = stream.readSignedWord(); + } else if (type == 73) { + obstructsGround = true; + } else if (type == 74) { + hollow = true; + } else if(type == 75) { + supportItems = dataBuf.readUnsignedByte(); + } else if (type == 77) { + varp = stream.readUShort(); + if (varp == 65535) { + varp = -1; + } + varbit = stream.readUShort(); + if (varbit == 65535) { + varbit = -1; + } + int length = stream.readUnsignedByte(); + childrenIDs = new int[length]; + for (int i = 0; i < length; i++) { + childrenIDs[i] = stream.readUShort(); + if (childrenIDs[i] == 65535) { + childrenIDs[i] = -1; + } + } + } + + if (flag == -1 && name != "null" && name != null) { + isInteractive = modelIds != null + && (modelTypes == null || modelTypes[0] == 10); + if (interactions != null) + isInteractive = true; + } + if (hollow) { + solid = false; + impenetrable = false; + } + if (supportItems == -1) + supportItems = solid ? 1 : 0; + } + + } + public void reset() { + modelIds = null; + modelTypes = null; + name = null; + description = null; + modifiedModelColors = null; + originalModelColors = null; + objectSizeX = 1; + objectSizeY = 1; + solid = true; + impenetrable = true; + isInteractive = false; + contouredGround = false; + delayShading = false; + occludes = false; + animation = -1; + decorDisplacement = 16; + ambientLighting = 0; + lightDiffusion = 0; + interactions = null; + minimapFunction = -1; + mapscene = -1; + inverted = false; + castsShadow = true; + scaleX = 128; + scaleY = 128; + scaleZ = 128; + surroundings = 0; + translateX = 0; + translateY = 0; + translateZ = 0; + obstructsGround = false; + hollow = false; + supportItems = -1; + varbit = -1; + varp = -1; + childrenIDs = null; + } + + public void loadModels(ResourceProvider archive) { + if (modelIds == null) + return; + for (int index = 0; index < modelIds.length; index++) + archive.loadExtra(modelIds[index] & 0xffff, 0); + } + + public boolean method577(int i) { + if (modelTypes == null) { + if (modelIds == null) + return true; + if (i != 10) + return true; + boolean flag1 = true; + for (int k = 0; k < modelIds.length; k++) + flag1 &= Model.isCached(modelIds[k] & 0xffff); + + return flag1; + } + for (int j = 0; j < modelTypes.length; j++) + if (modelTypes[j] == i) + return Model.isCached(modelIds[j] & 0xffff); + + return true; + } + + public Model modelAt(int type, int orientation, int aY, int bY, int cY, int dY, int frameId) { + Model model = model(type, frameId, orientation); + if (model == null) + return null; + if (contouredGround || delayShading) + model = new Model(contouredGround, delayShading, model); + if (contouredGround) { + int y = (aY + bY + cY + dY) / 4; + for (int vertex = 0; vertex < model.numVertices; vertex++) { + int x = model.vertexX[vertex]; + int z = model.vertexZ[vertex]; + int l2 = aY + ((bY - aY) * (x + 64)) / 128; + int i3 = dY + ((cY - dY) * (x + 64)) / 128; + int j3 = l2 + ((i3 - l2) * (z + 64)) / 128; + model.vertexY[vertex] += j3 - y; + } + + model.computeSphericalBounds(); + } + + return model; + } + + public boolean method579() { + if (modelIds == null) + return true; + boolean flag1 = true; + for (int i = 0; i < modelIds.length; i++) + flag1 &= Model.isCached(modelIds[i] & 0xffff); + return flag1; + } + + public ObjectDefinition method580() { + int i = -1; + if (varbit != -1) { + Varbit varBit = Varbit.varbits[varbit]; + int j = varBit.getSetting(); + int k = varBit.getLow(); + int l = varBit.getHigh(); + int i1 = Client.BIT_MASKS[l - k]; + i = clientInstance.settings[j] >> k & i1; + } else if (varp != -1) + i = clientInstance.settings[varp]; + if (i < 0 || i >= childrenIDs.length || childrenIDs[i] == -1) + return null; + else + return lookup(childrenIDs[i]); + } + + public Model model(int j, int k, int l) { + Model model = null; + long l1; + if (modelTypes == null) { + if (j != 10) + return null; + l1 = (long) ((type << 6) + l) + ((long) (k + 1) << 32); + Model model_1 = (Model) models.get(l1); + if (model_1 != null) { + return model_1; + } + if (modelIds == null) + return null; + boolean flag1 = inverted ^ (l > 3); + int k1 = modelIds.length; + for (int i2 = 0; i2 < k1; i2++) { + int l2 = modelIds[i2]; + if (flag1) + l2 += 0x10000; + model = (Model) baseModels.get(l2); + if (model == null) { + model = Model.getModel(l2 & 0xffff); + if (model == null) + return null; + if (flag1) + model.method477(); + baseModels.put(model, l2); + } + if (k1 > 1) + aModelArray741s[i2] = model; + } + + if (k1 > 1) + model = new Model(k1, aModelArray741s); + } else { + int i1 = -1; + for (int j1 = 0; j1 < modelTypes.length; j1++) { + if (modelTypes[j1] != j) + continue; + i1 = j1; + break; + } + + if (i1 == -1) + return null; + l1 = (long) ((type << 8) + (i1 << 3) + l) + ((long) (k + 1) << 32); + Model model_2 = (Model) models.get(l1); + if (model_2 != null) { + return model_2; + } + if (modelIds == null) { + return null; + } + int j2 = modelIds[i1]; + boolean flag3 = inverted ^ (l > 3); + if (flag3) + j2 += 0x10000; + model = (Model) baseModels.get(j2); + if (model == null) { + model = Model.getModel(j2 & 0xffff); + if (model == null) + return null; + if (flag3) + model.method477(); + baseModels.put(model, j2); + } + } + boolean flag; + flag = scaleX != 128 || scaleY != 128 || scaleZ != 128; + boolean flag2; + flag2 = translateX != 0 || translateY != 0 || translateZ != 0; + Model model_3 = new Model(modifiedModelColors == null, + Frame.noAnimationInProgress(k), l == 0 && k == -1 && !flag + && !flag2, model); + if (k != -1) { + model_3.skin(); + model_3.applyTransform(k); + model_3.faceGroups = null; + model_3.vertexGroups = null; + } + while (l-- > 0) + model_3.rotate90Degrees(); + if (modifiedModelColors != null) { + for (int k2 = 0; k2 < modifiedModelColors.length; k2++) + model_3.recolor(modifiedModelColors[k2], + originalModelColors[k2]); + + } + /* if (modifiedTexture != null) { + for (int k2 = 0; k2 < modifiedTexture.length; k2++) + model_3.retexture(modifiedTexture[k2], originalTexture[k2], + -1); + }*/ + if (flag) + model_3.scale(scaleX, scaleZ, scaleY); + if (flag2) + model_3.translate(translateX, translateY, translateZ); + // model_3.light(84, 1500, -90, -280, -70, !delayShading); + model_3.light(64 + ambientLighting, 1300 + (lightDiffusion * 5), -90, -280, -70, !delayShading); + if (supportItems == 1) + model_3.itemDropHeight = model_3.modelBaseY; + models.put(model_3, l1); + return model_3; + } + +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/cache/def/ObjectDefinition.java b/src/main/java/org/rebotted/cache/def/ObjectDefinition.java new file mode 100644 index 0000000..22d2f7e --- /dev/null +++ b/src/main/java/org/rebotted/cache/def/ObjectDefinition.java @@ -0,0 +1,523 @@ +package org.rebotted.cache.def; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; + +import org.rebotted.Client; +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.config.Varbit; +import org.rebotted.collection.ReferenceCache; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; +import org.rebotted.net.requester.ResourceProvider; + +public final class ObjectDefinition { + + public static void init(FileArchive streamLoader) throws IOException { + dataBuf = new Buffer(streamLoader.readFile("loc.dat")); + Buffer idxBuf = new Buffer(streamLoader.readFile("loc.idx")); + totalObjects = idxBuf.readUShort(); + streamIndices = new int[totalObjects]; + int offset = 2; + for (int index = 0; index < totalObjects; index++) { + streamIndices[index] = offset; + offset += idxBuf.readUShort(); + } + cache = new ObjectDefinition[20]; + for (int index = 0; index < 20; index++) { + cache[index] = new ObjectDefinition(); + } + +// for(int i = 0; i < totalObjects; i++) { +// ObjectDefinition def = ObjectDefinition.lookup(i); +// +// if (def == null || def.name == null) { +// continue; +// } +// +// System.out.println(i + " " + def.name); +// +// } + + System.out.println("Loaded: " + totalObjects + " Objects"); + } + + private void decode(Buffer stream, int id) { + try { + while (true) { + int flag = -1; + + int type = stream.readUnsignedByte(); + + if (type == 0) { + break; + } else if (type == 1) { + int length = stream.readUnsignedByte(); + if (length > 0) { + if (modelIds == null || lowMemory) { + modelTypes = new int[length]; + modelIds = new int[length]; + for (int i = 0; i < length; i++) { + modelIds[i] = stream.readUShort(); + modelTypes[i] = stream.readUnsignedByte(); + } + } else { + stream.currentPosition += length * 3; + } + } + } else if (type == 2) { + name = stream.readString(); + } else if (type == 3) { + description = stream.readBytes(); + } else if (type == 5) { + int len = stream.readUnsignedByte(); + if (len > 0) { + if (modelIds == null || lowMemory) { + modelTypes = null; + modelIds = new int[len]; + for (int l1 = 0; l1 < len; l1++) + modelIds[l1] = stream.readUShort(); + } else { + stream.currentPosition += len * 2; + } + } + } else if (type == 14) { + objectSizeX = stream.readUnsignedByte(); + } else if (type == 15) { + objectSizeY = stream.readUnsignedByte(); + } else if (type == 17) { + solid = false; + } else if (type == 18) { + impenetrable = false; + } else if (type == 19) { + isInteractive = (stream.readUnsignedByte() == 1); + } else if (type == 21) { + contouredGround = true; + } else if (type == 22) { + delayShading = false; + } else if (type == 23) { + occludes = true; + } else if (type == 24) { + animation = stream.readUShort(); + if (animation == 65535) + animation = -1; + } else if (type == 28) { + decorDisplacement = stream.readUnsignedByte(); + } else if (type == 29) { + ambientLighting = stream.readSignedByte(); + } else if (type == 39) { + lightDiffusion = stream.readSignedByte(); + } else if (type >= 30 && type < 39) { + if (interactions == null) { + interactions = new String[5]; + } + interactions[type - 30] = stream.readString(); + if (interactions[type - 30].equalsIgnoreCase("hidden")) { + interactions[type - 30] = null; + } + + } else if (type == 40) { + int i1 = stream.readUnsignedByte(); + modifiedModelColors = new int[i1]; + originalModelColors = new int[i1]; + for (int i2 = 0; i2 < i1; i2++) { + modifiedModelColors[i2] = stream.readUShort(); + originalModelColors[i2] = stream.readUShort(); + } + } else if (type == 60) { + minimapFunction = stream.readUShort(); + } else if (type == 62) { + inverted = true; + } else if (type == 64) { + castsShadow = false; + } else if (type == 65) { + scaleX = stream.readUShort(); + } else if (type == 66) { + scaleY = stream.readUShort(); + } else if (type == 67) { + scaleZ = stream.readUShort(); + } else if (type == 68) { + mapscene = stream.readUShort(); + } else if (type == 69) { + surroundings = stream.readUnsignedByte(); + } else if (type == 70) { + translateX = stream.readSignedWord(); + } else if (type == 71) { + translateY = stream.readSignedWord(); + } else if (type == 72) { + translateZ = stream.readSignedWord(); + } else if (type == 73) { + obstructsGround = true; + } else if (type == 74) { + hollow = true; + } else if (type == 75) { + supportItems = dataBuf.readUnsignedByte(); + } else if (type == 77) { + varp = stream.readUShort(); + if (varp == 65535) { + varp = -1; + } + varbit = stream.readUShort(); + if (varbit == 65535) { + varbit = -1; + } + int length = stream.readUnsignedByte(); + childrenIDs = new int[length]; + for (int i = 0; i < length; i++) { + childrenIDs[i] = stream.readUShort(); + if (childrenIDs[i] == 65535) { + childrenIDs[i] = -1; + } + } + } + + if (flag == -1 && name != "null" && name != null) { + isInteractive = modelIds != null + && (modelTypes == null || modelTypes[0] == 10); + if (interactions != null) + isInteractive = true; + } + if (hollow) { + solid = false; + impenetrable = false; + } + if (supportItems == -1) + supportItems = solid ? 1 : 0; + } + } catch (Exception e) { + System.err.println("ERROR LOADING: "+id); + } + } + public boolean obstructsGround; + public byte ambientLighting; + public int translateX; + public String name; + public int scaleZ; + public static final Model[] aModelArray741s = new Model[4]; + public byte lightDiffusion; + public int objectSizeX; + public int translateY; + public int minimapFunction; + public int[] originalModelColors; + public int scaleX; + public int varp; + public boolean inverted; + public static boolean lowMemory; + public static Buffer dataBuf; + public int type; + public static int[] streamIndices; + public boolean impenetrable; + public int mapscene; + public int childrenIDs[]; + public int supportItems; + public int objectSizeY; + public boolean contouredGround; + public boolean occludes; + public static Client clientInstance; + public boolean hollow; + public boolean solid; + public int surroundings; + public boolean delayShading; + public static int cacheIndex; + public int scaleY; + public int[] modelIds; + public int varbit; + public int decorDisplacement; + public int[] modelTypes; + public byte[] description; + public boolean isInteractive; + public boolean castsShadow; + public static ReferenceCache models = new ReferenceCache(30); + public int animation; + public static ObjectDefinition[] cache; + public int translateZ; + public int[] modifiedModelColors; + public static ReferenceCache baseModels = new ReferenceCache(500); + public String interactions[]; + + private short[] originalTexture; + private short[] modifiedTexture; + + public ObjectDefinition() { + type = -1; + } + + public static void dumpNames() throws Exception { + BufferedWriter writer = new BufferedWriter(new FileWriter("./Cache/object_names.txt")); + for(int i = 0; i < totalObjects; i++) { + ObjectDefinition def = lookup(i); + String name = def == null ? "null" : def.name; + writer.write("ID: "+i+", name: "+name+""); + writer.newLine(); + } + writer.close(); + } + + public static ObjectDefinition lookup(int id) { + if (id > streamIndices.length) { + id = streamIndices.length - 1; + } + switch (id) { + case 9251: + id = 5790; + break; + } + for (int index = 0; index < 20; index++) { + if (cache[index].type == id) { + return cache[index]; + } + } + + cacheIndex = (cacheIndex + 1) % 20; + ObjectDefinition def = cache[cacheIndex]; + dataBuf.currentPosition = streamIndices[id]; + def.type = id; + def.reset(); + def.decode(dataBuf, id); + switch (id) { + case 6: + def.interactions[1] = "Load"; + def.interactions[2] = "Pick-up"; + break; + } + + //Disable delayed shading. + //Cheap fix for: edgeville ditch, raids, wintertodt fire etc + //Fixes black square on the model + def.delayShading = false; + return def; + } + + public void reset() { + modelIds = null; + modelTypes = null; + name = null; + description = null; + modifiedModelColors = null; + originalModelColors = null; + objectSizeX = 1; + objectSizeY = 1; + solid = true; + impenetrable = true; + isInteractive = false; + contouredGround = false; + delayShading = false; + occludes = false; + animation = -1; + decorDisplacement = 16; + ambientLighting = 0; + lightDiffusion = 0; + interactions = null; + minimapFunction = -1; + mapscene = -1; + inverted = false; + castsShadow = true; + scaleX = 128; + scaleY = 128; + scaleZ = 128; + surroundings = 0; + translateX = 0; + translateY = 0; + translateZ = 0; + obstructsGround = false; + hollow = false; + supportItems = -1; + varbit = -1; + varp = -1; + childrenIDs = null; + } + + public void loadModels(ResourceProvider archive) { + if (modelIds == null) + return; + for (int index = 0; index < modelIds.length; index++) + archive.loadExtra(modelIds[index] & 0xffff, 0); + } + + public static void clear() { + baseModels = null; + models = null; + streamIndices = null; + cache = null; + dataBuf = null; + } + + private static int totalObjects; + + public boolean method577(int i) { + if (modelTypes == null) { + if (modelIds == null) + return true; + if (i != 10) + return true; + boolean flag1 = true; + for (int k = 0; k < modelIds.length; k++) + flag1 &= Model.isCached(modelIds[k] & 0xffff); + + return flag1; + } + for (int j = 0; j < modelTypes.length; j++) + if (modelTypes[j] == i) + return Model.isCached(modelIds[j] & 0xffff); + + return true; + } + + public Model modelAt(int type, int orientation, int aY, int bY, int cY, int dY, int frameId) { + Model model = model(type, frameId, orientation); + if (model == null) + return null; + if (contouredGround || delayShading) + model = new Model(contouredGround, delayShading, model); + if (contouredGround) { + int y = (aY + bY + cY + dY) / 4; + for (int vertex = 0; vertex < model.numVertices; vertex++) { + int x = model.vertexX[vertex]; + int z = model.vertexZ[vertex]; + int l2 = aY + ((bY - aY) * (x + 64)) / 128; + int i3 = dY + ((cY - dY) * (x + 64)) / 128; + int j3 = l2 + ((i3 - l2) * (z + 64)) / 128; + model.vertexY[vertex] += j3 - y; + } + + model.computeSphericalBounds(); + } + + return model; + } + + public boolean method579() { + if (modelIds == null) + return true; + boolean flag1 = true; + for (int i = 0; i < modelIds.length; i++) { + flag1 &= Model.isCached(modelIds[i] & 0xffff); + } + return flag1; + } + + public ObjectDefinition method580() { + int i = -1; + if (varbit != -1) { + Varbit varBit = Varbit.varbits[varbit]; + int j = varBit.getSetting(); + int k = varBit.getLow(); + int l = varBit.getHigh(); + int i1 = Client.BIT_MASKS[l - k]; + i = clientInstance.settings[j] >> k & i1; + } else if (varp != -1) + i = clientInstance.settings[varp]; + if (i < 0 || i >= childrenIDs.length || childrenIDs[i] == -1) + return null; + else + return lookup(childrenIDs[i]); + } + + public Model model(int j, int k, int l) { + Model model = null; + long l1; + if (modelTypes == null) { + if (j != 10) + return null; + l1 = (long) ((type << 6) + l) + ((long) (k + 1) << 32); + Model model_1 = (Model) models.get(l1); + if (model_1 != null) { + return model_1; + } + if (modelIds == null) + return null; + boolean flag1 = inverted ^ (l > 3); + int k1 = modelIds.length; + for (int i2 = 0; i2 < k1; i2++) { + int l2 = modelIds[i2]; + if (flag1) + l2 += 0x10000; + model = (Model) baseModels.get(l2); + if (model == null) { + model = Model.getModel(l2 & 0xffff); + if (model == null) + return null; + if (flag1) + model.method477(); + baseModels.put(model, l2); + } + if (k1 > 1) + aModelArray741s[i2] = model; + } + + if (k1 > 1) + model = new Model(k1, aModelArray741s); + } else { + int i1 = -1; + for (int j1 = 0; j1 < modelTypes.length; j1++) { + if (modelTypes[j1] != j) + continue; + i1 = j1; + break; + } + + if (i1 == -1) + return null; + l1 = (long) ((type << 8) + (i1 << 3) + l) + ((long) (k + 1) << 32); + Model model_2 = (Model) models.get(l1); + if (model_2 != null) { + return model_2; + } + if(modelIds == null) { + return null; + } + int j2 = modelIds[i1]; + boolean flag3 = inverted ^ (l > 3); + if (flag3) + j2 += 0x10000; + model = (Model) baseModels.get(j2); + if (model == null) { + model = Model.getModel(j2 & 0xffff); + if (model == null) + return null; + if (flag3) + model.method477(); + baseModels.put(model, j2); + } + } + boolean flag; + flag = scaleX != 128 || scaleY != 128 || scaleZ != 128; + boolean flag2; + flag2 = translateX != 0 || translateY != 0 || translateZ != 0; + Model model_3 = new Model(modifiedModelColors == null, + Frame.noAnimationInProgress(k), l == 0 && k == -1 && !flag + && !flag2, model); + if (k != -1) { + model_3.skin(); + model_3.applyTransform(k); + model_3.faceGroups = null; + model_3.vertexGroups = null; + } + while (l-- > 0) + model_3.rotate90Degrees(); + if (modifiedModelColors != null) { + for (int k2 = 0; k2 < modifiedModelColors.length; k2++) + model_3.recolor(modifiedModelColors[k2], + originalModelColors[k2]); + + } + /* if (modifiedTexture != null) { + for (int k2 = 0; k2 < modifiedTexture.length; k2++) + model_3.retexture(modifiedTexture[k2], originalTexture[k2], + -1); + }*/ + if (flag) + model_3.scale(scaleX, scaleZ, scaleY); + if (flag2) + model_3.translate(translateX, translateY, translateZ); + // model_3.light(84, 1500, -90, -280, -70, !delayShading); + model_3.light(64 + ambientLighting, 1300 + (lightDiffusion * 5), -90, -280, -70, !delayShading); + if (supportItems == 1) + model_3.itemDropHeight = model_3.modelBaseY; + models.put(model_3, l1); + return model_3; + } + +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/cache/graphics/GameFont.java b/src/main/java/org/rebotted/cache/graphics/GameFont.java new file mode 100644 index 0000000..71741c7 --- /dev/null +++ b/src/main/java/org/rebotted/cache/graphics/GameFont.java @@ -0,0 +1,415 @@ +package org.rebotted.cache.graphics; + +import java.util.Random; + +import org.rebotted.cache.FileArchive; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.io.Buffer; + +public final class GameFont extends Rasterizer2D { + + public GameFont(boolean flag, String s, FileArchive streamLoader) { + aByteArrayArray1491 = new byte[256][]; + anIntArray1492 = new int[256]; + anIntArray1493 = new int[256]; + anIntArray1494 = new int[256]; + anIntArray1495 = new int[256]; + anIntArray1496 = new int[256]; + aRandom1498 = new Random(); + aBoolean1499 = false; + Buffer stream = new Buffer(streamLoader.readFile(s + ".dat")); + Buffer stream_1 = new Buffer(streamLoader.readFile("index.dat")); + stream_1.currentPosition = stream.readUShort() + 4; + int k = stream_1.readUnsignedByte(); + if(k > 0) + stream_1.currentPosition += 3 * (k - 1); + for(int l = 0; l < 256; l++) { + anIntArray1494[l] = stream_1.readUnsignedByte(); + anIntArray1495[l] = stream_1.readUnsignedByte(); + int i1 = anIntArray1492[l] = stream_1.readUShort(); + int j1 = anIntArray1493[l] = stream_1.readUShort(); + int k1 = stream_1.readUnsignedByte(); + int l1 = i1 * j1; + aByteArrayArray1491[l] = new byte[l1]; + if(k1 == 0) { + for(int i2 = 0; i2 < l1; i2++) + aByteArrayArray1491[l][i2] = stream.readSignedByte(); + + } else if(k1 == 1) { + for(int j2 = 0; j2 < i1; j2++) { + for(int l2 = 0; l2 < j1; l2++) + aByteArrayArray1491[l][j2 + l2 * i1] = stream.readSignedByte(); + } + } + if(j1 > verticalSpace && l < 128) + verticalSpace = j1; + anIntArray1494[l] = 1; + anIntArray1496[l] = i1 + 2; + int k2 = 0; + for(int i3 = j1 / 7; i3 < j1; i3++) + k2 += aByteArrayArray1491[l][i3 * i1]; + if(k2 <= j1 / 7) { + anIntArray1496[l]--; + anIntArray1494[l] = 0; + } + k2 = 0; + for(int j3 = j1 / 7; j3 < j1; j3++) + k2 += aByteArrayArray1491[l][(i1 - 1) + j3 * i1]; + if(k2 <= j1 / 7) + anIntArray1496[l]--; + } + if(flag) { + anIntArray1496[32] = anIntArray1496[73]; + } else { + anIntArray1496[32] = anIntArray1496[105]; + } + } + + public void method380(String s, int i, int j, int k) { + render(j, s, k, i - method384(s)); + } + + public void drawText(int i, String s, int k, int l) { + render(i, s, k, l - method384(s) / 2); + } + + public void method382(int i, int j, String s, int l, boolean flag) { + drawTextWithPotentialShadow(flag, j - getTextWidth(s) / 2, i, s, l); + } + + public void drawChatInput(int i, int j, String s, int l, boolean flag) { + drawTextWithPotentialShadow(flag, j, i, s, l); + } + + public int getTextWidth(String s) { + if(s == null) + return 0; + int j = 0; + for(int k = 0; k < s.length(); k++) + if(s.charAt(k) == '@' && k + 4 < s.length() && s.charAt(k + 4) == '@') + k += 4; + else + j += anIntArray1496[s.charAt(k)]; + return j; + } + + public int method384(String s) { + if(s == null) + return 0; + int j = 0; + for(int k = 0; k < s.length(); k++) + j += anIntArray1496[s.charAt(k)]; + return j; + } + + public void render(int i, String s, int j, int l) { + if(s == null) + return; + j -= verticalSpace; + for(int i1 = 0; i1 < s.length(); i1++) { + char c = s.charAt(i1); + if(c != ' ') + method392(aByteArrayArray1491[c], l + anIntArray1494[c], j + anIntArray1495[c], anIntArray1492[c], anIntArray1493[c], i); + l += anIntArray1496[c]; + } + } + + public void wave(int i, String s, int j, int k, int l) { + if(s == null) + return; + j -= method384(s) / 2; + l -= verticalSpace; + for(int i1 = 0; i1 < s.length(); i1++) { + char c = s.charAt(i1); + if(c != ' ') + method392(aByteArrayArray1491[c], j + anIntArray1494[c], l + anIntArray1495[c] + (int)(Math.sin((double)i1 / 2D + (double)k / 5D) * 5D), anIntArray1492[c], anIntArray1493[c], i); + j += anIntArray1496[c]; + } + } + + public void wave2(int i, String s, int j, int k, int l) { + if(s == null) + return; + i -= method384(s) / 2; + k -= verticalSpace; + for(int i1 = 0; i1 < s.length(); i1++) { + char c = s.charAt(i1); + if(c != ' ') + method392(aByteArrayArray1491[c], i + anIntArray1494[c] + (int)(Math.sin((double)i1 / 5D + (double)j / 5D) * 5D), k + anIntArray1495[c] + (int)(Math.sin((double)i1 / 3D + (double)j / 5D) * 5D), anIntArray1492[c], anIntArray1493[c], l); + i += anIntArray1496[c]; + } + } + + public void shake(int i, String s, int j, int k, int l, int i1) { + if(s == null) + return; + double d = 7D - (double)i / 8D; + if(d < 0.0D) + d = 0.0D; + l -= method384(s) / 2; + k -= verticalSpace; + for(int k1 = 0; k1 < s.length(); k1++) { + char c = s.charAt(k1); + if(c != ' ') + method392(aByteArrayArray1491[c], l + anIntArray1494[c], k + anIntArray1495[c] + (int)(Math.sin((double)k1 / 1.5D + (double)j) * d), anIntArray1492[c], anIntArray1493[c], i1); + l += anIntArray1496[c]; + } + } + + public void drawTextWithPotentialShadow(boolean flag1, int i, int j, String s, int k) { + aBoolean1499 = false; + int l = i; + if(s == null) + return; + k -= verticalSpace; + for(int i1 = 0; i1 < s.length(); i1++) + if(s.charAt(i1) == '@' && i1 + 4 < s.length() && s.charAt(i1 + 4) == '@') { + int j1 = getColorByName(s.substring(i1 + 1, i1 + 4)); + if(j1 != -1) + j = j1; + i1 += 4; + } else { + char c = s.charAt(i1); + if(c != ' ') { + if(flag1) + method392(aByteArrayArray1491[c], i + anIntArray1494[c] + 1, k + anIntArray1495[c] + 1, anIntArray1492[c], anIntArray1493[c], 0); + method392(aByteArrayArray1491[c], i + anIntArray1494[c], k + anIntArray1495[c], anIntArray1492[c], anIntArray1493[c], j); + } + i += anIntArray1496[c]; + } + if(aBoolean1499) + Rasterizer2D.drawHorizontalLine(l, k + (int)((double)verticalSpace * 0.69999999999999996D), i - l, 0x800000); + } + + public void method390(int i, int j, String s, int k, int i1) { + if(s == null) + return; + aRandom1498.setSeed(k); + int j1 = 192 + (aRandom1498.nextInt() & 0x1f); + i1 -= verticalSpace; + for(int k1 = 0; k1 < s.length(); k1++) { + if(s.charAt(k1) == '@' && k1 + 4 < s.length() && s.charAt(k1 + 4) == '@') { + int l1 = getColorByName(s.substring(k1 + 1, k1 + 4)); + if(l1 != -1) + j = l1; + k1 += 4; + } else { + char c = s.charAt(k1); + if(c >= anIntArray1494.length) { + c = ' '; + } + if(c != ' ') { + method394(192, i + anIntArray1494[c] + 1, aByteArrayArray1491[c], anIntArray1492[c], i1 + anIntArray1495[c] + 1, anIntArray1493[c], 0); + method394(j1, i + anIntArray1494[c], aByteArrayArray1491[c], anIntArray1492[c], i1 + anIntArray1495[c], anIntArray1493[c], j); + } + i += anIntArray1496[c]; + if((aRandom1498.nextInt() & 3) == 0) + i++; + } + } + } + + private int getColorByName(String s) { + if(s.equals("369"))//color code, use as @###@ + return 0x336699;//hex code + if(s.equals("mon")) + return 0x00ff80; + if(s.equals("red")) + return 0xff0000; + if(s.equals("gre")) + return 65280; + if(s.equals("blu")) + return 255; + if(s.equals("yel")) + return 0xffff00; + if(s.equals("cya")) + return 65535; + if(s.equals("mag")) + return 0xff00ff; + if(s.equals("whi")) + return 0xffffff; + if(s.equals("bla")) + return 0; + if(s.equals("lre")) + return 0xff9040; + if(s.equals("dre")) + return 0x800000; + if(s.equals("dbl")) + return 128; + if(s.equals("or1")) + return 0xffb000; + if(s.equals("or2")) + return 0xff7000; + if(s.equals("or3")) + return 0xff3000; + if(s.equals("gr1")) + return 0xc0ff00; + if(s.equals("gr2")) + return 0x80ff00; + if(s.equals("gr3")) + return 0x40ff00; + if(s.equals("str")) + aBoolean1499 = true; + if(s.equals("end")) + aBoolean1499 = false; + return -1; + } + + private void method392(byte abyte0[], int i, int j, int k, int l, int i1) { + int j1 = i + j * width; + int k1 = width - k; + int l1 = 0; + int i2 = 0; + if (j < topY) { + int j2 = topY - j; + l -= j2; + j = topY; + i2 += j2 * k; + j1 += j2 * width; + } + if (j + l >= bottomY) + l -= ((j + l) - bottomY); + if (i < leftX) { + int k2 = leftX - i; + k -= k2; + i = leftX; + i2 += k2; + j1 += k2; + l1 += k2; + k1 += k2; + } + if (i + k >= bottomX) { + int l2 = ((i + k) - bottomX); + k -= l2; + l1 += l2; + k1 += l2; + } + if (!(k <= 0 || l <= 0)) { + method393(pixels, abyte0, i1, i2, j1, k, l, k1, l1); + } + } + + private void method393(int ai[], byte abyte0[], int i, int j, int k, int l, int i1, int j1, int k1) { + 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; + } + } + + private void method394(int i, int j, byte abyte0[], int k, int l, int i1, + int j1) { + int k1 = j + l * width; + int l1 = width - k; + int i2 = 0; + int j2 = 0; + if (l < topY) { + int k2 = topY - l; + i1 -= k2; + l = topY; + j2 += k2 * k; + k1 += k2 * width; + } + if (l + i1 >= bottomY) + i1 -= ((l + i1) - bottomY); + if (j < leftX) { + int l2 = leftX - j; + k -= l2; + j = leftX; + j2 += l2; + k1 += l2; + i2 += l2; + l1 += l2; + } + if (j + k >= bottomX) { + int i3 = ((j + k) - bottomX); + k -= i3; + i2 += i3; + l1 += i3; + } + if (k <= 0 || i1 <= 0) + return; + method395(abyte0, i1, k1, pixels, j2, k, i2, l1, j1, i); + } + + private void method395(byte abyte0[], int i, int j, int ai[], int l, int i1, int j1, int k1, int l1, int i2) { + l1 = ((l1 & 0xff00ff) * i2 & 0xff00ff00) + ((l1 & 0xff00) * i2 & 0xff0000) >> 8; + i2 = 256 - i2; + for(int j2 = -i; j2 < 0; j2++) { + for(int k2 = -i1; k2 < 0; k2++) + if(abyte0[l++] != 0) { + int l2 = ai[j]; + ai[j++] = (((l2 & 0xff00ff) * i2 & 0xff00ff00) + ((l2 & 0xff00) * i2 & 0xff0000) >> 8) + l1; + } else { + j++; + } + j += k1; + l += j1; + } + } + + public static void drawAlphaFilledPixels(int xPos, int yPos, + int pixelWidth, int pixelHeight, int color, int alpha) {// method586 + if (xPos < leftX) { + pixelWidth -= leftX - xPos; + xPos = leftX; + } + if (yPos < topY) { + pixelHeight -= topY - yPos; + yPos = topY; + } + if (xPos + pixelWidth > bottomX) + pixelWidth = bottomX - xPos; + if (yPos + pixelHeight > bottomY) + pixelHeight = bottomY - yPos; + color = ((color & 0xff00ff) * alpha >> 8 & 0xff00ff) + + ((color & 0xff00) * alpha >> 8 & 0xff00); + int k1 = 256 - alpha; + int l1 = width - pixelWidth; + int i2 = xPos + yPos * width; + for (int j2 = 0; j2 < pixelHeight; j2++) { + for (int k2 = -pixelWidth; k2 < 0; k2++) { + int l2 = pixels[i2]; + l2 = ((l2 & 0xff00ff) * k1 >> 8 & 0xff00ff) + + ((l2 & 0xff00) * k1 >> 8 & 0xff00); + pixels[i2++] = color + l2; + } + i2 += l1; + } + } + + public byte[][] aByteArrayArray1491; + public int[] anIntArray1492; + public int[] anIntArray1493; + public int[] anIntArray1494; + public int[] anIntArray1495; + public int[] anIntArray1496; + public int verticalSpace; + public Random aRandom1498; + public boolean aBoolean1499; +} diff --git a/src/main/java/org/rebotted/cache/graphics/IndexedImage.java b/src/main/java/org/rebotted/cache/graphics/IndexedImage.java new file mode 100644 index 0000000..a25a9ce --- /dev/null +++ b/src/main/java/org/rebotted/cache/graphics/IndexedImage.java @@ -0,0 +1,239 @@ +package org.rebotted.cache.graphics; +import org.rebotted.cache.FileArchive; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.io.Buffer; + +public final class IndexedImage extends Rasterizer2D { + + public byte palettePixels[]; + public final int[] palette; + public int width; + public int height; + public int drawOffsetX; + public int drawOffsetY; + public int resizeWidth; + private int resizeHeight; + + public IndexedImage(FileArchive archive, String s, int i) { + Buffer image = new Buffer(archive.readFile(s + ".dat")); + Buffer meta = new Buffer(archive.readFile("index.dat")); + meta.currentPosition = image.readUShort(); + resizeWidth = meta.readUShort(); + resizeHeight = meta.readUShort(); + + int colorLength = meta.readUnsignedByte(); + palette = new int[colorLength]; + + for(int index = 0; index < colorLength - 1; index++) { + palette[index + 1] = meta.readTriByte(); + } + + for(int l = 0; l < i; l++) { + meta.currentPosition += 2; + image.currentPosition += meta.readUShort() * meta.readUShort(); + meta.currentPosition++; + } + drawOffsetX = meta.readUnsignedByte(); + drawOffsetY = meta.readUnsignedByte(); + width = meta.readUShort(); + height = meta.readUShort(); + int type = meta.readUnsignedByte(); + int pixels = width * height; + palettePixels = new byte[pixels]; + + if(type == 0) { + for(int index = 0; index < pixels; index++) { + palettePixels[index] = image.readSignedByte(); + } + } else if(type == 1) { + for(int x = 0; x < width; x++) { + for(int y = 0; y < height; y++) { + palettePixels[x + y * width] = image.readSignedByte(); + } + } + } + } + + public void downscale() { + resizeWidth /= 2; + resizeHeight /= 2; + byte raster[] = new byte[resizeWidth * resizeHeight]; + int sourceIndex = 0; + for(int y = 0; y < height; y ++) { + for(int x = 0; x < width; x++) { + raster[(x + drawOffsetX >> 1) + (y + drawOffsetY >> 1) * resizeWidth] = raster[sourceIndex++]; + } + } + this.palettePixels = raster; + width = resizeWidth; + height = resizeHeight; + drawOffsetX = 0; + drawOffsetY = 0; + } + + public void resize() { + if(width == resizeWidth && height == resizeHeight) { + return; + } + + byte raster[] = new byte[resizeWidth * resizeHeight]; + + int i = 0; + for(int y = 0; y < height; y++) { + for(int x = 0; x < width; x++) { + raster[x + drawOffsetX + (y + drawOffsetY) * resizeWidth] = raster[i++]; + } + } + this.palettePixels = raster; + width = resizeWidth; + height = resizeHeight; + drawOffsetX = 0; + drawOffsetY = 0; + } + + public void flipHorizontally() { + byte raster[] = new byte[width * height]; + int pixel = 0; + for(int y = 0; y < height; y++) { + for(int x = width - 1; x >= 0; x--) { + raster[pixel++] = raster[x + y * width]; + } + } + this.palettePixels = raster; + drawOffsetX = resizeWidth - width - drawOffsetX; + } + + public void flipVertically() { + byte raster[] = new byte[width * height]; + int pixel = 0; + for(int y = height - 1; y >= 0; y--) { + for(int x = 0; x < width; x++) { + raster[pixel++] = raster[x + y * width]; + } + } + this.palettePixels = raster; + drawOffsetY = resizeHeight - height - drawOffsetY; + } + + public void offsetColor(int redOffset, int greenOffset, int blueOffset) { + for(int index = 0; index < palette.length; index++) { + int red = palette[index] >> 16 & 0xff; + red += redOffset; + + if(red < 0) { + red = 0; + } else if(red > 255) { + red = 255; + } + + int green = palette[index] >> 8 & 0xff; + + green += greenOffset; + if(green < 0) { + green = 0; + } else if(green > 255) { + green = 255; + } + + int blue = palette[index] & 0xff; + + blue += blueOffset; + if(blue < 0) { + blue = 0; + } else if(blue > 255) { + blue = 255; + } + palette[index] = (red << 16) + (green << 8) + blue; + } + } + + public void draw(int x, int y) { + x += drawOffsetX; + y += drawOffsetY; + int destOffset = x + y * Rasterizer2D.width; + int sourceOffset = 0; + int height = this.height; + int width = this.width; + int destStep = Rasterizer2D.width - width; + int sourceStep = 0; + + if(y < Rasterizer2D.topY) { + int dy = Rasterizer2D.topY - y; + height -= dy; + y = Rasterizer2D.topY; + sourceOffset += dy * width; + destOffset += dy * Rasterizer2D.width; + } + + if(y + height > Rasterizer2D.bottomY) { + height -= (y + height) - Rasterizer2D.bottomY; + } + + if(x < Rasterizer2D.leftX) { + int k2 = Rasterizer2D.leftX - x; + width -= k2; + x = Rasterizer2D.leftX; + sourceOffset += k2; + destOffset += k2; + sourceStep += k2; + destStep += k2; + } + + if(x + width > Rasterizer2D.bottomX) { + int dx = (x + width) - Rasterizer2D.bottomX; + width -= dx; + sourceStep += dx; + destStep += dx; + } + + if(!(width <= 0 || height <= 0)) { + draw(height, Rasterizer2D.pixels, palettePixels, destStep, destOffset, width, sourceOffset, palette, sourceStep); + } + + } + + private void draw(int i, int raster[], byte image[], int destStep, int destIndex, int width, int sourceIndex, int ai1[], int sourceStep) { + int minX = -(width >> 2); + width = -(width & 3); + for(int y = -i; y < 0; y++) { + for(int x = minX; x < 0; x++) { + + byte pixel = image[sourceIndex++]; + + if(pixel != 0) { + raster[destIndex++] = ai1[pixel & 0xff]; + } else { + destIndex++; + } + pixel = image[sourceIndex++]; + if(pixel != 0) { + raster[destIndex++] = ai1[pixel & 0xff]; + } else { + destIndex++; + } + pixel = image[sourceIndex++]; + if(pixel != 0) { + raster[destIndex++] = ai1[pixel & 0xff]; + } else { + destIndex++; + } + pixel = image[sourceIndex++]; + if(pixel != 0) { + raster[destIndex++] = ai1[pixel & 0xff]; + } else { + destIndex++; + } + } + for(int x = width; x < 0; x++) { + byte pixel = image[sourceIndex++]; + if(pixel != 0) { + raster[destIndex++] = ai1[pixel & 0xff]; + } else { + destIndex++; + } + } + destIndex += destStep; + sourceIndex += sourceStep; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/cache/graphics/Sprite.java b/src/main/java/org/rebotted/cache/graphics/Sprite.java new file mode 100644 index 0000000..7adc94d --- /dev/null +++ b/src/main/java/org/rebotted/cache/graphics/Sprite.java @@ -0,0 +1,944 @@ +package org.rebotted.cache.graphics; +import java.awt.*; +import java.awt.image.PixelGrabber; + +import javax.swing.ImageIcon; + +import org.rebotted.Client; +import org.rebotted.cache.FileArchive; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.io.Buffer; +import org.rebotted.util.FileUtils; + +public final class Sprite extends Rasterizer2D { + + private int id; + private String name; + + private int myPixels[]; + private int myWidth; + private int myHeight; + private int offsetX; + private int offsetY; + private int maxWidth; + private int maxHeight; + + public Sprite() { + + } + + public Sprite(int i, int j) { + myPixels = new int[i * j]; + myWidth = maxWidth = i; + myHeight = maxHeight = j; + offsetX = offsetY = 0; + } + + public Sprite(Sprite sprite, int width, int height) { + this.myWidth = width; + this.myHeight = height; + this.maxWidth = width; + this.maxHeight = height; + offsetX = 0; + offsetY = 0; + + myPixels = new int[width * height]; + + System.arraycopy(sprite.myPixels, 0, myPixels, 0, myPixels.length); + } + + public Sprite(byte data[], Component component) { + try { + Image image = Toolkit.getDefaultToolkit().createImage(data); + MediaTracker mediatracker = new MediaTracker(component); + mediatracker.addImage(image, 0); + mediatracker.waitForAll(); + myWidth = image.getWidth(component); + myHeight = image.getHeight(component); + maxWidth = myWidth; + maxHeight = myHeight; + offsetX = 0; + offsetY = 0; + myPixels = new int[myWidth * myHeight]; + PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, myWidth, myHeight, myPixels, 0, myWidth); + pixelgrabber.grabPixels(); + } catch (Exception _ex) { + System.out.println("Error converting jpg"); + } + } + + public Sprite(String img, int width, int height) { + try { + Image image = Toolkit.getDefaultToolkit().createImage(FileUtils.readFile(img)); + myWidth = width; + myHeight = height; + maxWidth = myWidth; + maxHeight = myHeight; + offsetX = 0; + offsetY = 0; + myPixels = new int[myWidth * myHeight]; + PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, myWidth, myHeight, myPixels, 0, myWidth); + pixelgrabber.grabPixels(); + image = null; + } catch (Exception _ex) { + System.out.println(_ex); + } + } + + public void drawHoverSprite(int x, int y, int offsetX, int offsetY, Sprite hover) { + this.drawSprite(x, y); + if (Client.instance.mouseX >= offsetX + x && Client.instance.mouseX <= offsetX + x + this.myWidth + && Client.instance.mouseY >= offsetY + y && Client.instance.mouseY <= offsetY + y + this.myHeight) { + hover.drawSprite(x, y); + } + } + + public void draw24BitSprite(int x, int y) { + int alpha = 256; + x += this.offsetX;// offsetX + y += this.offsetY;// offsetY + int destOffset = x + y * Rasterizer2D.width; + int srcOffset = 0; + int height = this.myHeight; + int width = this.myWidth; + int destStep = Rasterizer2D.width - width; + int srcStep = 0; + if (y < Rasterizer2D.topY) { + int trimHeight = Rasterizer2D.topY - y; + height -= trimHeight; + y = Rasterizer2D.topY; + srcOffset += trimHeight * width; + destOffset += trimHeight * Rasterizer2D.width; + } + if (y + height > Rasterizer2D.bottomY) { + height -= (y + height) - Rasterizer2D.bottomY; + } + if (x < Rasterizer2D.leftX) { + int trimLeft = Rasterizer2D.leftX - x; + width -= trimLeft; + x = Rasterizer2D.leftX; + srcOffset += trimLeft; + destOffset += trimLeft; + srcStep += trimLeft; + destStep += trimLeft; + } + if (x + width > Rasterizer2D.bottomX) { + int trimRight = (x + width) - Rasterizer2D.bottomX; + width -= trimRight; + srcStep += trimRight; + destStep += trimRight; + } + if (!((width <= 0) || (height <= 0))) { + set24BitPixels(width, height, Rasterizer2D.pixels, myPixels, alpha, destOffset, srcOffset, destStep, srcStep); + } + } + + public void drawTransparentSprite(int x, int y, int opacity) { + int k = opacity;// was parameter + x += offsetX; + y += offsetY; + int i1 = x + y * Rasterizer2D.width; + int j1 = 0; + int k1 = myHeight; + int l1 = myWidth; + int i2 = Rasterizer2D.width - l1; + int j2 = 0; + if (y < Rasterizer2D.topY) { + int k2 = Rasterizer2D.topY - y; + k1 -= k2; + y = Rasterizer2D.topY; + j1 += k2 * l1; + i1 += k2 * Rasterizer2D.width; + } + if (y + k1 > Rasterizer2D.bottomY) + k1 -= (y + k1) - Rasterizer2D.bottomY; + if (x < Rasterizer2D.leftX) { + int l2 = Rasterizer2D.leftX - x; + l1 -= l2; + x = Rasterizer2D.leftX; + j1 += l2; + i1 += l2; + j2 += l2; + i2 += l2; + } + if (x + l1 > Rasterizer2D.bottomX) { + int i3 = (x + l1) - Rasterizer2D.bottomX; + l1 -= i3; + j2 += i3; + i2 += i3; + } + if (!(l1 <= 0 || k1 <= 0)) { + method351(j1, l1, Rasterizer2D.pixels, myPixels, j2, k1, i2, k, i1); + } + } + + private void set24BitPixels(int width, int height, int destPixels[], int srcPixels[], int srcAlpha, int destOffset, int srcOffset, int destStep, int srcStep) { + int srcColor; + int destAlpha; + for (int loop = -height; loop < 0; loop++) { + for (int loop2 = -width; loop2 < 0; loop2++) { + srcAlpha = ((this.myPixels[srcOffset] >> 24) & 255); + destAlpha = 256 - srcAlpha; + srcColor = srcPixels[srcOffset++]; + if (srcColor != 0 && srcColor != 0xffffff) { + int destColor = destPixels[destOffset]; + destPixels[destOffset++] = ((srcColor & 0xff00ff) * srcAlpha + (destColor & 0xff00ff) * destAlpha & 0xff00ff00) + ((srcColor & 0xff00) * srcAlpha + (destColor & 0xff00) * destAlpha & 0xff0000) >> 8; + } else { + destOffset++; + } + } + destOffset += destStep; + srcOffset += srcStep; + } + } + + public void setTransparency(int transRed, int transGreen, int transBlue) { + for (int index = 0; index < myPixels.length; index++) + if (((myPixels[index] >> 16) & 255) == transRed && ((myPixels[index] >> 8) & 255) == transGreen && (myPixels[index] & 255) == transBlue) + myPixels[index] = 0; + } + + public Sprite(FileArchive archive, String name, int i) { + Buffer dataBuffer = new Buffer(archive.readFile(name + ".dat")); + Buffer indexBuffer = new Buffer(archive.readFile("index.dat")); + + indexBuffer.currentPosition = dataBuffer.readUShort(); + + maxWidth = indexBuffer.readUShort(); + maxHeight = indexBuffer.readUShort(); + int pixelCount = indexBuffer.readUnsignedByte(); + int raster[] = new int[pixelCount]; + + for (int pixel = 0; pixel < pixelCount - 1; pixel++) { + raster[pixel + 1] = indexBuffer.readTriByte(); + if (raster[pixel + 1] == 0) + raster[pixel + 1] = 1; + } + + for (int index = 0; index < i; index++) { + indexBuffer.currentPosition += 2; + dataBuffer.currentPosition += indexBuffer.readUShort() * indexBuffer.readUShort(); + indexBuffer.currentPosition++; + } + + offsetX = indexBuffer.readUnsignedByte(); + offsetY = indexBuffer.readUnsignedByte(); + myWidth = indexBuffer.readUShort(); + myHeight = indexBuffer.readUShort(); + + int type = indexBuffer.readUnsignedByte(); + + int spriteSize = myWidth * myHeight; + + myPixels = new int[spriteSize]; + if (type == 0) { + for (int pixel = 0; pixel < spriteSize; pixel++) { + myPixels[pixel] = raster[dataBuffer.readUnsignedByte()]; + } + setTransparency(255, 0, 255); + return; + } + if (type == 1) { + for (int x = 0; x < myWidth; x++) { + for (int y = 0; y < myHeight; y++) { + myPixels[x + y * myWidth] = raster[dataBuffer.readUnsignedByte()]; + } + } + + } + setTransparency(255, 0, 255); + } + + public void init() { + Rasterizer2D.initDrawingArea(myHeight, myWidth, myPixels, null); + } + + public void method344(int i, int j, int k) { + for (int i1 = 0; i1 < myPixels.length; i1++) { + int j1 = myPixels[i1]; + if (j1 != 0) { + int k1 = j1 >> 16 & 0xff; + k1 += i; + if (k1 < 1) + k1 = 1; + else if (k1 > 255) + k1 = 255; + int l1 = j1 >> 8 & 0xff; + l1 += j; + if (l1 < 1) + l1 = 1; + else if (l1 > 255) + l1 = 255; + int i2 = j1 & 0xff; + i2 += k; + if (i2 < 1) + i2 = 1; + else if (i2 > 255) + i2 = 255; + myPixels[i1] = (k1 << 16) + (l1 << 8) + i2; + } + } + + } + + public void method345() { + int ai[] = new int[maxWidth * maxHeight]; + for (int j = 0; j < myHeight; j++) { + System.arraycopy(myPixels, j * myWidth, ai, j + offsetY * maxWidth + offsetX, myWidth); + } + + myPixels = ai; + myWidth = maxWidth; + myHeight = maxHeight; + offsetX = 0; + offsetY = 0; + } + + public void method346(int x, int y) { + x += offsetX; + y += offsetY; + int l = x + y * Rasterizer2D.width; + int i1 = 0; + int height = myHeight; + int width = myWidth; + int l1 = Rasterizer2D.width - width; + int i2 = 0; + if (y < Rasterizer2D.topY) { + int j2 = Rasterizer2D.topY - y; + height -= j2; + y = Rasterizer2D.topY; + i1 += j2 * width; + l += j2 * Rasterizer2D.width; + } + if (y + height > Rasterizer2D.bottomY) + height -= (y + height) - Rasterizer2D.bottomY; + if (x < Rasterizer2D.leftX) { + int k2 = Rasterizer2D.leftX - x; + width -= k2; + x = Rasterizer2D.leftX; + i1 += k2; + l += k2; + i2 += k2; + l1 += k2; + } + if (x + width > Rasterizer2D.bottomX) { + int l2 = (x + width) - Rasterizer2D.bottomX; + width -= l2; + i2 += l2; + l1 += l2; + } + if (width <= 0 || height <= 0) { + } else { + method347(l, width, height, i2, i1, l1, myPixels, Rasterizer2D.pixels); + } + } + + private void method347(int i, int j, int k, int l, int i1, int k1, int ai[], int ai1[]) { + int l1 = -(j >> 2); + j = -(j & 3); + for (int i2 = -k; i2 < 0; i2++) { + for (int j2 = l1; j2 < 0; j2++) { + ai1[i++] = ai[i1++]; + ai1[i++] = ai[i1++]; + ai1[i++] = ai[i1++]; + ai1[i++] = ai[i1++]; + } + + for (int k2 = j; k2 < 0; k2++) + ai1[i++] = ai[i1++]; + + i += k1; + i1 += l; + } + } + + public void drawSprite1(int i, int j) { + drawSprite1(i, j, 128); + } + + public void drawSprite1(int i, int j, int k) { + i += offsetX; + j += offsetY; + int i1 = i + j * Rasterizer2D.width; + int j1 = 0; + int k1 = myHeight; + int l1 = myWidth; + int i2 = Rasterizer2D.width - l1; + int j2 = 0; + if (j < Rasterizer2D.topY) { + int k2 = Rasterizer2D.topY - j; + k1 -= k2; + j = Rasterizer2D.topY; + j1 += k2 * l1; + i1 += k2 * Rasterizer2D.width; + } + if (j + k1 > Rasterizer2D.bottomY) + k1 -= (j + k1) - Rasterizer2D.bottomY; + if (i < Rasterizer2D.leftX) { + int l2 = Rasterizer2D.leftX - i; + l1 -= l2; + i = Rasterizer2D.leftX; + j1 += l2; + i1 += l2; + j2 += l2; + i2 += l2; + } + if (i + l1 > Rasterizer2D.bottomX) { + int i3 = (i + l1) - Rasterizer2D.bottomX; + l1 -= i3; + j2 += i3; + i2 += i3; + } + if (!(l1 <= 0 || k1 <= 0)) { + method351(j1, l1, Rasterizer2D.pixels, myPixels, j2, k1, i2, k, i1); + } + } + + public void drawSprite(int x, int y) + { + x += offsetX; + y += offsetY; + int rasterClip = x + y * Rasterizer2D.width; + int imageClip = 0; + int height = myHeight; + int width = myWidth; + int rasterOffset = Rasterizer2D.width - width; + int imageOffset = 0; + if(y < Rasterizer2D.topY) + { + int dy = Rasterizer2D.topY - y; + height -= dy; + y = Rasterizer2D.topY; + imageClip += dy * width; + rasterClip += dy * Rasterizer2D.width; + } + if(y + height > Rasterizer2D.bottomY) + height -= (y + height) - Rasterizer2D.bottomY; + if(x < Rasterizer2D.leftX) + { + int dx = Rasterizer2D.leftX - x; + width -= dx; + x = Rasterizer2D.leftX; + imageClip += dx; + rasterClip += dx; + imageOffset += dx; + rasterOffset += dx; + } + if(x + width > Rasterizer2D.bottomX) + { + int dx = (x + width) - Rasterizer2D.bottomX; + width -= dx; + imageOffset += dx; + rasterOffset += dx; + } + if(!(width <= 0 || height <= 0)) + { + method349(Rasterizer2D.pixels, myPixels, imageClip, rasterClip, width, height, rasterOffset, imageOffset); + } + } + + public void drawSprite(int i, int k, int color) { + int tempWidth = myWidth + 2; + int tempHeight = myHeight + 2; + int[] tempArray = new int[tempWidth * tempHeight]; + for (int x = 0; x < myWidth; x++) { + for (int y = 0; y < myHeight; y++) { + if (myPixels[x + y * myWidth] != 0) + tempArray[(x + 1) + (y + 1) * tempWidth] = myPixels[x + y * myWidth]; + } + } + for (int x = 0; x < tempWidth; x++) { + for (int y = 0; y < tempHeight; y++) { + if (tempArray[(x) + (y) * tempWidth] == 0) { + if (x < tempWidth - 1 && tempArray[(x + 1) + ((y) * tempWidth)] > 0 && tempArray[(x + 1) + ((y) * tempWidth)] != 0xffffff) { + tempArray[(x) + (y) * tempWidth] = color; + } + if (x > 0 && tempArray[(x - 1) + ((y) * tempWidth)] > 0 && tempArray[(x - 1) + ((y) * tempWidth)] != 0xffffff) { + tempArray[(x) + (y) * tempWidth] = color; + } + if (y < tempHeight - 1 && tempArray[(x) + ((y + 1) * tempWidth)] > 0 && tempArray[(x) + ((y + 1) * tempWidth)] != 0xffffff) { + tempArray[(x) + (y) * tempWidth] = color; + } + if (y > 0 && tempArray[(x) + ((y - 1) * tempWidth)] > 0 && tempArray[(x) + ((y - 1) * tempWidth)] != 0xffffff) { + tempArray[(x) + (y) * tempWidth] = color; + } + } + } + } + i--; + k--; + i += offsetX; + k += offsetY; + int l = i + k * Rasterizer2D.width; + int i1 = 0; + int j1 = tempHeight; + int k1 = tempWidth; + int l1 = Rasterizer2D.width - k1; + int i2 = 0; + if (k < Rasterizer2D.topY) { + int j2 = Rasterizer2D.topY - k; + j1 -= j2; + k = Rasterizer2D.topY; + i1 += j2 * k1; + l += j2 * Rasterizer2D.width; + } + if (k + j1 > Rasterizer2D.bottomY) { + j1 -= (k + j1) - Rasterizer2D.bottomY; + } + if (i < Rasterizer2D.leftX) { + int k2 = Rasterizer2D.leftX - i; + k1 -= k2; + i = Rasterizer2D.leftX; + i1 += k2; + l += k2; + i2 += k2; + l1 += k2; + } + if (i + k1 > Rasterizer2D.bottomX) { + int l2 = (i + k1) - Rasterizer2D.bottomX; + k1 -= l2; + i2 += l2; + l1 += l2; + } + if (!(k1 <= 0 || j1 <= 0)) { + method349(Rasterizer2D.pixels, tempArray, i1, l, k1, j1, l1, i2); + } + } + + public void drawSprite2(int i, int j) { + int k = 225;// was parameter + i += offsetX; + j += offsetY; + int i1 = i + j * Rasterizer2D.width; + int j1 = 0; + int k1 = myHeight; + int l1 = myWidth; + int i2 = Rasterizer2D.width - l1; + int j2 = 0; + if (j < Rasterizer2D.topY) { + int k2 = Rasterizer2D.topY - j; + k1 -= k2; + j = Rasterizer2D.topY; + j1 += k2 * l1; + i1 += k2 * Rasterizer2D.width; + } + if (j + k1 > Rasterizer2D.bottomY) + k1 -= (j + k1) - Rasterizer2D.bottomY; + if (i < Rasterizer2D.leftX) { + int l2 = Rasterizer2D.leftX - i; + l1 -= l2; + i = Rasterizer2D.leftX; + j1 += l2; + i1 += l2; + j2 += l2; + i2 += l2; + } + if (i + l1 > Rasterizer2D.bottomX) { + int i3 = (i + l1) - Rasterizer2D.bottomX; + l1 -= i3; + j2 += i3; + i2 += i3; + } + if (!(l1 <= 0 || k1 <= 0)) { + method351(j1, l1, Rasterizer2D.pixels, myPixels, j2, k1, i2, k, i1); + } + } + + private void method349(int ai[], int ai1[], int j, int k, int l, int i1, int j1, int k1) { + int i;// was parameter + int l1 = -(l >> 2); + l = -(l & 3); + for (int i2 = -i1; i2 < 0; i2++) { + for (int j2 = l1; j2 < 0; j2++) { + i = ai1[j++]; + if (i != 0 && i != -1) { + ai[k++] = i; + } else { + k++; + } + i = ai1[j++]; + if (i != 0 && i != -1) { + ai[k++] = i; + } else { + k++; + } + i = ai1[j++]; + if (i != 0 && i != -1) { + ai[k++] = i; + } else { + k++; + } + i = ai1[j++]; + if (i != 0 && i != -1) { + ai[k++] = i; + } else { + k++; + } + } + + for (int k2 = l; k2 < 0; k2++) { + i = ai1[j++]; + if (i != 0 && i != -1) { + ai[k++] = i; + } else { + k++; + } + } + k += j1; + j += k1; + } + } + + private void method351(int i, int j, int ai[], int ai1[], int l, int i1, int j1, int k1, int l1) { + int k;// was parameter + int j2 = 256 - k1; + for (int k2 = -i1; k2 < 0; k2++) { + for (int l2 = -j; l2 < 0; l2++) { + k = ai1[i++]; + if (k != 0) { + int i3 = ai[l1]; + ai[l1++] = ((k & 0xff00ff) * k1 + (i3 & 0xff00ff) * j2 & 0xff00ff00) + ((k & 0xff00) * k1 + (i3 & 0xff00) * j2 & 0xff0000) >> 8; + } else { + l1++; + } + } + + l1 += j1; + i += l; + } + } + + public void rotate(int i, int j, int ai[], int k, int ai1[], int i1, int j1, int k1, int l1, int i2) { + try { + int j2 = -l1 / 2; + int k2 = -i / 2; + int l2 = (int) (Math.sin((double) j / 326.11000000000001D) * 65536D); + int i3 = (int) (Math.cos((double) j / 326.11000000000001D) * 65536D); + l2 = l2 * k >> 8; + i3 = i3 * k >> 8; + int j3 = (i2 << 16) + (k2 * l2 + j2 * i3); + int k3 = (i1 << 16) + (k2 * i3 - j2 * l2); + int l3 = k1 + j1 * Rasterizer2D.width; + for (j1 = 0; j1 < i; j1++) { + int i4 = ai1[j1]; + int j4 = l3 + i4; + int k4 = j3 + i3 * i4; + int l4 = k3 - l2 * i4; + for (k1 = -ai[j1]; k1 < 0; k1++) { + int x1 = k4 >> 16; + int y1 = l4 >> 16; + int x2 = x1 + 1; + int y2 = y1 + 1; + int c1 = myPixels[x1 + y1 * myWidth]; + int c2 = myPixels[x2 + y1 * myWidth]; + int c3 = myPixels[x1 + y2 * myWidth]; + int c4 = myPixels[x2 + y2 * myWidth]; + int u1 = (k4 >> 8) - (x1 << 8); + int v1 = (l4 >> 8) - (y1 << 8); + int u2 = (x2 << 8) - (k4 >> 8); + int v2 = (y2 << 8) - (l4 >> 8); + int a1 = u2 * v2; + int a2 = u1 * v2; + int a3 = u2 * v1; + int a4 = u1 * v1; + int r = (c1 >> 16 & 0xff) * a1 + (c2 >> 16 & 0xff) * a2 + (c3 >> 16 & 0xff) * a3 + (c4 >> 16 & 0xff) * a4 & 0xff0000; + int g = (c1 >> 8 & 0xff) * a1 + (c2 >> 8 & 0xff) * a2 + (c3 >> 8 & 0xff) * a3 + (c4 >> 8 & 0xff) * a4 >> 8 & 0xff00; + int b = (c1 & 0xff) * a1 + (c2 & 0xff) * a2 + (c3 & 0xff) * a3 + (c4 & 0xff) * a4 >> 16; + Rasterizer2D.pixels[j4++] = r | g | b; + k4 += i3; + l4 -= l2; + } + + j3 += l2; + k3 += i3; + l3 += Rasterizer2D.width; + } + + } catch (Exception _ex) { + } + } + + public void method353(int i, double d, int l1) { + // all of the following were parameters + int j = 15; + int k = 20; + int l = 15; + int j1 = 256; + int k1 = 20; + // all of the previous were parameters + try { + int i2 = -k / 2; + int j2 = -k1 / 2; + int k2 = (int) (Math.sin(d) * 65536D); + int l2 = (int) (Math.cos(d) * 65536D); + k2 = k2 * j1 >> 8; + l2 = l2 * j1 >> 8; + int i3 = (l << 16) + (j2 * k2 + i2 * l2); + int j3 = (j << 16) + (j2 * l2 - i2 * k2); + int k3 = l1 + i * Rasterizer2D.width; + for (i = 0; i < k1; i++) { + int l3 = k3; + int i4 = i3; + int j4 = j3; + for (l1 = -k; l1 < 0; l1++) { + int k4 = myPixels[(i4 >> 16) + (j4 >> 16) * myWidth]; + if (k4 != 0) + Rasterizer2D.pixels[l3++] = k4; + else + l3++; + i4 += l2; + j4 -= k2; + } + + i3 += k2; + j3 += l2; + k3 += Rasterizer2D.width; + } + + } catch (Exception _ex) { + } + } + + public Sprite(byte spriteData[]) { + try { + Image image = Toolkit.getDefaultToolkit().createImage(spriteData); + ImageIcon sprite = new ImageIcon(image); + myWidth = sprite.getIconWidth(); + myHeight = sprite.getIconHeight(); + maxWidth = myWidth; + maxHeight = myHeight; + offsetX = 0; + offsetY = 0; + myPixels = new int[myWidth * myHeight]; + PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, myWidth, myHeight, myPixels, 0, myWidth); + pixelgrabber.grabPixels(); + image = null; + setTransparency(255, 0, 255); + } catch (Exception _ex) { + System.out.println(_ex); + } + } + + public void method354(IndexedImage background, int i, int j) { + j += offsetX; + i += offsetY; + int k = j + i * Rasterizer2D.width; + int l = 0; + int i1 = myHeight; + int j1 = myWidth; + int k1 = Rasterizer2D.width - j1; + int l1 = 0; + if (i < Rasterizer2D.topY) { + int i2 = Rasterizer2D.topY - i; + i1 -= i2; + i = Rasterizer2D.topY; + l += i2 * j1; + k += i2 * Rasterizer2D.width; + } + if (i + i1 > Rasterizer2D.bottomY) + i1 -= (i + i1) - Rasterizer2D.bottomY; + if (j < Rasterizer2D.leftX) { + int j2 = Rasterizer2D.leftX - j; + j1 -= j2; + j = Rasterizer2D.leftX; + l += j2; + k += j2; + l1 += j2; + k1 += j2; + } + if (j + j1 > Rasterizer2D.bottomX) { + int k2 = (j + j1) - Rasterizer2D.bottomX; + j1 -= k2; + l1 += k2; + k1 += k2; + } + if (!(j1 <= 0 || i1 <= 0)) { + method355(myPixels, j1, background.palettePixels, i1, Rasterizer2D.pixels, 0, k1, k, l1, l); + } + } + + public void drawARGBSprite(int xPos, int yPos) { + drawARGBSprite(xPos, yPos, 256); + } + + public void drawARGBSprite(int xPos, int yPos, int alpha) { + int alphaValue = alpha; + xPos += offsetX; + yPos += offsetY; + int i1 = xPos + yPos * Rasterizer2D.width; + int j1 = 0; + int spriteHeight = myHeight; + int spriteWidth = myWidth; + int i2 = Rasterizer2D.width - spriteWidth; + int j2 = 0; + if (yPos < Rasterizer2D.topY) { + int k2 = Rasterizer2D.topY - yPos; + spriteHeight -= k2; + yPos = Rasterizer2D.topY; + j1 += k2 * spriteWidth; + i1 += k2 * Rasterizer2D.width; + } + if (yPos + spriteHeight > Rasterizer2D.bottomY) + spriteHeight -= (yPos + spriteHeight) - Rasterizer2D.bottomY; + if (xPos < Rasterizer2D.leftX) { + int l2 = Rasterizer2D.leftX - xPos; + spriteWidth -= l2; + xPos = Rasterizer2D.leftX; + j1 += l2; + i1 += l2; + j2 += l2; + i2 += l2; + } + if (xPos + spriteWidth > Rasterizer2D.bottomX) { + int i3 = (xPos + spriteWidth) - Rasterizer2D.bottomX; + spriteWidth -= i3; + j2 += i3; + i2 += i3; + } + if (!(spriteWidth <= 0 || spriteHeight <= 0)) { + renderARGBPixels(spriteWidth, spriteHeight, myPixels, Rasterizer2D.pixels, i1, alphaValue, j1, j2, i2); + } + } + + private void renderARGBPixels(int spriteWidth, int spriteHeight, int spritePixels[], int renderAreaPixels[], int pixel, int alphaValue, int i, int l, int j1) { + int pixelColor; + int alphaLevel; + int alpha = alphaValue; + for (int height = -spriteHeight; height < 0; height++) { + for (int width = -spriteWidth; width < 0; width++) { + alphaValue = ((myPixels[i] >> 24) & (alpha - 1)); + alphaLevel = 256 - alphaValue; + if (alphaLevel > 256) { + alphaValue = 0; + } + if (alpha == 0) { + alphaLevel = 256; + alphaValue = 0; + } + pixelColor = spritePixels[i++]; + if (pixelColor != 0) { + int pixelValue = renderAreaPixels[pixel]; + renderAreaPixels[pixel++] = ((pixelColor & 0xff00ff) * alphaValue + (pixelValue & 0xff00ff) * alphaLevel & 0xff00ff00) + ((pixelColor & 0xff00) * alphaValue + (pixelValue & 0xff00) * alphaLevel & 0xff0000) >> 8; + } else { + pixel++; + } + } + pixel += j1; + i += l; + } + } + + private void method355(int ai[], int i, byte abyte0[], int j, int ai1[], int k, int l, int i1, int j1, int k1) { + int l1 = -(i >> 2); + i = -(i & 3); + for (int j2 = -j; j2 < 0; j2++) { + for (int k2 = l1; k2 < 0; k2++) { + k = ai[k1++]; + if (k != 0 && abyte0[i1] == 0) + ai1[i1++] = k; + else + i1++; + k = ai[k1++]; + if (k != 0 && abyte0[i1] == 0) + ai1[i1++] = k; + else + i1++; + k = ai[k1++]; + if (k != 0 && abyte0[i1] == 0) + ai1[i1++] = k; + else + i1++; + k = ai[k1++]; + if (k != 0 && abyte0[i1] == 0) + ai1[i1++] = k; + else + i1++; + } + + for (int l2 = i; l2 < 0; l2++) { + k = ai[k1++]; + if (k != 0 && abyte0[i1] == 0) + ai1[i1++] = k; + else + i1++; + } + + i1 += l; + k1 += j1; + } + + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int[] getMyPixels() { + return myPixels; + } + + public void setMyPixels(int[] myPixels) { + this.myPixels = myPixels; + } + + public int getMyWidth() { + return myWidth; + } + + public void setMyWidth(int myWidth) { + this.myWidth = myWidth; + } + + public int getMyHeight() { + return myHeight; + } + + public void setMyHeight(int myHeight) { + this.myHeight = myHeight; + } + + public int getOffsetX() { + return offsetX; + } + + public void setOffsetX(int offsetX) { + this.offsetX = offsetX; + } + + public int getOffsetY() { + return offsetY; + } + + public void setOffsetY(int offsetY) { + this.offsetY = offsetY; + } + + public int getMaxWidth() { + return maxWidth; + } + + public void setMaxWidth(int maxWidth) { + this.maxWidth = maxWidth; + } + + public int getMaxHeight() { + return maxHeight; + } + + public void setMaxHeight(int maxHeight) { + this.maxHeight = maxHeight; + } + +} diff --git a/src/main/java/org/rebotted/cache/graphics/SpriteCache.java b/src/main/java/org/rebotted/cache/graphics/SpriteCache.java new file mode 100644 index 0000000..edc2036 --- /dev/null +++ b/src/main/java/org/rebotted/cache/graphics/SpriteCache.java @@ -0,0 +1,98 @@ +package org.rebotted.cache.graphics; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import org.apache.commons.compress.compressors.xz.XZCompressorInputStream; + +import org.rebotted.io.Buffer; +import org.rebotted.sign.SignLink; +import org.rebotted.util.FileUtils; + +public final class SpriteCache { + + private static Sprite[] sprites; + + private static int totalSprites; + + public static void load() { + Buffer data = new Buffer(FileUtils.readFile(SignLink.findcachedir() + "main_file_sprites.dat")); + + try (DataInputStream dataFile = new DataInputStream(new XZCompressorInputStream(new ByteArrayInputStream(data.payload)))) { + + int totalSprites = dataFile.readInt(); + + sprites = new Sprite[totalSprites]; + + for (int index = 0; index < totalSprites; index++) { + sprites[index] = SpriteCache.decode(dataFile); + + sprites[index].setTransparency(255, 0, 255); + } + + System.out.println("Sprites Loaded: " + totalSprites); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + private static Sprite decode(DataInputStream dat) throws IOException { + + Sprite sprite = new Sprite(); + + while (true) { + + byte opcode = dat.readByte(); + + if (opcode == 0) { + return sprite; + } else if (opcode == 1) { + sprite.setId(dat.readShort()); + } else if (opcode == 2) { + sprite.setName(dat.readUTF()); + } else if (opcode == 3) { + sprite.setMyWidth(dat.readShort()); + } else if (opcode == 4) { + sprite.setMyHeight(dat.readShort()); + } else if (opcode == 5) { + sprite.setOffsetX(dat.readShort()); + } else if (opcode == 6) { + sprite.setOffsetY(dat.readShort()); + } else if (opcode == 7) { + + int indexLength = dat.readInt(); + + int[] pixels = new int[indexLength]; + + for (int i = 0; i < pixels.length; i++) { + pixels[i] = dat.readInt(); + } + + sprite.setMyPixels(pixels); + } + } + } + + public Sprite[] getSprites() { + return sprites; + } + + public static Sprite lookup(int id) { + if (id < 0 || id > sprites.length) { + throw new IllegalArgumentException(String.format("Invalid id: %d while trying to lookup a sprite.", id)); + } + return sprites[id]; + } + + public static void set(int id, Sprite sprite) { + if (id < 0 || id > sprites.length) { + throw new IllegalArgumentException(String.format("Invalid id: %d while trying to lookup a sprite.", id)); + } + sprites[id] = sprite; + } + + public int totalSprites() { + return totalSprites; + } + +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/cache/graphics/Widget.java b/src/main/java/org/rebotted/cache/graphics/Widget.java new file mode 100644 index 0000000..a48ddc5 --- /dev/null +++ b/src/main/java/org/rebotted/cache/graphics/Widget.java @@ -0,0 +1,2077 @@ +package org.rebotted.cache.graphics; + +import org.rebotted.Client; +import org.rebotted.Configuration; +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.def.ItemDefinition; +import org.rebotted.cache.def.NpcDefinition; +import org.rebotted.collection.ReferenceCache; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; +import org.rebotted.util.StringUtils; + +/** + * Previously known as RSInterface, which is a class used to create and show + * game interfaces. + */ +public final class Widget { + + public static final int OPTION_OK = 1; + public static final int OPTION_USABLE = 2; + public static final int OPTION_CLOSE = 3; + public static final int OPTION_TOGGLE_SETTING = 4; + public static final int OPTION_RESET_SETTING = 5; + public static final int OPTION_CONTINUE = 6; + + public static final int TYPE_CONTAINER = 0; + public static final int TYPE_MODEL_LIST = 1; + public static final int TYPE_INVENTORY = 2; + public static final int TYPE_RECTANGLE = 3; + public static final int TYPE_TEXT = 4; + public static final int TYPE_SPRITE = 5; + public static final int TYPE_MODEL = 6; + public static final int TYPE_ITEM_LIST = 7; + + public void swapInventoryItems(int i, int j) { + int id = inventoryItemId[i]; + inventoryItemId[i] = inventoryItemId[j]; + inventoryItemId[j] = id; + id = inventoryAmounts[i]; + inventoryAmounts[i] = inventoryAmounts[j]; + inventoryAmounts[j] = id; + } + + public static void load(FileArchive interfaces, GameFont textDrawingAreas[], FileArchive graphics) { + spriteCache = new ReferenceCache(50000); + Buffer buffer = new Buffer(interfaces.readFile("data")); + int defaultParentId = -1; + buffer.readUShort(); + interfaceCache = new Widget[38000]; + + while (buffer.currentPosition < buffer.payload.length) { + int interfaceId = buffer.readUShort(); + if (interfaceId == 65535) { + defaultParentId = buffer.readUShort(); + interfaceId = buffer.readUShort(); + } + + Widget widget = interfaceCache[interfaceId] = new Widget(); + widget.id = interfaceId; + widget.parent = defaultParentId; + widget.type = buffer.readUnsignedByte(); + widget.optionType = buffer.readUnsignedByte(); + widget.contentType = buffer.readUShort(); + widget.width = buffer.readUShort(); + widget.height = buffer.readUShort(); + widget.opacity = (byte) buffer.readUnsignedByte(); + widget.hoverType = buffer.readUnsignedByte(); + if (widget.hoverType != 0) + widget.hoverType = (widget.hoverType - 1 << 8) + buffer.readUnsignedByte(); + else + widget.hoverType = -1; + int operators = buffer.readUnsignedByte(); + if (operators > 0) { + widget.scriptOperators = new int[operators]; + widget.scriptDefaults = new int[operators]; + for (int index = 0; index < operators; index++) { + widget.scriptOperators[index] = buffer.readUnsignedByte(); + widget.scriptDefaults[index] = buffer.readUShort(); + } + + } + int scripts = buffer.readUnsignedByte(); + if (scripts > 0) { + widget.scripts = new int[scripts][]; + for (int script = 0; script < scripts; script++) { + int instructions = buffer.readUShort(); + widget.scripts[script] = new int[instructions]; + for (int instruction = 0; instruction < instructions; instruction++) + widget.scripts[script][instruction] = buffer.readUShort(); + + } + + } + if (widget.type == TYPE_CONTAINER) { + widget.drawsTransparent = false; + widget.scrollMax = buffer.readUShort(); + widget.invisible = buffer.readUnsignedByte() == 1; + int length = buffer.readUShort(); + widget.children = new int[length]; + widget.childX = new int[length]; + widget.childY = new int[length]; + for (int index = 0; index < length; index++) { + widget.children[index] = buffer.readUShort(); + widget.childX[index] = buffer.readShort(); + widget.childY[index] = buffer.readShort(); + } + } + if (widget.type == TYPE_MODEL_LIST) { + buffer.readUShort(); + buffer.readUnsignedByte(); + } + if (widget.type == TYPE_INVENTORY) { + widget.inventoryItemId = new int[widget.width * widget.height]; + widget.inventoryAmounts = new int[widget.width * widget.height]; + widget.aBoolean259 = buffer.readUnsignedByte() == 1; + widget.hasActions = buffer.readUnsignedByte() == 1; + widget.usableItems = buffer.readUnsignedByte() == 1; + widget.replaceItems = buffer.readUnsignedByte() == 1; + widget.spritePaddingX = buffer.readUnsignedByte(); + widget.spritePaddingY = buffer.readUnsignedByte(); + widget.spritesX = new int[20]; + widget.spritesY = new int[20]; + widget.sprites = new Sprite[20]; + for (int j2 = 0; j2 < 20; j2++) { + int k3 = buffer.readUnsignedByte(); + if (k3 == 1) { + widget.spritesX[j2] = buffer.readShort(); + widget.spritesY[j2] = buffer.readShort(); + String s1 = buffer.readString(); + if (graphics != null && s1.length() > 0) { + int i5 = s1.lastIndexOf(","); + + int index = Integer.parseInt(s1.substring(i5 + 1)); + + String name = s1.substring(0, i5); + + widget.sprites[j2] = getSprite(index, graphics, name); + } + } + } + widget.actions = new String[5]; + for (int actionIndex = 0; actionIndex < 5; actionIndex++) { + widget.actions[actionIndex] = buffer.readString(); + if (widget.actions[actionIndex].length() == 0) + widget.actions[actionIndex] = null; + if (widget.parent == 1644) + widget.actions[2] = "Operate"; + } + } + if (widget.type == TYPE_RECTANGLE) + widget.filled = buffer.readUnsignedByte() == 1; + if (widget.type == TYPE_TEXT || widget.type == TYPE_MODEL_LIST) { + widget.centerText = buffer.readUnsignedByte() == 1; + int k2 = buffer.readUnsignedByte(); + if (textDrawingAreas != null) + widget.textDrawingAreas = textDrawingAreas[k2]; + widget.textShadow = buffer.readUnsignedByte() == 1; + } + + if (widget.type == TYPE_TEXT) { + widget.defaultText = buffer.readString().replaceAll("RuneScape", Configuration.CLIENT_NAME); + if (widget.id == 19209) { + widget.defaultText.replaceAll("Total", ""); + } + widget.secondaryText = buffer.readString(); + } + + if (widget.type == TYPE_MODEL_LIST || widget.type == TYPE_RECTANGLE || widget.type == TYPE_TEXT) + widget.textColor = buffer.readInt(); + if (widget.type == TYPE_RECTANGLE || widget.type == TYPE_TEXT) { + widget.secondaryColor = buffer.readInt(); + widget.defaultHoverColor = buffer.readInt(); + widget.secondaryHoverColor = buffer.readInt(); + } + if (widget.type == TYPE_SPRITE) { + widget.drawsTransparent = false; + String name = buffer.readString(); + if (graphics != null && name.length() > 0) { + int index = name.lastIndexOf(","); + widget.disabledSprite = getSprite(Integer.parseInt(name.substring(index + 1)), graphics, + name.substring(0, index)); + } + name = buffer.readString(); + if (graphics != null && name.length() > 0) { + int index = name.lastIndexOf(","); + widget.enabledSprite = getSprite(Integer.parseInt(name.substring(index + 1)), graphics, + name.substring(0, index)); + } + } + if (widget.type == TYPE_MODEL) { + int content = buffer.readUnsignedByte(); + if (content != 0) { + widget.defaultMediaType = 1; + widget.defaultMedia = (content - 1 << 8) + buffer.readUnsignedByte(); + } + content = buffer.readUnsignedByte(); + if (content != 0) { + widget.anInt255 = 1; + widget.anInt256 = (content - 1 << 8) + buffer.readUnsignedByte(); + } + content = buffer.readUnsignedByte(); + if (content != 0) + widget.defaultAnimationId = (content - 1 << 8) + buffer.readUnsignedByte(); + else + widget.defaultAnimationId = -1; + content = buffer.readUnsignedByte(); + if (content != 0) + widget.secondaryAnimationId = (content - 1 << 8) + buffer.readUnsignedByte(); + else + widget.secondaryAnimationId = -1; + widget.modelZoom = buffer.readUShort(); + widget.modelRotation1 = buffer.readUShort(); + widget.modelRotation2 = buffer.readUShort(); + } + if (widget.type == TYPE_ITEM_LIST) { + widget.inventoryItemId = new int[widget.width * widget.height]; + widget.inventoryAmounts = new int[widget.width * widget.height]; + widget.centerText = buffer.readUnsignedByte() == 1; + int l2 = buffer.readUnsignedByte(); + if (textDrawingAreas != null) + widget.textDrawingAreas = textDrawingAreas[l2]; + widget.textShadow = buffer.readUnsignedByte() == 1; + widget.textColor = buffer.readInt(); + widget.spritePaddingX = buffer.readShort(); + widget.spritePaddingY = buffer.readShort(); + widget.hasActions = buffer.readUnsignedByte() == 1; + widget.actions = new String[5]; + for (int actionCount = 0; actionCount < 5; actionCount++) { + widget.actions[actionCount] = buffer.readString(); + if (widget.actions[actionCount].length() == 0) + widget.actions[actionCount] = null; + } + + } + if (widget.optionType == OPTION_USABLE || widget.type == TYPE_INVENTORY) { + widget.selectedActionName = buffer.readString(); + widget.spellName = buffer.readString(); + widget.spellUsableOn = buffer.readUShort(); + } + + if (widget.type == 8) + widget.defaultText = buffer.readString(); + + if (widget.optionType == OPTION_OK || widget.optionType == OPTION_TOGGLE_SETTING + || widget.optionType == OPTION_RESET_SETTING || widget.optionType == OPTION_CONTINUE) { + widget.tooltip = buffer.readString(); + if (widget.tooltip.length() == 0) { + // TODO + if (widget.optionType == OPTION_OK) + widget.tooltip = "Ok"; + if (widget.optionType == OPTION_TOGGLE_SETTING) + widget.tooltip = "Select"; + if (widget.optionType == OPTION_RESET_SETTING) + widget.tooltip = "Select"; + if (widget.optionType == OPTION_CONTINUE) + widget.tooltip = "Continue"; + } + } + } + interfaceLoader = interfaces; + clanChatTab(textDrawingAreas); + configureLunar(textDrawingAreas); + quickCurses(textDrawingAreas); + quickPrayers(textDrawingAreas); + edgevilleHomeTeleport(textDrawingAreas); + equipmentScreen(textDrawingAreas); + equipmentTab(textDrawingAreas); + itemsOnDeathDATA(textDrawingAreas); + itemsKeptOnDeath(textDrawingAreas); + itemsOnDeath(textDrawingAreas); + + repositionModernSpells(); + + spriteCache = null; + } + + public static void debugInterface() { + Widget widget = Widget.interfaceCache[12424]; + for (int i = 0; i < widget.children.length; i++) { + System.out.println("childX: " + widget.childX[i] + " childY: " + widget.childY[i] + " index: " + i + + " spellId: " + widget.children[i]); + } + } + + public static void repositionModernSpells() { + + Widget widget = Widget.interfaceCache[12424]; + for (int index = 0; index < widget.children.length; index++) { + + switch (widget.children[index]) { + + case 1185: + widget.childX[33] = 148; + widget.childY[33] = 150; + break; + + case 1183: // wind wave + widget.childX[31] = 76; + widget.childY[31] = 149; + break; + + case 1188: // earth wave + widget.childX[36] = 71; + widget.childY[36] = 172; + break; + + case 1543: + widget.childX[46] = 96; + widget.childY[46] = 173; + break; + + case 1193: // charge + widget.childX[41] = 49; + widget.childY[41] = 198; + break; + + case 12435: // tele other falador + widget.childX[54] = 74; + widget.childY[54] = 198; + break; + + case 12445: // teleblock + widget.childX[55] = 99; + widget.childY[55] = 198; + break; + + case 6003: // lvl 6 enchant + widget.childX[57] = 122; + widget.childY[57] = 198; + break; + + // 150 x is end of the line + + case 12455: // tele other camelot + widget.childX[56] = 147; + widget.childY[56] = 198; + break; + } + } + } + + public static void itemsKeptOnDeath(GameFont[] tda) { + Widget Interface = addInterface(22030); + addSprite(22031, 214); + addHoverButton(22032, 215, 17, 17, "Close", 250, 22033, 3); + addHoveredButton(22033, 216, 17, 17, 22034); + addText(22035, "", tda, 0, 0xff981f, false, true); + addText(22036, "", tda, 0, 0xff981f, false, true); + addText(22037, "", tda, 0, 0xff981f, false, true); + addText(22038, "", tda, 0, 0xff981f, false, true); + addText(22039, "", tda, 0, 0xff981f, false, true); + addText(22040, "", tda, 1, 0xffcc33, false, true); + setChildren(9, Interface); + setBounds(22031, 7, 8, 0, Interface); + setBounds(22032, 480, 18, 1, Interface); + setBounds(22033, 480, 18, 2, Interface); + setBounds(22035, 348, 98, 3, Interface); + setBounds(22036, 348, 110, 4, Interface); + setBounds(22037, 348, 122, 5, Interface); + setBounds(22038, 348, 134, 6, Interface); + setBounds(22039, 348, 146, 7, Interface); + setBounds(22040, 398, 297, 8, Interface); + } + + public static void clanChatTab(GameFont[] tda) { + Widget tab = addTabInterface(37128); + addHoverButton(37129, 208, 72, 32, "Join Chat", -1, 37130, 5); + addHoveredButton(37130, 209, 72, 32, 37131); + addHoverButton(37132, 208, 72, 32, "Clan Setup", -1, 37133, 5); + addHoveredButton(37133, 209, 72, 32, 37134); + addText(37135, "Join Chat", tda, 0, 0xff9b00, true, true); + addText(37136, "Clan Setup", tda, 0, 0xff9b00, true, true); + addSprite(37137, 210); + addText(37138, "Clan Chat", tda, 1, 0xff9b00, true, true); + addText(37139, "Talking in: Not in chat", tda, 0, 0xff9b00, false, true); + addText(37140, "Owner: None", tda, 0, 0xff9b00, false, true); + tab.totalChildren(13); + tab.child(0, 16126, 0, 221); + tab.child(1, 16126, 0, 59); + tab.child(2, 37137, 0, 62); + tab.child(3, 37143, 0, 62); + tab.child(4, 37129, 15, 226); + tab.child(5, 37130, 15, 226); + tab.child(6, 37132, 103, 226); + tab.child(7, 37133, 103, 226); + tab.child(8, 37135, 51, 237); + tab.child(9, 37136, 139, 237); + tab.child(10, 37138, 95, 1); + tab.child(11, 37139, 10, 23); + tab.child(12, 37140, 25, 38); + /* Text area */ + Widget list = addTabInterface(37143); + list.totalChildren(100); + for (int i = 37144; i <= 37244; i++) { + addText(i, "", tda, 0, 0xffffff, false, true); + } + for (int id = 37144, i = 0; id <= 37243 && i <= 99; id++, i++) { + interfaceCache[id].actions = new String[] { "Kick" }; + list.children[i] = id; + list.childX[i] = 5; + for (int id2 = 37144, i2 = 1; id2 <= 37243 && i2 <= 99; id2++, i2++) { + list.childY[0] = 2; + list.childY[i2] = list.childY[i2 - 1] + 14; + } + } + list.height = 158; + list.width = 174; + list.scrollMax = 1405; + } + + public static void addHoverText2(int id, String text, String[] tooltips, GameFont tda[], int idx, int color, + boolean center, boolean textShadowed, int width) { + Widget rsinterface = addInterface(id); + rsinterface.id = id; + rsinterface.parent = id; + rsinterface.type = 4; + rsinterface.optionType = 1; + rsinterface.width = width; + rsinterface.height = 11; + rsinterface.contentType = 0; + rsinterface.opacity = 0; + rsinterface.hoverType = -1; + rsinterface.centerText = center; + rsinterface.textShadow = textShadowed; + rsinterface.textDrawingAreas = tda[idx]; + rsinterface.defaultText = text; + rsinterface.secondaryText = ""; + rsinterface.textColor = color; + rsinterface.secondaryColor = 0; + rsinterface.defaultHoverColor = 0xffffff; + rsinterface.secondaryHoverColor = 0; + rsinterface.tooltips = tooltips; + } + + public static void addText2(int id, String text, GameFont tda[], int idx, int color, boolean center, + boolean shadow) { + Widget tab = addTabInterface(id); + tab.parent = id; + tab.id = id; + tab.type = 4; + tab.optionType = 0; + tab.width = 0; + tab.height = 11; + tab.contentType = 0; + tab.opacity = 0; + tab.hoverType = -1; + tab.centerText = center; + tab.textShadow = shadow; + tab.textDrawingAreas = tda[idx]; + tab.defaultText = text; + tab.secondaryText = ""; + tab.textColor = color; + tab.secondaryColor = 0; + tab.defaultHoverColor = 0; + tab.secondaryHoverColor = 0; + } + + public static void addSprite(int interfaceId, int disabledSpriteId, int enabledSpriteId) { + Widget rsinterface = interfaceCache[interfaceId] = new Widget(); + rsinterface.id = interfaceId; + rsinterface.parent = interfaceId; + rsinterface.type = 5; + rsinterface.optionType = 1; + rsinterface.contentType = 0; + rsinterface.width = 20; + rsinterface.height = 20; + rsinterface.opacity = 0; + rsinterface.mOverInterToTrigger = 52; + rsinterface.disabledSprite = SpriteCache.lookup(disabledSpriteId); + rsinterface.enabledSprite = SpriteCache.lookup(enabledSpriteId); + } + + public static void addText(int id, String text, GameFont wid[], int idx, int color) { + Widget rsinterface = addTabInterface(id); + rsinterface.id = id; + rsinterface.parent = id; + rsinterface.type = 4; + rsinterface.optionType = 0; + rsinterface.width = 174; + rsinterface.height = 11; + rsinterface.contentType = 0; + rsinterface.opacity = 0; + rsinterface.mOverInterToTrigger = -1; + rsinterface.centerText = false; + rsinterface.textShadow = true; + rsinterface.textDrawingAreas = wid[idx]; + rsinterface.defaultText = text; + rsinterface.secondaryText = ""; + rsinterface.textColor = color; + rsinterface.secondaryColor = 0; + rsinterface.defaultHoverColor = 0; + rsinterface.secondaryHoverColor = 0; + } + + public static void itemsOnDeath(GameFont[] wid) { + Widget rsinterface = addInterface(17100); + addSprite(17101, 102); + // addHover(17102,"Items Kept On Death/SPRITE", 1, 17, 17, "Close", 0, + // 10602, 1); + // addHovered(10602,"Items Kept On Death/SPRITE", 3, 17, 17, 10603); + addText(17103, "Items kept on death", wid, 2, 0xff981f); + addText(17104, "Items I will keep...", wid, 1, 0xff981f); + addText(17105, "Items I will lose...", wid, 1, 0xff981f); + addText(17106, "Info", wid, 1, 0xff981f); + addText(17107, "", wid, 1, 0xffcc33); + addText(17108, "", wid, 1, 0xffcc33); + // rsinterface.scrollMax = 50; + rsinterface.interfaceShown = false; + rsinterface.children = new int[12]; + rsinterface.childX = new int[12]; + rsinterface.childY = new int[12]; + + rsinterface.children[0] = 17101; + rsinterface.childX[0] = 7; + rsinterface.childY[0] = 8; + rsinterface.children[1] = 15210; + rsinterface.childX[1] = 478; + rsinterface.childY[1] = 17; + rsinterface.children[2] = 17103; + rsinterface.childX[2] = 185; + rsinterface.childY[2] = 18; + rsinterface.children[3] = 17104; + rsinterface.childX[3] = 22; + rsinterface.childY[3] = 49; + rsinterface.children[4] = 17105; + rsinterface.childX[4] = 22; + rsinterface.childY[4] = 109; + rsinterface.children[5] = 17106; + rsinterface.childX[5] = 347; + rsinterface.childY[5] = 49; + rsinterface.children[6] = 17107; + rsinterface.childX[6] = 348; + rsinterface.childY[6] = 270; + rsinterface.children[7] = 17108; + rsinterface.childX[7] = 401; + rsinterface.childY[7] = 293; + rsinterface.children[8] = 17115; + rsinterface.childX[8] = 348; + rsinterface.childY[8] = 64; + rsinterface.children[9] = 10494; + rsinterface.childX[9] = 26; + rsinterface.childY[9] = 71; + rsinterface.children[10] = 10600; + rsinterface.childX[10] = 26; + rsinterface.childY[10] = 129; + rsinterface.children[11] = 15211; + rsinterface.childX[11] = 478; + rsinterface.childY[11] = 17; + rsinterface = interfaceCache[10494]; + rsinterface.spritePaddingX = 6; + rsinterface.spritePaddingY = 5; + rsinterface = interfaceCache[10600]; + rsinterface.spritePaddingX = 6; + rsinterface.spritePaddingY = 5; + } + + public static void itemsOnDeathDATA(GameFont[] tda) { + Widget RSinterface = addInterface(17115); + addText(17109, "", 0xff981f, false, false, 0, tda, 0); + addText(17110, "The normal amount of", 0xff981f, false, false, 0, tda, 0); + addText(17111, "items kept is three.", 0xff981f, false, false, 0, tda, 0); + addText(17112, "", 0xff981f, false, false, 0, tda, 0); + addText(17113, "If you are skulled,", 0xff981f, false, false, 0, tda, 0); + addText(17114, "you will lose all your", 0xff981f, false, false, 0, tda, 0); + addText(17117, "items, unless an item", 0xff981f, false, false, 0, tda, 0); + addText(17118, "protecting prayer is", 0xff981f, false, false, 0, tda, 0); + addText(17119, "used.", 0xff981f, false, false, 0, tda, 0); + addText(17120, "", 0xff981f, false, false, 0, tda, 0); + addText(17121, "Item protecting prayers", 0xff981f, false, false, 0, tda, 0); + addText(17122, "will allow you to keep", 0xff981f, false, false, 0, tda, 0); + addText(17123, "one extra item.", 0xff981f, false, false, 0, tda, 0); + addText(17124, "", 0xff981f, false, false, 0, tda, 0); + addText(17125, "The items kept are", 0xff981f, false, false, 0, tda, 0); + addText(17126, "selected by the server", 0xff981f, false, false, 0, tda, 0); + addText(17127, "and include the most", 0xff981f, false, false, 0, tda, 0); + addText(17128, "expensive items you're", 0xff981f, false, false, 0, tda, 0); + addText(17129, "carrying.", 0xff981f, false, false, 0, tda, 0); + addText(17130, "", 0xff981f, false, false, 0, tda, 0); + RSinterface.parent = 17115; + RSinterface.id = 17115; + RSinterface.type = 0; + RSinterface.optionType = 0; + RSinterface.contentType = 0; + RSinterface.width = 130; + RSinterface.height = 197; + RSinterface.opacity = 0; + RSinterface.hoverType = -1; + RSinterface.scrollMax = 280; + RSinterface.children = new int[20]; + RSinterface.childX = new int[20]; + RSinterface.childY = new int[20]; + RSinterface.children[0] = 17109; + RSinterface.childX[0] = 0; + RSinterface.childY[0] = 0; + RSinterface.children[1] = 17110; + RSinterface.childX[1] = 0; + RSinterface.childY[1] = 12; + RSinterface.children[2] = 17111; + RSinterface.childX[2] = 0; + RSinterface.childY[2] = 24; + RSinterface.children[3] = 17112; + RSinterface.childX[3] = 0; + RSinterface.childY[3] = 36; + RSinterface.children[4] = 17113; + RSinterface.childX[4] = 0; + RSinterface.childY[4] = 48; + RSinterface.children[5] = 17114; + RSinterface.childX[5] = 0; + RSinterface.childY[5] = 60; + RSinterface.children[6] = 17117; + RSinterface.childX[6] = 0; + RSinterface.childY[6] = 72; + RSinterface.children[7] = 17118; + RSinterface.childX[7] = 0; + RSinterface.childY[7] = 84; + RSinterface.children[8] = 17119; + RSinterface.childX[8] = 0; + RSinterface.childY[8] = 96; + RSinterface.children[9] = 17120; + RSinterface.childX[9] = 0; + RSinterface.childY[9] = 108; + RSinterface.children[10] = 17121; + RSinterface.childX[10] = 0; + RSinterface.childY[10] = 120; + RSinterface.children[11] = 17122; + RSinterface.childX[11] = 0; + RSinterface.childY[11] = 132; + RSinterface.children[12] = 17123; + RSinterface.childX[12] = 0; + RSinterface.childY[12] = 144; + RSinterface.children[13] = 17124; + RSinterface.childX[13] = 0; + RSinterface.childY[13] = 156; + RSinterface.children[14] = 17125; + RSinterface.childX[14] = 0; + RSinterface.childY[14] = 168; + RSinterface.children[15] = 17126; + RSinterface.childX[15] = 0; + RSinterface.childY[15] = 180; + RSinterface.children[16] = 17127; + RSinterface.childX[16] = 0; + RSinterface.childY[16] = 192; + RSinterface.children[17] = 17128; + RSinterface.childX[17] = 0; + RSinterface.childY[17] = 204; + RSinterface.children[18] = 17129; + RSinterface.childX[18] = 0; + RSinterface.childY[18] = 216; + RSinterface.children[19] = 17130; + RSinterface.childX[19] = 0; + RSinterface.childY[19] = 228; + } + + public static void equipmentTab(GameFont[] wid) { + Widget Interface = interfaceCache[1644]; + + removeConfig(21338); + removeConfig(21344); + removeConfig(21342); + removeConfig(21341); + removeConfig(21340); + removeConfig(15103); + removeConfig(15104); + removeConfig(15109); + + Interface.children[24] = 15102; + Interface.childX[24] = 110; + Interface.childY[24] = 205; + Interface.children[25] = 15109; + Interface.childX[25] = 39; + Interface.childY[25] = 240; + Interface.children[26] = 27650; + Interface.childX[26] = 0; + Interface.childY[26] = 0; + Interface = addInterface(27650); + + addHoverButton(27651, 202, 40, 40, "Price-checker", -1, 27652, 1); + addHoveredButton(27652, 203, 40, 40, 27658); + + addHoverButton(27653, 204, 40, 40, "Show Equipment Stats", -1, 27655, 1); + addHoveredButton(27655, 205, 40, 40, 27665); + + addHoverButton(27654, 206, 40, 40, "Show items kept on death", -1, 27657, 1); + addHoveredButton(27657, 207, 40, 40, 27666); + + setChildren(6, Interface); + setBounds(27651, 75, 205, 0, Interface); + setBounds(27652, 75, 205, 1, Interface); + setBounds(27653, 23, 205, 2, Interface); + setBounds(27654, 127, 205, 3, Interface); + setBounds(27655, 23, 205, 4, Interface); + setBounds(27657, 127, 205, 5, Interface); + } + + public static void removeConfig(int id) { + @SuppressWarnings("unused") + Widget rsi = interfaceCache[id] = new Widget(); + } + + public static void addHoverText(int id, String text, String tooltip, GameFont tda[], int idx, int color, + boolean centerText, boolean textShadowed, int width) { + Widget rsinterface = addInterface(id); + rsinterface.id = id; + rsinterface.parent = id; + rsinterface.type = 4; + rsinterface.optionType = 1; + rsinterface.width = width; + rsinterface.height = 11; + rsinterface.contentType = 0; + rsinterface.opacity = 0; + rsinterface.mOverInterToTrigger = -1; + rsinterface.centerText = centerText; + rsinterface.textShadow = textShadowed; + rsinterface.textDrawingAreas = tda[idx]; + rsinterface.defaultText = text; + rsinterface.secondaryText = ""; + rsinterface.textColor = color; + rsinterface.secondaryColor = 0; + rsinterface.defaultHoverColor = 0xffffff; + rsinterface.secondaryHoverColor = 0; + rsinterface.tooltip = tooltip; + } + + public static void equipmentScreen(GameFont[] wid) { + Widget Interface = Widget.interfaceCache[1644]; + addButton(19144, 217, "Show Equipment Stats"); + removeComponent(19145); + removeComponent(19146); + removeComponent(19147); + setBounds(19145, 40, 210, 24, Interface); + setBounds(19146, 40, 210, 25, Interface); + setBounds(19147, 40, 210, 26, Interface); + Widget tab = addTabInterface(15106); + addSprite(15107, 211); + addHoverButton(15210, 212, 21, 21, "Close", 250, 15211, 3); + addHoveredButton(15211, 213, 21, 21, 15212); + addText(15111, "Equip Your Character...", wid, 2, 0xe4a146, false, true); + addText(15112, "Attack bonus", wid, 2, 0xe4a146, false, true); + addText(15113, "Defence bonus", wid, 2, 0xe4a146, false, true); + addText(15114, "Other bonuses", wid, 2, 0xe4a146, false, true); + + for (int i = 1675; i <= 1684; i++) { + textSize(i, wid, 1); + } + + textSize(1686, wid, 1); + textSize(1687, wid, 1); + addChar(15125); + tab.totalChildren(44); + tab.child(0, 15107, 4, 20); + tab.child(1, 15210, 476, 29); + tab.child(2, 15211, 476, 29); + tab.child(3, 15111, 14, 30); + int Child = 4; + int Y = 69; + for (int i = 1675; i <= 1679; i++) { + tab.child(Child, i, 20, Y); + Child++; + Y += 14; + } + tab.child(9, 1680, 20, 161); + tab.child(10, 1681, 20, 177); + tab.child(11, 1682, 20, 192); + tab.child(12, 1683, 20, 207); + tab.child(13, 1684, 20, 221); + tab.child(14, 1686, 20, 262); + tab.child(15, 15125, 170, 200); + tab.child(16, 15112, 16, 55); + tab.child(17, 1687, 20, 276); + tab.child(18, 15113, 16, 147); + tab.child(19, 15114, 16, 248); + tab.child(20, 1645, 104 + 295, 149 - 52); + tab.child(21, 1646, 399, 163); + tab.child(22, 1647, 399, 163); + tab.child(23, 1648, 399, 58 + 146); + tab.child(24, 1649, 26 + 22 + 297 - 2, 110 - 44 + 118 - 13 + 5); + tab.child(25, 1650, 321 + 22, 58 + 154); + tab.child(26, 1651, 321 + 134, 58 + 118); + tab.child(27, 1652, 321 + 134, 58 + 154); + tab.child(28, 1653, 321 + 48, 58 + 81); + tab.child(29, 1654, 321 + 107, 58 + 81); + tab.child(30, 1655, 321 + 58, 58 + 42); + tab.child(31, 1656, 321 + 112, 58 + 41); + tab.child(32, 1657, 321 + 78, 58 + 4); + tab.child(33, 1658, 321 + 37, 58 + 43); + tab.child(34, 1659, 321 + 78, 58 + 43); + tab.child(35, 1660, 321 + 119, 58 + 43); + tab.child(36, 1661, 321 + 22, 58 + 82); + tab.child(37, 1662, 321 + 78, 58 + 82); + tab.child(38, 1663, 321 + 134, 58 + 82); + tab.child(39, 1664, 321 + 78, 58 + 122); + tab.child(40, 1665, 321 + 78, 58 + 162); + tab.child(41, 1666, 321 + 22, 58 + 162); + tab.child(42, 1667, 321 + 134, 58 + 162); + tab.child(43, 1688, 50 + 297 - 2, 110 - 13 + 5); + for (int i = 1675; i <= 1684; i++) { + Widget rsi = interfaceCache[i]; + rsi.textColor = 0xe4a146; + rsi.centerText = false; + } + for (int i = 1686; i <= 1687; i++) { + Widget rsi = interfaceCache[i]; + rsi.textColor = 0xe4a146; + rsi.centerText = false; + } + } + + public static void addChar(int ID) { + Widget t = interfaceCache[ID] = new Widget(); + t.id = ID; + t.parent = ID; + t.type = 6; + t.optionType = 0; + t.contentType = 328; + t.width = 136; + t.height = 168; + t.opacity = 0; + t.mOverInterToTrigger = 0; + t.modelZoom = 560; + t.modelRotation1 = 150; + t.modelRotation2 = 0; + t.defaultAnimationId = -1; + t.secondaryAnimationId = -1; + } + + public static void edgevilleHomeTeleport(GameFont[] TDA) { + Widget rsi = interfaceCache[21741]; + rsi.optionType = 1; + rsi.tooltip = "Cast @gre@Edgeville Home Teleport"; + } + + public static void addButton(int id, int sid, String tooltip) { + Widget tab = interfaceCache[id] = new Widget(); + tab.id = id; + tab.parent = id; + tab.type = 5; + tab.optionType = 1; + tab.contentType = 0; + tab.opacity = (byte) 0; + tab.hoverType = 52; + tab.disabledSprite = SpriteCache.lookup(sid); + tab.enabledSprite = SpriteCache.lookup(sid); + tab.width = tab.disabledSprite.getMyWidth(); + tab.height = tab.enabledSprite.getMyHeight(); + tab.tooltip = tooltip; + } + + public String popupString; + + public static void addTooltipBox(int id, String text) { + Widget rsi = addInterface(id); + rsi.id = id; + rsi.parent = id; + rsi.type = 8; + rsi.popupString = text; + } + + public static void addTooltip(int id, String text) { + Widget rsi = addInterface(id); + rsi.id = id; + rsi.type = 0; + rsi.invisible = true; + rsi.hoverType = -1; + addTooltipBox(id + 1, text); + rsi.totalChildren(1); + rsi.child(0, id + 1, 0, 0); + } + + public static Widget addInterface(int id) { + Widget rsi = interfaceCache[id] = new Widget(); + rsi.id = id; + rsi.parent = id; + rsi.width = 512; + rsi.height = 334; + return rsi; + } + + public static void addText(int id, String text, GameFont tda[], int idx, int color, boolean centered) { + Widget rsi = interfaceCache[id] = new Widget(); + if (centered) + rsi.centerText = true; + rsi.textShadow = true; + rsi.textDrawingAreas = tda[idx]; + rsi.defaultText = text; + rsi.textColor = color; + rsi.id = id; + rsi.type = 4; + } + + public static void textColor(int id, int color) { + Widget rsi = interfaceCache[id]; + rsi.textColor = color; + } + + public static void textSize(int id, GameFont tda[], int idx) { + Widget rsi = interfaceCache[id]; + rsi.textDrawingAreas = tda[idx]; + } + + public static void addCacheSprite(int id, int sprite1, int sprite2, String sprites) { + Widget rsi = interfaceCache[id] = new Widget(); + rsi.disabledSprite = getSprite(sprite1, interfaceLoader, sprites); + rsi.enabledSprite = getSprite(sprite2, interfaceLoader, sprites); + rsi.parent = id; + rsi.id = id; + rsi.type = 5; + } + + public void totalChildren(int id, int x, int y) { + children = new int[id]; + childX = new int[x]; + childY = new int[y]; + } + + public static void removeComponent(int id) { + @SuppressWarnings("unused") + Widget rsi = interfaceCache[id] = new Widget(); + } + + public static void quickCurses(GameFont[] TDA) { + Widget tab = addTabInterface(17234); + addTransparentSprite(17229, 96, 50); + addSprite(17201, 99); + addText(17230, "Select your quick prayers:", TDA, 0, 0xFF981F, false, true); + + for (int i = 17202, j = 630; i <= 17228 || j <= 656; i++, j++) { + addConfigButton(i, 17200, 98, 97, 14, 15, "Select", 0, 1, j); + } + + addHoverButton(17231, 100, 190, 24, "Confirm Selection", -1, 17232, 1); + addHoveredButton(17232, 101, 190, 24, 17233); + int frame = 0; + setChildren(46, tab); + setBounds(21358, 11, 8 + 20, frame++, tab); + setBounds(21360, 50, 11 + 20, frame++, tab); + setBounds(21362, 87, 11 + 20, frame++, tab); + setBounds(21364, 122, 10 + 20, frame++, tab); + setBounds(21366, 159, 11 + 20, frame++, tab); + setBounds(21368, 12, 45 + 20, frame++, tab); + setBounds(21370, 46, 45 + 20, frame++, tab); + setBounds(21372, 83, 46 + 20, frame++, tab); + setBounds(21374, 119, 45 + 20, frame++, tab); + setBounds(21376, 157, 45 + 20, frame++, tab); + setBounds(21378, 11, 83 + 20, frame++, tab); + setBounds(21380, 49, 84 + 20, frame++, tab); + setBounds(21382, 84, 83 + 20, frame++, tab); + setBounds(21384, 123, 84 + 20, frame++, tab); + setBounds(21386, 159, 83 + 20, frame++, tab); + setBounds(21388, 12, 119 + 20, frame++, tab); + setBounds(21390, 49, 119 + 20, frame++, tab); + setBounds(21392, 88, 119 + 20, frame++, tab); + setBounds(21394, 122, 121 + 20, frame++, tab); + setBounds(21396, 155, 122 + 20, frame++, tab); + setBounds(17229, 0, 25, frame++, tab);// Faded backing + setBounds(17201, 0, 22, frame++, tab);// Split + setBounds(17201, 0, 237, frame++, tab);// Split + setBounds(17202, 13 - 3, 8 + 17, frame++, tab); + setBounds(17203, 52 - 3, 8 + 17, frame++, tab); + setBounds(17204, 90 - 3, 8 + 17, frame++, tab); + setBounds(17205, 126 - 3, 8 + 17, frame++, tab); + setBounds(17206, 162 - 3, 8 + 17, frame++, tab); + setBounds(17207, 13 - 3, 45 + 17, frame++, tab); + setBounds(17208, 52 - 3, 45 + 17, frame++, tab); + setBounds(17209, 90 - 3, 45 + 17, frame++, tab); + setBounds(17210, 126 - 3, 45 + 17, frame++, tab); + setBounds(17211, 162 - 3, 45 + 17, frame++, tab); + setBounds(17212, 13 - 3, 80 + 17, frame++, tab); + setBounds(17213, 52 - 3, 80 + 17, frame++, tab); + setBounds(17214, 90 - 3, 80 + 17, frame++, tab); + setBounds(17215, 126 - 3, 80 + 17, frame++, tab); + setBounds(17216, 162 - 3, 80 + 17, frame++, tab); + setBounds(17217, 13 - 3, 119 + 17, frame++, tab); + setBounds(17218, 52 - 3, 119 + 17, frame++, tab); + setBounds(17219, 90 - 3, 119 + 17, frame++, tab); + setBounds(17220, 126 - 3, 119 + 17, frame++, tab); + setBounds(17221, 162 - 3, 119 + 17, frame++, tab); + setBounds(17230, 5, 5, frame++, tab);// text + setBounds(17231, 0, 237, frame++, tab);// confirm + setBounds(17232, 0, 237, frame++, tab);// Confirm hover + } + + public static void quickPrayers(GameFont[] TDA) { + int frame = 0; + Widget tab = addTabInterface(17200); + + setChildren(58, tab);// + setBounds(5632, 5, 8 + 20, frame++, tab); + setBounds(5633, 44, 8 + 20, frame++, tab); + setBounds(5634, 79, 11 + 20, frame++, tab); + setBounds(19813, 116, 10 + 20, frame++, tab); + setBounds(19815, 153, 9 + 20, frame++, tab); + setBounds(5635, 5, 48 + 20, frame++, tab); + setBounds(5636, 44, 47 + 20, frame++, tab); + setBounds(5637, 79, 49 + 20, frame++, tab); + setBounds(5638, 116, 50 + 20, frame++, tab); + setBounds(5639, 154, 50 + 20, frame++, tab); + setBounds(5640, 4, 84 + 20, frame++, tab); + setBounds(19817, 44, 87 + 20, frame++, tab); + setBounds(19820, 81, 85 + 20, frame++, tab); + setBounds(5641, 117, 85 + 20, frame++, tab); + setBounds(5642, 156, 87 + 20, frame++, tab); + setBounds(5643, 5, 125 + 20, frame++, tab); + setBounds(5644, 43, 124 + 20, frame++, tab); + setBounds(13984, 83, 124 + 20, frame++, tab); + setBounds(5645, 115, 121 + 20, frame++, tab); + setBounds(19822, 154, 124 + 20, frame++, tab); + setBounds(19824, 5, 160 + 20, frame++, tab); + setBounds(5649, 41, 158 + 20, frame++, tab); + setBounds(5647, 79, 163 + 20, frame++, tab); + setBounds(5648, 116, 158 + 20, frame++, tab); + setBounds(19826, 161, 160 + 20, frame++, tab); + setBounds(19828, 4, 207 + 12, frame++, tab); + + setBounds(17229, 0, 25, frame++, tab);// Faded backing + setBounds(17201, 0, 22, frame++, tab);// Split + setBounds(17201, 0, 237, frame++, tab);// Split + + setBounds(17202, 5 - 3, 8 + 17, frame++, tab); + setBounds(17203, 44 - 3, 8 + 17, frame++, tab); + setBounds(17204, 79 - 3, 8 + 17, frame++, tab); + setBounds(17205, 116 - 3, 8 + 17, frame++, tab); + setBounds(17206, 153 - 3, 8 + 17, frame++, tab); + setBounds(17207, 5 - 3, 48 + 17, frame++, tab); + setBounds(17208, 44 - 3, 48 + 17, frame++, tab); + setBounds(17209, 79 - 3, 48 + 17, frame++, tab); + setBounds(17210, 116 - 3, 48 + 17, frame++, tab); + setBounds(17211, 153 - 3, 48 + 17, frame++, tab); + setBounds(17212, 5 - 3, 85 + 17, frame++, tab); + setBounds(17213, 44 - 3, 85 + 17, frame++, tab); + setBounds(17214, 79 - 3, 85 + 17, frame++, tab); + setBounds(17215, 116 - 3, 85 + 17, frame++, tab); + setBounds(17216, 153 - 3, 85 + 17, frame++, tab); + setBounds(17217, 5 - 3, 124 + 17, frame++, tab); + setBounds(17218, 44 - 3, 124 + 17, frame++, tab); + setBounds(17219, 79 - 3, 124 + 17, frame++, tab); + setBounds(17220, 116 - 3, 124 + 17, frame++, tab); + setBounds(17221, 153 - 3, 124 + 17, frame++, tab); + setBounds(17222, 5 - 3, 160 + 17, frame++, tab); + setBounds(17223, 44 - 3, 160 + 17, frame++, tab); + setBounds(17224, 79 - 3, 160 + 17, frame++, tab); + setBounds(17225, 116 - 3, 160 + 17, frame++, tab); + setBounds(17226, 153 - 3, 160 + 17, frame++, tab); + setBounds(17227, 4 - 3, 207 + 4, frame++, tab); + + setBounds(17230, 5, 5, frame++, tab);// text + setBounds(17231, 0, 237, frame++, tab);// confirm + setBounds(17232, 0, 237, frame++, tab);// Confirm hover + } + + public int transparency; + + private static void addTransparentSprite(int id, int spriteId, int transparency) { + Widget tab = interfaceCache[id] = new Widget(); + tab.id = id; + tab.parent = id; + tab.type = 5; + tab.optionType = 0; + tab.contentType = 0; + tab.transparency = (byte) transparency; + tab.hoverType = 52; + tab.disabledSprite = SpriteCache.lookup(spriteId); + tab.enabledSprite = SpriteCache.lookup(spriteId); + tab.width = 512; + tab.height = 334; + tab.drawsTransparent = true; + } + + public static void Pestpanel(GameFont[] tda) { + Widget RSinterface = addInterface(21119); + addText(21120, "What", 0x999999, false, true, 52, tda, 1); + addText(21121, "What", 0x33cc00, false, true, 52, tda, 1); + addText(21122, "(Need 5 to 25 players)", 0xFFcc33, false, true, 52, tda, 1); + addText(21123, "Points", 0x33ccff, false, true, 52, tda, 1); + int last = 4; + RSinterface.children = new int[last]; + RSinterface.childX = new int[last]; + RSinterface.childY = new int[last]; + setBounds(21120, 15, 12, 0, RSinterface); + setBounds(21121, 15, 30, 1, RSinterface); + setBounds(21122, 15, 48, 2, RSinterface); + setBounds(21123, 15, 66, 3, RSinterface); + } + + public String hoverText; + + public static void addHoverBox(int id, int ParentID, String text, String text2, int configId, int configFrame) { + Widget rsi = addTabInterface(id); + rsi.id = id; + rsi.parent = ParentID; + rsi.type = 8; + rsi.secondaryText = text; + rsi.defaultText = text2; + rsi.scriptOperators = new int[1]; + rsi.scriptDefaults = new int[1]; + rsi.scriptOperators[0] = 1; + rsi.scriptDefaults[0] = configId; + rsi.scripts = new int[1][3]; + rsi.scripts[0][0] = 5; + rsi.scripts[0][1] = configFrame; + rsi.scripts[0][2] = 0; + } + + public static void addText(int id, String text, GameFont tda[], int idx, int color, boolean center, + boolean shadow) { + Widget tab = addTabInterface(id); + tab.parent = id; + tab.id = id; + tab.type = 4; + tab.optionType = 0; + tab.width = 0; + tab.height = 11; + tab.contentType = 0; + tab.opacity = 0; + tab.hoverType = -1; + tab.centerText = center; + tab.textShadow = shadow; + tab.textDrawingAreas = tda[idx]; + tab.defaultText = text; + tab.secondaryText = ""; + tab.textColor = color; + tab.secondaryColor = 0; + tab.defaultHoverColor = 0; + tab.secondaryHoverColor = 0; + } + + public static void addText(int i, String s, int k, boolean l, boolean m, int a, GameFont[] TDA, int j) { + Widget RSInterface = addInterface(i); + RSInterface.parent = i; + RSInterface.id = i; + RSInterface.type = 4; + RSInterface.optionType = 0; + RSInterface.width = 0; + RSInterface.height = 0; + RSInterface.contentType = 0; + RSInterface.opacity = 0; + RSInterface.hoverType = a; + RSInterface.centerText = l; + RSInterface.textShadow = m; + RSInterface.textDrawingAreas = TDA[j]; + RSInterface.defaultText = s; + RSInterface.secondaryText = ""; + RSInterface.textColor = k; + } + + public static void addButton(int id, int sid, String tooltip, int w, int h) { + Widget tab = interfaceCache[id] = new Widget(); + tab.id = id; + tab.parent = id; + tab.type = 5; + tab.optionType = 1; + tab.contentType = 0; + tab.opacity = (byte) 0; + tab.hoverType = 52; + tab.disabledSprite = SpriteCache.lookup(sid); + tab.enabledSprite = SpriteCache.lookup(sid); + tab.width = w; + tab.height = h; + tab.tooltip = tooltip; + } + + public static void addConfigButton(int ID, int pID, int disabledSpriteId, int enabledSpriteId, int width, int height, + String tT, int configID, int aT, int configFrame) { + Widget Tab = addTabInterface(ID); + Tab.parent = pID; + Tab.id = ID; + Tab.type = 5; + Tab.optionType = aT; + Tab.contentType = 0; + Tab.width = width; + Tab.height = height; + Tab.opacity = 0; + Tab.hoverType = -1; + Tab.scriptOperators = new int[1]; + Tab.scriptDefaults = new int[1]; + Tab.scriptOperators[0] = 1; + Tab.scriptDefaults[0] = configID; + Tab.scripts = new int[1][3]; + Tab.scripts[0][0] = 5; + Tab.scripts[0][1] = configFrame; + Tab.scripts[0][2] = 0; + Tab.disabledSprite = SpriteCache.lookup(disabledSpriteId); + Tab.enabledSprite = SpriteCache.lookup(enabledSpriteId); + Tab.tooltip = tT; + } + + public static void addSprite(int id, int spriteId) { + Widget tab = interfaceCache[id] = new Widget(); + tab.id = id; + tab.parent = id; + tab.type = 5; + tab.optionType = 0; + tab.contentType = 0; + tab.opacity = (byte) 0; + tab.hoverType = 52; + tab.disabledSprite = SpriteCache.lookup(spriteId); + tab.enabledSprite = SpriteCache.lookup(spriteId); + tab.width = 512; + tab.height = 334; + } + + public static void addHoverButton(int i, int spriteId, int width, int height, String text, + int contentType, int hoverOver, int aT) { + + Widget tab = addTabInterface(i); + tab.id = i; + tab.parent = i; + tab.type = 5; + tab.optionType = aT; + tab.contentType = contentType; + tab.opacity = 0; + tab.hoverType = hoverOver; + tab.disabledSprite = SpriteCache.lookup(spriteId); + tab.enabledSprite = SpriteCache.lookup(spriteId); + tab.width = width; + tab.height = height; + tab.tooltip = text; + } + + public static void addHoveredButton(int i, int j, int w, int h, int spriteId) { + Widget tab = addTabInterface(i); + tab.parent = i; + tab.id = i; + tab.type = 0; + tab.optionType = 0; + tab.width = w; + tab.height = h; + tab.invisible = true; + tab.opacity = 0; + tab.hoverType = -1; + tab.scrollMax = 0; + addHoverImage(spriteId, j, j); + tab.totalChildren(1); + tab.child(0, spriteId, 0, 0); + } + + public static void addHoverImage(int i, int disabledSpriteId, int enabledSpriteId) { + Widget tab = addTabInterface(i); + tab.id = i; + tab.parent = i; + tab.type = 5; + tab.optionType = 0; + tab.contentType = 0; + tab.width = 512; + tab.height = 334; + tab.opacity = 0; + tab.hoverType = 52; + tab.disabledSprite = SpriteCache.lookup(disabledSpriteId); + tab.enabledSprite = SpriteCache.lookup(enabledSpriteId); + } + + public static void addTransparentSprite(int id, int spriteId) { + Widget tab = interfaceCache[id] = new Widget(); + tab.id = id; + tab.parent = id; + tab.type = 5; + tab.optionType = 0; + tab.contentType = 0; + tab.opacity = (byte) 0; + tab.hoverType = 52; + tab.disabledSprite = SpriteCache.lookup(spriteId); + tab.enabledSprite = SpriteCache.lookup(spriteId); + tab.width = 512; + tab.height = 334; + tab.drawsTransparent = true; + } + + public static Widget addScreenInterface(int id) { + Widget tab = interfaceCache[id] = new Widget(); + tab.id = id; + tab.parent = id; + tab.type = 0; + tab.optionType = 0; + tab.contentType = 0; + tab.width = 512; + tab.height = 334; + tab.opacity = (byte) 0; + tab.hoverType = 0; + return tab; + } + + public static Widget addTabInterface(int id) { + Widget tab = interfaceCache[id] = new Widget(); + tab.id = id;// 250 + tab.parent = id;// 236 + tab.type = 0;// 262 + tab.optionType = 0;// 217 + tab.contentType = 0; + tab.width = 512;// 220 + tab.height = 700;// 267 + tab.opacity = (byte) 0; + tab.hoverType = -1;// Int 230 + return tab; + } + + public void child(int id, int interID, int x, int y) { + children[id] = interID; + childX[id] = x; + childY[id] = y; + } + + public void totalChildren(int t) { + children = new int[t]; + childX = new int[t]; + childY = new int[t]; + } + + private Model getModel(int type, int mobId) { + Model model = (Model) models.get((type << 16) + mobId); + + if (model != null) { + return model; + } + + if (type == 1) { + model = Model.getModel(mobId); + } + + if (type == 2) { + model = NpcDefinition.lookup(mobId).model(); + } + + if (type == 3) { + model = Client.localPlayer.getHeadModel(); + } + + if (type == 4) { + model = ItemDefinition.lookup(mobId).getUnshadedModel(50); + } + + if (type == 5) { + model = null; + } + + if (model != null) { + models.put(model, (type << 16) + mobId); + } + + return model; + } + + private static Sprite getSprite(int i, FileArchive streamLoader, String s) { + long l = (StringUtils.hashSpriteName(s) << 8) + (long) i; + Sprite sprite = (Sprite) spriteCache.get(l); + if (sprite != null) + return sprite; + try { + sprite = new Sprite(streamLoader, s, i); + spriteCache.put(sprite, l); + } catch (Exception _ex) { + return null; + } + return sprite; + } + + public static void method208(boolean flag, Model model) { + int i = 0;// was parameter + int j = 5;// was parameter + if (flag) + return; + models.clear(); + if (model != null && j != 4) + models.put(model, (j << 16) + i); + } + + public Model method209(int j, int k, boolean flag) { + Model model; + if (flag) + model = getModel(anInt255, anInt256); + else + model = getModel(defaultMediaType, defaultMedia); + if (model == null) + return null; + if (k == -1 && j == -1 && model.triangleColours == null) + return model; + Model model_1 = new Model(true, Frame.noAnimationInProgress(k) & Frame.noAnimationInProgress(j), false, model); + if (k != -1 || j != -1) + model_1.skin(); + if (k != -1) + model_1.applyTransform(k); + if (j != -1) + model_1.applyTransform(j); + model_1.light(64, 768, -50, -10, -50, true); + return model_1; + } + + + public Widget() { + } + + public static FileArchive interfaceLoader; + public boolean drawsTransparent; + public Sprite disabledSprite; + public int lastFrameTime; + + public Sprite sprites[]; + public static Widget interfaceCache[]; + public int scriptDefaults[]; + public int contentType; + public int spritesX[]; + public int defaultHoverColor; + public int optionType; + public String spellName; + public int secondaryColor; + public int width; + public String tooltip; + public String selectedActionName; + public boolean centerText; + public int scrollPosition; + public String actions[]; + public int scripts[][]; + public boolean filled; + public String secondaryText; + public int hoverType; + public int spritePaddingX; + public int textColor; + public int defaultMediaType; + public int defaultMedia; + public boolean replaceItems; + public int parent; + public int spellUsableOn; + private static ReferenceCache spriteCache; + public int secondaryHoverColor; + public int children[]; + public int childX[]; + public boolean usableItems; + public GameFont textDrawingAreas; + public int spritePaddingY; + public int scriptOperators[]; + public int currentFrame; + public int spritesY[]; + public String defaultText; + public boolean hasActions; + public int id; + public int inventoryAmounts[]; + public int inventoryItemId[]; + public byte opacity; + private int anInt255; + private int anInt256; + public int defaultAnimationId; + public int secondaryAnimationId; + + public boolean aBoolean259; + public Sprite enabledSprite; + public int scrollMax; + public int type; + public int x; + private static final ReferenceCache models = new ReferenceCache(30); + public int anInt265; + public boolean invisible; + public int height; + public boolean textShadow; + public int modelZoom; + public int modelRotation1; + public int modelRotation2; + public int childY[]; + + public static void addLunarSprite(int i, int spriteId) { + Widget RSInterface = addInterface(i); + RSInterface.id = i; + RSInterface.parent = i; + RSInterface.type = 5; + RSInterface.optionType = 0; + RSInterface.contentType = 0; + RSInterface.opacity = 0; + RSInterface.hoverType = 52; + RSInterface.disabledSprite = SpriteCache.lookup(spriteId); + RSInterface.width = 500; + RSInterface.height = 500; + RSInterface.tooltip = ""; + } + + public static void drawRune(int i, int id, String runeName) { + Widget RSInterface = addInterface(i); + RSInterface.type = 5; + RSInterface.optionType = 0; + RSInterface.contentType = 0; + RSInterface.opacity = 0; + RSInterface.hoverType = 52; + RSInterface.disabledSprite = SpriteCache.lookup(id + 185); + RSInterface.width = 500; + RSInterface.height = 500; + } + + public static void addRuneText(int ID, int runeAmount, int RuneID, GameFont[] font) { + Widget rsInterface = addInterface(ID); + rsInterface.id = ID; + rsInterface.parent = 1151; + rsInterface.type = 4; + rsInterface.optionType = 0; + rsInterface.contentType = 0; + rsInterface.width = 0; + rsInterface.height = 14; + rsInterface.opacity = 0; + rsInterface.hoverType = -1; + rsInterface.scriptOperators = new int[1]; + rsInterface.scriptDefaults = new int[1]; + rsInterface.scriptOperators[0] = 3; + rsInterface.scriptDefaults[0] = runeAmount; + rsInterface.scripts = new int[1][4]; + rsInterface.scripts[0][0] = 4; + rsInterface.scripts[0][1] = 3214; + rsInterface.scripts[0][2] = RuneID; + rsInterface.scripts[0][3] = 0; + rsInterface.centerText = true; + rsInterface.textDrawingAreas = font[0]; + rsInterface.textShadow = true; + rsInterface.defaultText = "%1/" + runeAmount + ""; + rsInterface.secondaryText = ""; + rsInterface.textColor = 12582912; + rsInterface.secondaryColor = 49152; + } + + public static void homeTeleport() { + Widget RSInterface = addInterface(30000); + RSInterface.tooltip = "Cast @gre@Lunar Home Teleport"; + RSInterface.id = 30000; + RSInterface.parent = 30000; + RSInterface.type = 5; + RSInterface.optionType = 5; + RSInterface.contentType = 0; + RSInterface.opacity = 0; + RSInterface.hoverType = 30001; + RSInterface.disabledSprite = SpriteCache.lookup(201); + RSInterface.width = 20; + RSInterface.height = 20; + Widget Int = addInterface(30001); + Int.invisible = true; + Int.hoverType = -1; + setChildren(1, Int); + addLunarSprite(30002, 200); + setBounds(30002, 0, 0, 0, Int); + } + + public static void addLunar2RunesSmallBox(int ID, int r1, int r2, int ra1, int ra2, int rune1, int lvl, String name, + String descr, GameFont[] TDA, int sid, int suo, int type) { + Widget rsInterface = addInterface(ID); + rsInterface.id = ID; + rsInterface.parent = 1151; + rsInterface.type = 5; + rsInterface.optionType = type; + rsInterface.contentType = 0; + rsInterface.hoverType = ID + 1; + rsInterface.spellUsableOn = suo; + rsInterface.selectedActionName = "Cast On"; + rsInterface.width = 20; + rsInterface.height = 20; + rsInterface.tooltip = "Cast @gre@" + name; + rsInterface.spellName = name; + rsInterface.scriptOperators = new int[3]; + rsInterface.scriptDefaults = new int[3]; + rsInterface.scriptOperators[0] = 3; + rsInterface.scriptDefaults[0] = ra1; + rsInterface.scriptOperators[1] = 3; + rsInterface.scriptDefaults[1] = ra2; + rsInterface.scriptOperators[2] = 3; + rsInterface.scriptDefaults[2] = lvl; + rsInterface.scripts = new int[3][]; + rsInterface.scripts[0] = new int[4]; + rsInterface.scripts[0][0] = 4; + rsInterface.scripts[0][1] = 3214; + rsInterface.scripts[0][2] = r1; + rsInterface.scripts[0][3] = 0; + rsInterface.scripts[1] = new int[4]; + rsInterface.scripts[1][0] = 4; + rsInterface.scripts[1][1] = 3214; + rsInterface.scripts[1][2] = r2; + rsInterface.scripts[1][3] = 0; + rsInterface.scripts[2] = new int[3]; + rsInterface.scripts[2][0] = 1; + rsInterface.scripts[2][1] = 6; + rsInterface.scripts[2][2] = 0; + rsInterface.enabledSprite = SpriteCache.lookup(sid + 147); + rsInterface.disabledSprite = SpriteCache.lookup(sid + 108); + Widget INT = addInterface(ID + 1); + INT.invisible = true; + INT.hoverType = -1; + setChildren(7, INT); + addLunarSprite(ID + 2, 103); + setBounds(ID + 2, 0, 0, 0, INT); + addText(ID + 3, "Level " + (lvl + 1) + ": " + name, 0xFF981F, true, true, 52, TDA, 1); + setBounds(ID + 3, 90, 4, 1, INT); + addText(ID + 4, descr, 0xAF6A1A, true, true, 52, TDA, 0); + setBounds(ID + 4, 90, 19, 2, INT); + setBounds(30016, 37, 35, 3, INT);// Rune + setBounds(rune1, 112, 35, 4, INT);// Rune + addRuneText(ID + 5, ra1 + 1, r1, TDA); + setBounds(ID + 5, 50, 66, 5, INT); + addRuneText(ID + 6, ra2 + 1, r2, TDA); + setBounds(ID + 6, 123, 66, 6, INT); + } + + public static void addLunar3RunesSmallBox(int ID, int r1, int r2, int r3, int ra1, int ra2, int ra3, int rune1, + int rune2, int lvl, String name, String descr, GameFont[] TDA, int sid, int suo, int type) { + Widget rsInterface = addInterface(ID); + rsInterface.id = ID; + rsInterface.parent = 1151; + rsInterface.type = 5; + rsInterface.optionType = type; + rsInterface.contentType = 0; + rsInterface.hoverType = ID + 1; + rsInterface.spellUsableOn = suo; + rsInterface.selectedActionName = "Cast on"; + rsInterface.width = 20; + rsInterface.height = 20; + rsInterface.tooltip = "Cast @gre@" + name; + rsInterface.spellName = name; + rsInterface.scriptOperators = new int[4]; + rsInterface.scriptDefaults = new int[4]; + rsInterface.scriptOperators[0] = 3; + rsInterface.scriptDefaults[0] = ra1; + rsInterface.scriptOperators[1] = 3; + rsInterface.scriptDefaults[1] = ra2; + rsInterface.scriptOperators[2] = 3; + rsInterface.scriptDefaults[2] = ra3; + rsInterface.scriptOperators[3] = 3; + rsInterface.scriptDefaults[3] = lvl; + rsInterface.scripts = new int[4][]; + rsInterface.scripts[0] = new int[4]; + rsInterface.scripts[0][0] = 4; + rsInterface.scripts[0][1] = 3214; + rsInterface.scripts[0][2] = r1; + rsInterface.scripts[0][3] = 0; + rsInterface.scripts[1] = new int[4]; + rsInterface.scripts[1][0] = 4; + rsInterface.scripts[1][1] = 3214; + rsInterface.scripts[1][2] = r2; + rsInterface.scripts[1][3] = 0; + rsInterface.scripts[2] = new int[4]; + rsInterface.scripts[2][0] = 4; + rsInterface.scripts[2][1] = 3214; + rsInterface.scripts[2][2] = r3; + rsInterface.scripts[2][3] = 0; + rsInterface.scripts[3] = new int[3]; + rsInterface.scripts[3][0] = 1; + rsInterface.scripts[3][1] = 6; + rsInterface.scripts[3][2] = 0; + rsInterface.enabledSprite = SpriteCache.lookup(sid + 147); + rsInterface.disabledSprite = SpriteCache.lookup(sid + 108); + Widget INT = addInterface(ID + 1); + INT.invisible = true; + INT.hoverType = -1; + setChildren(9, INT); + addLunarSprite(ID + 2, 103); + setBounds(ID + 2, 0, 0, 0, INT); + addText(ID + 3, "Level " + (lvl + 1) + ": " + name, 0xFF981F, true, true, 52, TDA, 1); + setBounds(ID + 3, 90, 4, 1, INT); + addText(ID + 4, descr, 0xAF6A1A, true, true, 52, TDA, 0); + setBounds(ID + 4, 90, 19, 2, INT); + setBounds(30016, 14, 35, 3, INT); + setBounds(rune1, 74, 35, 4, INT); + setBounds(rune2, 130, 35, 5, INT); + addRuneText(ID + 5, ra1 + 1, r1, TDA); + setBounds(ID + 5, 26, 66, 6, INT); + addRuneText(ID + 6, ra2 + 1, r2, TDA); + setBounds(ID + 6, 87, 66, 7, INT); + addRuneText(ID + 7, ra3 + 1, r3, TDA); + setBounds(ID + 7, 142, 66, 8, INT); + } + + public static void addLunar3RunesBigBox(int ID, int r1, int r2, int r3, int ra1, int ra2, int ra3, int rune1, + int rune2, int lvl, String name, String descr, GameFont[] TDA, int sid, int suo, int type) { + Widget rsInterface = addInterface(ID); + rsInterface.id = ID; + rsInterface.parent = 1151; + rsInterface.type = 5; + rsInterface.optionType = type; + rsInterface.contentType = 0; + rsInterface.hoverType = ID + 1; + rsInterface.spellUsableOn = suo; + rsInterface.selectedActionName = "Cast on"; + rsInterface.width = 20; + rsInterface.height = 20; + rsInterface.tooltip = "Cast @gre@" + name; + rsInterface.spellName = name; + rsInterface.scriptOperators = new int[4]; + rsInterface.scriptDefaults = new int[4]; + rsInterface.scriptOperators[0] = 3; + rsInterface.scriptDefaults[0] = ra1; + rsInterface.scriptOperators[1] = 3; + rsInterface.scriptDefaults[1] = ra2; + rsInterface.scriptOperators[2] = 3; + rsInterface.scriptDefaults[2] = ra3; + rsInterface.scriptOperators[3] = 3; + rsInterface.scriptDefaults[3] = lvl; + rsInterface.scripts = new int[4][]; + rsInterface.scripts[0] = new int[4]; + rsInterface.scripts[0][0] = 4; + rsInterface.scripts[0][1] = 3214; + rsInterface.scripts[0][2] = r1; + rsInterface.scripts[0][3] = 0; + rsInterface.scripts[1] = new int[4]; + rsInterface.scripts[1][0] = 4; + rsInterface.scripts[1][1] = 3214; + rsInterface.scripts[1][2] = r2; + rsInterface.scripts[1][3] = 0; + rsInterface.scripts[2] = new int[4]; + rsInterface.scripts[2][0] = 4; + rsInterface.scripts[2][1] = 3214; + rsInterface.scripts[2][2] = r3; + rsInterface.scripts[2][3] = 0; + rsInterface.scripts[3] = new int[3]; + rsInterface.scripts[3][0] = 1; + rsInterface.scripts[3][1] = 6; + rsInterface.scripts[3][2] = 0; + rsInterface.enabledSprite = SpriteCache.lookup(sid + 147); + rsInterface.disabledSprite = SpriteCache.lookup(sid + 108); + Widget INT = addInterface(ID + 1); + INT.invisible = true; + INT.hoverType = -1; + setChildren(9, INT); + addLunarSprite(ID + 2, 104); + setBounds(ID + 2, 0, 0, 0, INT); + addText(ID + 3, "Level " + (lvl + 1) + ": " + name, 0xFF981F, true, true, 52, TDA, 1); + setBounds(ID + 3, 90, 4, 1, INT); + addText(ID + 4, descr, 0xAF6A1A, true, true, 52, TDA, 0); + setBounds(ID + 4, 90, 21, 2, INT); + setBounds(30016, 14, 48, 3, INT); + setBounds(rune1, 74, 48, 4, INT); + setBounds(rune2, 130, 48, 5, INT); + addRuneText(ID + 5, ra1 + 1, r1, TDA); + setBounds(ID + 5, 26, 79, 6, INT); + addRuneText(ID + 6, ra2 + 1, r2, TDA); + setBounds(ID + 6, 87, 79, 7, INT); + addRuneText(ID + 7, ra3 + 1, r3, TDA); + setBounds(ID + 7, 142, 79, 8, INT); + } + + public static void addLunar3RunesLargeBox(int ID, int r1, int r2, int r3, int ra1, int ra2, int ra3, int rune1, + int rune2, int lvl, String name, String descr, GameFont[] TDA, int sid, int suo, int type) { + Widget rsInterface = addInterface(ID); + rsInterface.id = ID; + rsInterface.parent = 1151; + rsInterface.type = 5; + rsInterface.optionType = type; + rsInterface.contentType = 0; + rsInterface.hoverType = ID + 1; + rsInterface.spellUsableOn = suo; + rsInterface.selectedActionName = "Cast on"; + rsInterface.width = 20; + rsInterface.height = 20; + rsInterface.tooltip = "Cast @gre@" + name; + rsInterface.spellName = name; + rsInterface.scriptOperators = new int[4]; + rsInterface.scriptDefaults = new int[4]; + rsInterface.scriptOperators[0] = 3; + rsInterface.scriptDefaults[0] = ra1; + rsInterface.scriptOperators[1] = 3; + rsInterface.scriptDefaults[1] = ra2; + rsInterface.scriptOperators[2] = 3; + rsInterface.scriptDefaults[2] = ra3; + rsInterface.scriptOperators[3] = 3; + rsInterface.scriptDefaults[3] = lvl; + rsInterface.scripts = new int[4][]; + rsInterface.scripts[0] = new int[4]; + rsInterface.scripts[0][0] = 4; + rsInterface.scripts[0][1] = 3214; + rsInterface.scripts[0][2] = r1; + rsInterface.scripts[0][3] = 0; + rsInterface.scripts[1] = new int[4]; + rsInterface.scripts[1][0] = 4; + rsInterface.scripts[1][1] = 3214; + rsInterface.scripts[1][2] = r2; + rsInterface.scripts[1][3] = 0; + rsInterface.scripts[2] = new int[4]; + rsInterface.scripts[2][0] = 4; + rsInterface.scripts[2][1] = 3214; + rsInterface.scripts[2][2] = r3; + rsInterface.scripts[2][3] = 0; + rsInterface.scripts[3] = new int[3]; + rsInterface.scripts[3][0] = 1; + rsInterface.scripts[3][1] = 6; + rsInterface.scripts[3][2] = 0; + rsInterface.enabledSprite = SpriteCache.lookup(sid + 147); + rsInterface.disabledSprite = SpriteCache.lookup(sid + 108); + Widget INT = addInterface(ID + 1); + INT.invisible = true; + INT.hoverType = -1; + setChildren(9, INT); + addLunarSprite(ID + 2, 105); + setBounds(ID + 2, 0, 0, 0, INT); + addText(ID + 3, "Level " + (lvl + 1) + ": " + name, 0xFF981F, true, true, 52, TDA, 1); + setBounds(ID + 3, 90, 4, 1, INT); + addText(ID + 4, descr, 0xAF6A1A, true, true, 52, TDA, 0); + setBounds(ID + 4, 90, 34, 2, INT); + setBounds(30016, 14, 61, 3, INT); + setBounds(rune1, 74, 61, 4, INT); + setBounds(rune2, 130, 61, 5, INT); + addRuneText(ID + 5, ra1 + 1, r1, TDA); + setBounds(ID + 5, 26, 92, 6, INT); + addRuneText(ID + 6, ra2 + 1, r2, TDA); + setBounds(ID + 6, 87, 92, 7, INT); + addRuneText(ID + 7, ra3 + 1, r3, TDA); + setBounds(ID + 7, 142, 92, 8, INT); + } + + public static void setChildren(int total, Widget i) { + i.children = new int[total]; + i.childX = new int[total]; + i.childY = new int[total]; + } + + public static void configureLunar(GameFont[] tda) { + homeTeleport(); + constructLunar(); + drawRune(30003, 1, "Fire"); + drawRune(30004, 2, "Water"); + drawRune(30005, 3, "Air"); + drawRune(30006, 4, "Earth"); + drawRune(30007, 5, "Mind"); + drawRune(30008, 6, "Body"); + drawRune(30009, 7, "Death"); + drawRune(30010, 8, "Nature"); + drawRune(30011, 9, "Chaos"); + drawRune(30012, 10, "Law"); + drawRune(30013, 11, "Cosmic"); + drawRune(30014, 12, "Blood"); + drawRune(30015, 13, "Soul"); + drawRune(30016, 14, "Astral"); + addLunar3RunesSmallBox(30017, 9075, 554, 555, 0, 4, 3, 30003, 30004, 64, "Bake Pie", + "Bake pies without a stove", tda, 0, 16, 2); + addLunar2RunesSmallBox(30025, 9075, 557, 0, 7, 30006, 65, "Cure Plant", "Cure disease on farming patch", tda, 1, + 4, 2); + addLunar3RunesBigBox(30032, 9075, 564, 558, 0, 0, 0, 30013, 30007, 65, "Monster Examine", + "Detect the combat statistics of a\\nmonster", tda, 2, 2, 2); + addLunar3RunesSmallBox(30040, 9075, 564, 556, 0, 0, 1, 30013, 30005, 66, "NPC Contact", + "Speak with varied NPCs", tda, 3, 0, 2); + addLunar3RunesSmallBox(30048, 9075, 563, 557, 0, 0, 9, 30012, 30006, 67, "Cure Other", "Cure poisoned players", + tda, 4, 8, 2); + addLunar3RunesSmallBox(30056, 9075, 555, 554, 0, 2, 0, 30004, 30003, 67, "Humidify", + "Fills certain vessels with water", tda, 5, 0, 5); + addLunar3RunesSmallBox(30064, 9075, 563, 557, 1, 0, 1, 30012, 30006, 68, "Moonclan Teleport", + "Teleports you to moonclan island", tda, 6, 0, 5); + addLunar3RunesBigBox(30075, 9075, 563, 557, 1, 0, 3, 30012, 30006, 69, "Tele Group Moonclan", + "Teleports players to Moonclan\\nisland", tda, 7, 0, 5); + addLunar3RunesSmallBox(30083, 9075, 563, 557, 1, 0, 5, 30012, 30006, 70, "Ourania Teleport", + "Teleports you to ourania rune altar", tda, 8, 0, 5); + addLunar3RunesSmallBox(30091, 9075, 564, 563, 1, 1, 0, 30013, 30012, 70, "Cure Me", "Cures Poison", tda, 9, 0, + 5); + addLunar2RunesSmallBox(30099, 9075, 557, 1, 1, 30006, 70, "Hunter Kit", "Get a kit of hunting gear", tda, 10, 0, + 5); + addLunar3RunesSmallBox(30106, 9075, 563, 555, 1, 0, 0, 30012, 30004, 71, "Waterbirth Teleport", + "Teleports you to Waterbirth island", tda, 11, 0, 5); + addLunar3RunesBigBox(30114, 9075, 563, 555, 1, 0, 4, 30012, 30004, 72, "Tele Group Waterbirth", + "Teleports players to Waterbirth\\nisland", tda, 12, 0, 5); + addLunar3RunesSmallBox(30122, 9075, 564, 563, 1, 1, 1, 30013, 30012, 73, "Cure Group", + "Cures Poison on players", tda, 13, 0, 5); + addLunar3RunesBigBox(30130, 9075, 564, 559, 1, 1, 4, 30013, 30008, 74, "Stat Spy", + "Cast on another player to see their\\nskill levels", tda, 14, 8, 2); + addLunar3RunesBigBox(30138, 9075, 563, 554, 1, 1, 2, 30012, 30003, 74, "Barbarian Teleport", + "Teleports you to the Barbarian\\noutpost", tda, 15, 0, 5); + addLunar3RunesBigBox(30146, 9075, 563, 554, 1, 1, 5, 30012, 30003, 75, "Tele Group Barbarian", + "Teleports players to the Barbarian\\noutpost", tda, 16, 0, 5); + addLunar3RunesSmallBox(30154, 9075, 554, 556, 1, 5, 9, 30003, 30005, 76, "Superglass Make", + "Make glass without a furnace", tda, 17, 16, 2); + addLunar3RunesSmallBox(30162, 9075, 563, 555, 1, 1, 3, 30012, 30004, 77, "Khazard Teleport", + "Teleports you to Port khazard", tda, 18, 0, 5); + addLunar3RunesSmallBox(30170, 9075, 563, 555, 1, 1, 7, 30012, 30004, 78, "Tele Group Khazard", + "Teleports players to Port khazard", tda, 19, 0, 5); + addLunar3RunesBigBox(30178, 9075, 564, 559, 1, 0, 4, 30013, 30008, 78, "Dream", + "Take a rest and restore hitpoints 3\\n times faster", tda, 20, 0, 5); + addLunar3RunesSmallBox(30186, 9075, 557, 555, 1, 9, 4, 30006, 30004, 79, "String Jewellery", + "String amulets without wool", tda, 21, 0, 5); + addLunar3RunesLargeBox(30194, 9075, 557, 555, 1, 9, 9, 30006, 30004, 80, "Stat Restore Pot\\nShare", + "Share a potion with up to 4 nearby\\nplayers", tda, 22, 0, 5); + addLunar3RunesSmallBox(30202, 9075, 554, 555, 1, 6, 6, 30003, 30004, 81, "Magic Imbue", + "Combine runes without a talisman", tda, 23, 0, 5); + addLunar3RunesBigBox(30210, 9075, 561, 557, 2, 1, 14, 30010, 30006, 82, "Fertile Soil", + "Fertilise a farming patch with super\\ncompost", tda, 24, 4, 2); + addLunar3RunesBigBox(30218, 9075, 557, 555, 2, 11, 9, 30006, 30004, 83, "Boost Potion Share", + "Shares a potion with up to 4 nearby\\nplayers", tda, 25, 0, 5); + addLunar3RunesSmallBox(30226, 9075, 563, 555, 2, 2, 9, 30012, 30004, 84, "Fishing Guild Teleport", + "Teleports you to the fishing guild", tda, 26, 0, 5); + addLunar3RunesLargeBox(30234, 9075, 563, 555, 1, 2, 13, 30012, 30004, 85, "Tele Group Fishing Guild", + "Teleports players to the Fishing\\nGuild", tda, 27, 0, 5); + addLunar3RunesSmallBox(30242, 9075, 557, 561, 2, 14, 0, 30006, 30010, 85, "Plank Make", "Turn Logs into planks", + tda, 28, 16, 5); + addLunar3RunesSmallBox(30250, 9075, 563, 555, 2, 2, 9, 30012, 30004, 86, "Catherby Teleport", + "Teleports you to Catherby", tda, 29, 0, 5); + addLunar3RunesSmallBox(30258, 9075, 563, 555, 2, 2, 14, 30012, 30004, 87, "Tele Group Catherby", + "Teleports players to Catherby", tda, 30, 0, 5); + addLunar3RunesSmallBox(30266, 9075, 563, 555, 2, 2, 7, 30012, 30004, 88, "Ice Plateau Teleport", + "Teleports you to Ice Plateau", tda, 31, 0, 5); + addLunar3RunesLargeBox(30274, 9075, 563, 555, 2, 2, 15, 30012, 30004, 89, "Tele Group Ice Plateau", + "Teleports players to Ice Plateau", tda, 32, 0, 5); + addLunar3RunesBigBox(30282, 9075, 563, 561, 2, 1, 0, 30012, 30010, 90, "Energy Transfer", + "Spend HP and SA energy to\\n give another SA and run energy", tda, 33, 8, 2); + addLunar3RunesBigBox(30290, 9075, 563, 565, 2, 2, 0, 30012, 30014, 91, "Heal Other", + "Transfer up to 75% of hitpoints\\n to another player", tda, 34, 8, 2); + addLunar3RunesBigBox(30298, 9075, 560, 557, 2, 1, 9, 30009, 30006, 92, "Vengeance Other", + "Allows another player to rebound\\ndamage to an opponent", tda, 35, 8, 2); + addLunar3RunesSmallBox(30306, 9075, 560, 557, 3, 1, 9, 30009, 30006, 93, "Vengeance", + "Rebound damage to an opponent", tda, 36, 0, 5); + addLunar3RunesBigBox(30314, 9075, 565, 563, 3, 2, 5, 30014, 30012, 94, "Heal Group", + "Transfer up to 75% of hitpoints\\n to a group", tda, 37, 0, 5); + addLunar3RunesBigBox(30322, 9075, 564, 563, 2, 1, 0, 30013, 30012, 95, "Spellbook Swap", + "Change to another spellbook for 1\\nspell cast", tda, 38, 0, 5); + } + + public static void constructLunar() { + Widget Interface = addTabInterface(29999); + setChildren(80, Interface); + setBounds(30000, 11, 10, 0, Interface); + setBounds(30017, 40, 9, 1, Interface); + setBounds(30025, 71, 12, 2, Interface); + setBounds(30032, 103, 10, 3, Interface); + setBounds(30040, 135, 12, 4, Interface); + setBounds(30048, 165, 10, 5, Interface); + setBounds(30056, 8, 38, 6, Interface); + setBounds(30064, 39, 39, 7, Interface); + setBounds(30075, 71, 39, 8, Interface); + setBounds(30083, 103, 39, 9, Interface); + setBounds(30091, 135, 39, 10, Interface); + setBounds(30099, 165, 37, 11, Interface); + setBounds(30106, 12, 68, 12, Interface); + setBounds(30114, 42, 68, 13, Interface); + setBounds(30122, 71, 68, 14, Interface); + setBounds(30130, 103, 68, 15, Interface); + setBounds(30138, 135, 68, 16, Interface); + setBounds(30146, 165, 68, 17, Interface); + setBounds(30154, 14, 97, 18, Interface); + setBounds(30162, 42, 97, 19, Interface); + setBounds(30170, 71, 97, 20, Interface); + setBounds(30178, 101, 97, 21, Interface); + setBounds(30186, 135, 98, 22, Interface); + setBounds(30194, 168, 98, 23, Interface); + setBounds(30202, 11, 125, 24, Interface); + setBounds(30210, 42, 124, 25, Interface); + setBounds(30218, 74, 125, 26, Interface); + setBounds(30226, 103, 125, 27, Interface); + setBounds(30234, 135, 125, 28, Interface); + setBounds(30242, 164, 126, 29, Interface); + setBounds(30250, 10, 155, 30, Interface); + setBounds(30258, 42, 155, 31, Interface); + setBounds(30266, 71, 155, 32, Interface); + setBounds(30274, 103, 155, 33, Interface); + setBounds(30282, 136, 155, 34, Interface); + setBounds(30290, 165, 155, 35, Interface); + setBounds(30298, 13, 185, 36, Interface); + setBounds(30306, 42, 185, 37, Interface); + setBounds(30314, 71, 184, 38, Interface); + setBounds(30322, 104, 184, 39, Interface); + setBounds(30001, 6, 184, 40, Interface);// hover + setBounds(30018, 5, 176, 41, Interface);// hover + setBounds(30026, 5, 176, 42, Interface);// hover + setBounds(30033, 5, 163, 43, Interface);// hover + setBounds(30041, 5, 176, 44, Interface);// hover + setBounds(30049, 5, 176, 45, Interface);// hover + setBounds(30057, 5, 176, 46, Interface);// hover + setBounds(30065, 5, 176, 47, Interface);// hover + setBounds(30076, 5, 163, 48, Interface);// hover + setBounds(30084, 5, 176, 49, Interface);// hover + setBounds(30092, 5, 176, 50, Interface);// hover + setBounds(30100, 5, 176, 51, Interface);// hover + setBounds(30107, 5, 176, 52, Interface);// hover + setBounds(30115, 5, 163, 53, Interface);// hover + setBounds(30123, 5, 176, 54, Interface);// hover + setBounds(30131, 5, 163, 55, Interface);// hover + setBounds(30139, 5, 163, 56, Interface);// hover + setBounds(30147, 5, 163, 57, Interface);// hover + setBounds(30155, 5, 176, 58, Interface);// hover + setBounds(30163, 5, 176, 59, Interface);// hover + setBounds(30171, 5, 176, 60, Interface);// hover + setBounds(30179, 5, 163, 61, Interface);// hover + setBounds(30187, 5, 176, 62, Interface);// hover + setBounds(30195, 5, 149, 63, Interface);// hover + setBounds(30203, 5, 176, 64, Interface);// hover + setBounds(30211, 5, 163, 65, Interface);// hover + setBounds(30219, 5, 163, 66, Interface);// hover + setBounds(30227, 5, 176, 67, Interface);// hover + setBounds(30235, 5, 149, 68, Interface);// hover + setBounds(30243, 5, 176, 69, Interface);// hover + setBounds(30251, 5, 5, 70, Interface);// hover + setBounds(30259, 5, 5, 71, Interface);// hover + setBounds(30267, 5, 5, 72, Interface);// hover + setBounds(30275, 5, 5, 73, Interface);// hover + setBounds(30283, 5, 5, 74, Interface);// hover + setBounds(30291, 5, 5, 75, Interface);// hover + setBounds(30299, 5, 5, 76, Interface);// hover + setBounds(30307, 5, 5, 77, Interface);// hover + setBounds(30323, 5, 5, 78, Interface);// hover + setBounds(30315, 5, 5, 79, Interface);// hover + } + + public static void setBounds(int ID, int X, int Y, int frame, Widget RSinterface) { + RSinterface.children[frame] = ID; + RSinterface.childX[frame] = X; + RSinterface.childY[frame] = Y; + } + + public static void addButton(int i, int spriteId, int W, int H, String S, int AT) { + Widget RSInterface = addInterface(i); + RSInterface.id = i; + RSInterface.parent = i; + RSInterface.type = 5; + RSInterface.optionType = AT; + RSInterface.contentType = 0; + RSInterface.opacity = 0; + RSInterface.hoverType = 52; + RSInterface.disabledSprite = SpriteCache.lookup(spriteId); + RSInterface.enabledSprite = SpriteCache.lookup(spriteId); + RSInterface.width = W; + RSInterface.height = H; + RSInterface.tooltip = S; + } + + public static void addConfigHover(int interfaceID, int actionType, int hoverid, int disabledSpriteId, int enabledSpriteId, + int Width, int Height, int configFrame, int configId, String Tooltip, int hoverId2, + int hoverSpriteId, int hoverSpriteId2, String hoverSpriteName, int hoverId3, String hoverDisabledText, + String hoverEnabledText, int X, int Y) { + Widget hover = addTabInterface(interfaceID); + hover.id = interfaceID; + hover.parent = interfaceID; + hover.type = 5; + hover.optionType = actionType; + hover.contentType = 0; + hover.opacity = 0; + hover.hoverType = hoverid; + hover.disabledSprite = SpriteCache.lookup(disabledSpriteId); + hover.enabledSprite = SpriteCache.lookup(enabledSpriteId); + hover.width = Width; + hover.tooltip = Tooltip; + hover.height = Height; + hover.scriptOperators = new int[1]; + hover.scriptDefaults = new int[1]; + hover.scriptOperators[0] = 1; + hover.scriptDefaults[0] = configId; + hover.scripts = new int[1][3]; + hover.scripts[0][0] = 5; + hover.scripts[0][1] = configFrame; + hover.scripts[0][2] = 0; + hover = addTabInterface(hoverid); + hover.parent = hoverid; + hover.id = hoverid; + hover.type = 0; + hover.optionType = 0; + hover.width = 550; + hover.height = 334; + hover.invisible = true; + hover.hoverType = -1; + addSprites(hoverId2, hoverSpriteId, hoverSpriteId2, hoverSpriteName, configId, configFrame); + addHoverBox(hoverId3, interfaceID, hoverDisabledText, hoverEnabledText, configId, configFrame); + setChildren(2, hover); + setBounds(hoverId2, 15, 60, 0, hover); + setBounds(hoverId3, X, Y, 1, hover); + } + + public static void addSprites(int ID, int disabledSpriteId, int enabledSpriteId, String name, int configId, int configFrame) { + Widget Tab = addTabInterface(ID); + Tab.id = ID; + Tab.parent = ID; + Tab.type = 5; + Tab.optionType = 0; + Tab.contentType = 0; + Tab.width = 512; + Tab.height = 334; + Tab.opacity = 0; + Tab.hoverType = -1; + Tab.scriptOperators = new int[1]; + Tab.scriptDefaults = new int[1]; + Tab.scriptOperators[0] = 1; + Tab.scriptDefaults[0] = configId; + Tab.scripts = new int[1][3]; + Tab.scripts[0][0] = 5; + Tab.scripts[0][1] = configFrame; + Tab.scripts[0][2] = 0; + Tab.disabledSprite = SpriteCache.lookup(disabledSpriteId); + Tab.enabledSprite = SpriteCache.lookup(enabledSpriteId); + } + + public String[] tooltips; + public boolean newScroller; + @SuppressWarnings("unused") + private int mOverInterToTrigger; + @SuppressWarnings("unused") + private boolean interfaceShown; +} diff --git a/src/main/java/org/rebotted/cache/idk/IdentityKit.java b/src/main/java/org/rebotted/cache/idk/IdentityKit.java new file mode 100644 index 0000000..478f58c --- /dev/null +++ b/src/main/java/org/rebotted/cache/idk/IdentityKit.java @@ -0,0 +1,133 @@ +package org.rebotted.cache.idk; + +import org.rebotted.cache.FileArchive; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; + +public final class IdentityKit { + + public static int length; + public static IdentityKit kits[]; + public int bodyPartId; + private int[] bodyModels; + private final int[] originalColors; + private final int[] replacementColors; + private final int[] headModels = { -1, -1, -1, -1, -1 }; + public boolean validStyle; + + private IdentityKit() { + bodyPartId = -1; + originalColors = new int[6]; + replacementColors = new int[6]; + validStyle = false; + } + + public static void init(FileArchive archive) { + Buffer buffer = new Buffer(archive.readFile("idk.dat")); + + length = buffer.readUShort(); + if (kits == null) { + kits = new IdentityKit[length]; + } + for (int id = 0; id < length; id++) { + if (kits[id] == null) { + kits[id] = new IdentityKit(); + } + kits[id].decode(buffer); + } + } + + private void decode(Buffer buffer) { + while(true) { + + int opcode = buffer.readUnsignedByte(); + + if (opcode == 0) { + return; + } else if (opcode == 1) { + bodyPartId = buffer.readUnsignedByte(); + } else if (opcode == 2) { + int count = buffer.readUnsignedByte(); + bodyModels = new int[count]; + for (int part = 0; part < count; part++) { + bodyModels[part] = buffer.readUShort(); + } + } else if (opcode == 3) { + validStyle = true; + } else if (opcode >= 40 && opcode < 50) { + originalColors[opcode - 40] = buffer.readUShort(); + } else if (opcode >= 50 && opcode < 60) { + replacementColors[opcode - 50] = buffer.readUShort(); + } else if (opcode >= 60 && opcode < 70) { + headModels[opcode - 60] = buffer.readUShort(); + } else { + System.out.println("Error unrecognised config code: " + opcode); + } + } + } + + public boolean bodyLoaded() { + if (bodyModels == null) + return true; + boolean ready = true; + for (int part = 0; part < bodyModels.length; part++) + if (!Model.isCached(bodyModels[part])) + ready = false; + + return ready; + } + + public Model bodyModel() { + if (bodyModels == null) { + return null; + } + + Model models[] = new Model[bodyModels.length]; + for (int part = 0; part < bodyModels.length; part++) { + models[part] = Model.getModel(bodyModels[part]); + } + + Model model; + if (models.length == 1) { + model = models[0]; + } else { + model = new Model(models.length, models); + } + for (int part = 0; part < 6; part++) { + if (originalColors[part] == 0) { + break; + } + model.recolor(originalColors[part], replacementColors[part]); + } + return model; + } + + public boolean headLoaded() { + boolean ready = true; + for (int part = 0; part < 5; part++) { + if (headModels[part] != -1 && !Model.isCached(headModels[part])) { + ready = false; + } + } + return ready; + } + + public Model headModel() { + Model models[] = new Model[5]; + int count = 0; + for (int part = 0; part < 5; part++) { + if (headModels[part] != -1) { + models[count++] = Model.getModel(headModels[part]); + } + } + + Model model = new Model(count, models); + for (int part = 0; part < 6; part++) { + if (originalColors[part] == 0) { + break; + } + model.recolor(originalColors[part], replacementColors[part]); + } + return model; + } +} diff --git a/src/main/java/org/rebotted/collection/Cacheable.java b/src/main/java/org/rebotted/collection/Cacheable.java new file mode 100644 index 0000000..5e5aef9 --- /dev/null +++ b/src/main/java/org/rebotted/collection/Cacheable.java @@ -0,0 +1,17 @@ +package org.rebotted.collection; + +public class Cacheable extends Linkable { + + public Cacheable nextCacheable; + public Cacheable previousCacheable; + + public final void unlinkCacheable() { + if (previousCacheable == null) { + } else { + previousCacheable.nextCacheable = nextCacheable; + nextCacheable.previousCacheable = previousCacheable; + nextCacheable = null; + previousCacheable = null; + } + } +} diff --git a/src/main/java/org/rebotted/collection/Deque.java b/src/main/java/org/rebotted/collection/Deque.java new file mode 100644 index 0000000..7a68f7c --- /dev/null +++ b/src/main/java/org/rebotted/collection/Deque.java @@ -0,0 +1,95 @@ +package org.rebotted.collection; + +public final class Deque { + + private final Linkable head; + private Linkable current; + + public Deque() { + head = new Linkable(); + head.previous = head; + head.next = head; + } + + public void insertHead(Linkable linkable) { + if (linkable.next != null) + linkable.unlink(); + linkable.next = head.next; + linkable.previous = head; + linkable.next.previous = linkable; + linkable.previous.next = linkable; + } + + public void insertTail(Linkable linkable) { + if (linkable.next != null) + linkable.unlink(); + linkable.next = head; + linkable.previous = head.previous; + linkable.next.previous = linkable; + linkable.previous.next = linkable; + } + + public Linkable popHead() { + Linkable node = head.previous; + if (node == head) { + return null; + } else { + node.unlink(); + return node; + } + } + + public Linkable reverseGetFirst() { + Linkable node = head.previous; + if (node == head) { + current = null; + return null; + } else { + current = node.previous; + return node; + } + } + + public Linkable getFirst() { + Linkable node = head.next; + if (node == head) { + current = null; + return null; + } else { + current = node.next; + return node; + } + } + + public Linkable reverseGetNext() { + Linkable node = current; + if (node == head) { + current = null; + return null; + } else { + current = node.previous; + return node; + } + } + + public Linkable getNext() { + Linkable node = current; + if (node == head) { + current = null; + return null; + } + current = node.next; + return node; + } + + public void clear() { + if (head.previous == head) + return; + do { + Linkable node = head.previous; + if (node == head) + return; + node.unlink(); + } while (true); + } +} diff --git a/src/main/java/org/rebotted/collection/HashTable.java b/src/main/java/org/rebotted/collection/HashTable.java new file mode 100644 index 0000000..47e4b20 --- /dev/null +++ b/src/main/java/org/rebotted/collection/HashTable.java @@ -0,0 +1,67 @@ +package org.rebotted.collection; + +import org.rebotted.sign.SignLink; + +final class HashTable { + + private final int bucketCount; + private final Linkable[] buckets; + + /** + * Creates the HashTable with the specified size. + */ + public HashTable() { + int size = 1024;// was parameter + bucketCount = size; + buckets = new Linkable[size]; + for (int index = 0; index < size; index++) { + Linkable node = buckets[index] = new Linkable(); + node.previous = node; + node.next = node; + } + } + + /** + * Gets the {@link Linkable} with the specified {@code key} from this + * HashTable. + * + * @param key + * The key. + * @return The Linkable, or {@code null} if this HashTable does not contain + * an associated for the specified key. + */ + public Linkable get(long key) { + Linkable linkable = buckets[(int) (key & (long) (bucketCount - 1))]; + for (Linkable next = linkable.previous; next != linkable; next = next.previous) + if (next.key == key) + return next; + + return null; + } + + /** + * Associates the specified {@link Linkable} with the specified {@code key}. + * + * @param key + * The key. + * @param linkable + * The Linkable. + */ + public void put(Linkable linkable, long key) { + try { + if (linkable.next != null) + linkable.unlink(); + Linkable current = buckets[(int) (key & (long) (bucketCount - 1))]; + linkable.next = current.next; + linkable.previous = current; + linkable.next.previous = linkable; + linkable.previous.next = linkable; + linkable.key = key; + return; + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("91499, " + linkable + ", " + key + ", " + + (byte) 7 + ", " + runtimeexception.toString()); + } + throw new RuntimeException(); + } +} diff --git a/src/main/java/org/rebotted/collection/Linkable.java b/src/main/java/org/rebotted/collection/Linkable.java new file mode 100644 index 0000000..7fa8ce2 --- /dev/null +++ b/src/main/java/org/rebotted/collection/Linkable.java @@ -0,0 +1,18 @@ +package org.rebotted.collection; + +public class Linkable { + + public long key; + public Linkable previous; + public Linkable next; + + public final void unlink() { + if (next == null) { + } else { + next.previous = previous; + previous.next = next; + previous = null; + next = null; + } + } +} diff --git a/src/main/java/org/rebotted/collection/Queue.java b/src/main/java/org/rebotted/collection/Queue.java new file mode 100644 index 0000000..1d6f95f --- /dev/null +++ b/src/main/java/org/rebotted/collection/Queue.java @@ -0,0 +1,61 @@ +package org.rebotted.collection; + +public final class Queue { + + private final Cacheable head; + private Cacheable current; + + public Queue() { + head = new Cacheable(); + head.nextCacheable = head; + head.previousCacheable = head; + } + + public void insertHead(Cacheable node) { + if (node.previousCacheable != null) + node.unlinkCacheable(); + node.previousCacheable = head.previousCacheable; + node.nextCacheable = head; + node.previousCacheable.nextCacheable = node; + node.nextCacheable.previousCacheable = node; + } + + public Cacheable popTail() { + Cacheable next = head.nextCacheable; + if (next == head) { + return null; + } else { + next.unlinkCacheable(); + return next; + } + } + + public Cacheable reverseGetFirst() { + Cacheable nodeSub = head.nextCacheable; + if (nodeSub == head) { + current = null; + return null; + } else { + current = nodeSub.nextCacheable; + return nodeSub; + } + } + + public Cacheable reverseGetNext() { + Cacheable next = current; + if (next == head) { + current = null; + return null; + } else { + current = next.nextCacheable; + return next; + } + } + + public int size() { + int count = 0; + for (Cacheable nodeSub = head.nextCacheable; nodeSub != head; nodeSub = nodeSub.nextCacheable) + count++; + return count; + } +} diff --git a/src/main/java/org/rebotted/collection/ReferenceCache.java b/src/main/java/org/rebotted/collection/ReferenceCache.java new file mode 100644 index 0000000..326805b --- /dev/null +++ b/src/main/java/org/rebotted/collection/ReferenceCache.java @@ -0,0 +1,95 @@ +package org.rebotted.collection; +import org.rebotted.sign.SignLink; + +/** + * A least-recently used cache of references, backed by a {@link HashTable} and a {@link Queue}. + */ +public final class ReferenceCache { + + /** + * The empty cacheable. + */ + private final Cacheable empty; + /** + * The capacity of this cache. + */ + private final int capacity; + /** + * The amount of unused slots in this cache. + */ + private int spaceLeft; + /** + * The HashTable backing this cache. + */ + private final HashTable table; + /** + * The queue of references, used for LRU behaviour. + */ + private final Queue references; + + /** + * Creates the ReferenceCache. + * + * @param capacity The capacity of this cache. + */ + public ReferenceCache(int i) { + empty = new Cacheable(); + references = new Queue(); + capacity = i; + spaceLeft = i; + table = new HashTable(); + } + + /** + * Gets the {@link Cacheable} with the specified key. + * + * @param key The key. + * @return The Cacheable. + */ + public Cacheable get(long key) { + Cacheable cacheable = (Cacheable) table.get(key); + if (cacheable != null) { + references.insertHead(cacheable); + } + return cacheable; + } + + public void put(Cacheable node, long key) { + try { + if (spaceLeft == 0) { + Cacheable front = references.popTail(); + front.unlink(); + front.unlinkCacheable(); + if (front == empty) { + front = references.popTail(); + front.unlink(); + front.unlinkCacheable(); + } + } else { + spaceLeft--; + } + table.put(node, key); + references.insertHead(node); + return; + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("47547, " + node + ", " + key + ", " + (byte) 2 + ", " + runtimeexception.toString()); + } + throw new RuntimeException(); + } + + /** + * Clears the contents of this ReferenceCache. + */ + public void clear() { + do { + Cacheable front = references.popTail(); + if (front != null) { + front.unlink(); + front.unlinkCacheable(); + } else { + spaceLeft = capacity; + return; + } + } while (true); + } +} diff --git a/src/main/java/org/rebotted/draw/ProducingGraphicsBuffer.java b/src/main/java/org/rebotted/draw/ProducingGraphicsBuffer.java new file mode 100644 index 0000000..9532a9f --- /dev/null +++ b/src/main/java/org/rebotted/draw/ProducingGraphicsBuffer.java @@ -0,0 +1,30 @@ +package org.rebotted.draw; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; + +public final class ProducingGraphicsBuffer { + + public final int[] canvasRaster; + public final int canvasWidth; + public final int canvasHeight; + private final BufferedImage bufferedImage; + private float[] depthbuffer; + + public ProducingGraphicsBuffer(int canvasWidth, int canvasHeight) { + this.canvasWidth = canvasWidth; + this.canvasHeight = canvasHeight; + depthbuffer = new float [canvasWidth * canvasHeight]; + bufferedImage = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB); + canvasRaster = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); + initDrawingArea(); + } + + public void drawGraphics(int x, Graphics graphics, int y) { + graphics.drawImage(bufferedImage, y, x, null); + } + + public void initDrawingArea() { + Rasterizer2D.initDrawingArea(canvasHeight, canvasWidth, canvasRaster, depthbuffer); + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/draw/Rasterizer2D.java b/src/main/java/org/rebotted/draw/Rasterizer2D.java new file mode 100644 index 0000000..c2f025b --- /dev/null +++ b/src/main/java/org/rebotted/draw/Rasterizer2D.java @@ -0,0 +1,341 @@ +package org.rebotted.draw; +import org.rebotted.collection.Cacheable; + +public class Rasterizer2D extends Cacheable { + /** + * Sets the Rasterizer2D in the upper left corner with height, width and pixels set. + * @param height The height of the drawingArea. + * @param width The width of the drawingArea. + * @param pixels The array of pixels (RGBColours) in the drawingArea. + * @param depth An array of fog depths. + */ + public static void initDrawingArea(int height, int width, int pixels[], float depth[]) { + depthBuffer = depth; + Rasterizer2D.pixels = pixels; + Rasterizer2D.width = width; + Rasterizer2D.height = height; + setDrawingArea(height, 0, width, 0); + } + + /** + * Draws a transparent box with a gradient that changes from top to bottom. + * @param leftX The left edge X-Coordinate of the box. + * @param topY The top edge Y-Coordinate of the box. + * @param width The width of the box. + * @param height The height of the box. + * @param topColour The top rgbColour of the gradient. + * @param bottomColour The bottom rgbColour of the gradient. + * @param opacity The opacity value ranging from 0 to 256. + */ + public static void drawTransparentGradientBox(int leftX, int topY, int width, int height, int topColour, int bottomColour, int opacity) { + int gradientProgress = 0; + int progressPerPixel = 0x10000 / height; + if(leftX < Rasterizer2D.leftX) { + width -= Rasterizer2D.leftX - leftX; + leftX = Rasterizer2D.leftX; + } + if(topY < Rasterizer2D.topY) { + gradientProgress += (Rasterizer2D.topY - topY) * progressPerPixel; + height -= Rasterizer2D.topY - topY; + topY = Rasterizer2D.topY; + } + if(leftX + width > bottomX) + width = bottomX - leftX; + if(topY + height > bottomY) + height = bottomY - topY; + int leftOver = Rasterizer2D.width - width; + int transparency = 256 - opacity; + int pixelIndex = leftX + topY * Rasterizer2D.width; + for(int rowIndex = 0; rowIndex < height; rowIndex++) { + int gradient = 0x10000 - gradientProgress >> 8; + int inverseGradient = gradientProgress >> 8; + int gradientColour = ((topColour & 0xff00ff) * gradient + (bottomColour & 0xff00ff) * inverseGradient & 0xff00ff00) + ((topColour & 0xff00) * gradient + (bottomColour & 0xff00) * inverseGradient & 0xff0000) >>> 8; + int transparentPixel = ((gradientColour & 0xff00ff) * opacity >> 8 & 0xff00ff) + ((gradientColour & 0xff00) * opacity >> 8 & 0xff00); + for(int columnIndex = 0; columnIndex < width; columnIndex++) { + int backgroundPixel = pixels[pixelIndex]; + backgroundPixel = ((backgroundPixel & 0xff00ff) * transparency >> 8 & 0xff00ff) + ((backgroundPixel & 0xff00) * transparency >> 8 & 0xff00); + pixels[pixelIndex++] = transparentPixel + backgroundPixel; + } + pixelIndex += leftOver; + gradientProgress += progressPerPixel; + } + } + + /** + * Sets the drawingArea to the default size and position. + * Position: Upper left corner. + * Size: As specified before. + */ + public static void defaultDrawingAreaSize() { + leftX = 0; + topY = 0; + bottomX = width; + bottomY = height; + lastX = bottomX; + viewportCenterX = bottomX / 2; + } + + /** + * Sets the drawingArea based on the coordinates of the edges. + * @param bottomY The bottom edge Y-Coordinate. + * @param leftX The left edge X-Coordinate. + * @param rightX The right edge X-Coordinate. + * @param topY The top edge Y-Coordinate. + */ + public static void setDrawingArea(int bottomY, int leftX, int rightX, int topY) { + if(leftX < 0) { + leftX = 0; + } + if(topY < 0) { + topY = 0; + } + if(rightX > width) { + rightX = width; + } + if(bottomY > height) { + bottomY = height; + } + Rasterizer2D.leftX = leftX; + Rasterizer2D.topY = topY; + bottomX = rightX; + Rasterizer2D.bottomY = bottomY; + lastX = bottomX; + viewportCenterX = bottomX / 2; + viewportCenterY = Rasterizer2D.bottomY / 2; + } + + /** + * Clears the drawingArea by setting every pixel to 0 (black). + */ + public static void clear() { + int i = width * height; + for(int j = 0; j < i; j++) { + pixels[j] = 0; + depthBuffer[j] = Float.MAX_VALUE; + } + + } + + /** + * Draws a box filled with a certain colour. + * @param leftX The left edge X-Coordinate of the box. + * @param topY The top edge Y-Coordinate of the box. + * @param width The width of the box. + * @param height The height of the box. + * @param rgbColour The RGBColour of the box. + */ + public static void drawBox(int leftX, int topY, int width, int height, int rgbColour) { + if (leftX < Rasterizer2D.leftX) { + width -= Rasterizer2D.leftX - leftX; + leftX = Rasterizer2D.leftX; + } + if (topY < Rasterizer2D.topY) { + height -= Rasterizer2D.topY - topY; + topY = Rasterizer2D.topY; + } + if (leftX + width > bottomX) + width = bottomX - leftX; + if (topY + height > bottomY) + height = bottomY - topY; + int leftOver = Rasterizer2D.width - width; + int pixelIndex = leftX + topY * Rasterizer2D.width; + for (int rowIndex = 0; rowIndex < height; rowIndex++) { + for (int columnIndex = 0; columnIndex < width; columnIndex++) + pixels[pixelIndex++] = rgbColour; + pixelIndex += leftOver; + } + } + + /** + * Draws a transparent box. + * @param leftX The left edge X-Coordinate of the box. + * @param topY The top edge Y-Coordinate of the box. + * @param width The box width. + * @param height The box height. + * @param rgbColour The box colour. + * @param opacity The opacity value ranging from 0 to 256. + */ + public static void drawTransparentBox(int leftX, int topY, int width, int height, int rgbColour, int opacity){ + if(leftX < Rasterizer2D.leftX){ + width -= Rasterizer2D.leftX - leftX; + leftX = Rasterizer2D.leftX; + } + if(topY < Rasterizer2D.topY){ + height -= Rasterizer2D.topY - topY; + topY = Rasterizer2D.topY; + } + if(leftX + width > bottomX) + width = bottomX - leftX; + if(topY + height > bottomY) + height = bottomY - topY; + int transparency = 256 - opacity; + int red = (rgbColour >> 16 & 0xff) * opacity; + int green = (rgbColour >> 8 & 0xff) * opacity; + int blue = (rgbColour & 0xff) * opacity; + int leftOver = Rasterizer2D.width - width; + int pixelIndex = leftX + topY * Rasterizer2D.width; + for(int rowIndex = 0; rowIndex < height; rowIndex++){ + for(int columnIndex = 0; columnIndex < width; columnIndex++){ + int otherRed = (pixels[pixelIndex] >> 16 & 0xff) * transparency; + int otherGreen = (pixels[pixelIndex] >> 8 & 0xff) * transparency; + int otherBlue = (pixels[pixelIndex] & 0xff) * transparency; + int transparentColour = ((red + otherRed >> 8) << 16) + ((green + otherGreen >> 8) << 8) + (blue + otherBlue >> 8); + pixels[pixelIndex++] = transparentColour; + } + pixelIndex += leftOver; + } + } + + /** + * Draws a 1 pixel thick box outline in a certain colour. + * @param leftX The left edge X-Coordinate. + * @param topY The top edge Y-Coordinate. + * @param width The width. + * @param height The height. + * @param rgbColour The RGB-Colour. + */ + public static void drawBoxOutline(int leftX, int topY, int width, int height, int rgbColour){ + drawHorizontalLine(leftX, topY, width, rgbColour); + drawHorizontalLine(leftX, (topY + height) - 1, width, rgbColour); + drawVerticalLine(leftX, topY, height, rgbColour); + drawVerticalLine((leftX + width) - 1, topY, height, rgbColour); + } + + /** + * Draws a coloured horizontal line in the drawingArea. + * @param xPosition The start X-Position of the line. + * @param yPosition The Y-Position of the line. + * @param width The width of the line. + * @param rgbColour The colour of the line. + */ + public static void drawHorizontalLine(int xPosition, int yPosition, int width, int rgbColour){ + if(yPosition < topY || yPosition >= bottomY) + return; + if(xPosition < leftX){ + width -= leftX - xPosition; + xPosition = leftX; + } + if(xPosition + width > bottomX) + width = bottomX - xPosition; + int pixelIndex = xPosition + yPosition * Rasterizer2D.width; + for(int i = 0; i < width; i++) + pixels[pixelIndex + i] = rgbColour; + } + + /** + * Draws a coloured vertical line in the drawingArea. + * @param xPosition The X-Position of the line. + * @param yPosition The start Y-Position of the line. + * @param height The height of the line. + * @param rgbColour The colour of the line. + */ + public static void drawVerticalLine(int xPosition, int yPosition, int height, int rgbColour){ + if(xPosition < leftX || xPosition >= bottomX) + return; + if(yPosition < topY){ + height -= topY - yPosition; + yPosition = topY; + } + if(yPosition + height > bottomY) + height = bottomY - yPosition; + int pixelIndex = xPosition + yPosition * width; + for(int rowIndex = 0; rowIndex < height; rowIndex++) + pixels[pixelIndex + rowIndex * width] = rgbColour; + } + + /** + * Draws a 1 pixel thick transparent box outline in a certain colour. + * @param leftX The left edge X-Coordinate + * @param topY The top edge Y-Coordinate. + * @param width The width. + * @param height The height. + * @param rgbColour The RGB-Colour. + * @param opacity The opacity value ranging from 0 to 256. + */ + public static void drawTransparentBoxOutline(int leftX, int topY, int width, int height, int rgbColour, int opacity) { + drawTransparentHorizontalLine(leftX, topY, width, rgbColour, opacity); + drawTransparentHorizontalLine(leftX, topY + height - 1, width, rgbColour, opacity); + if(height >= 3) { + drawTransparentVerticalLine(leftX, topY + 1, height - 2, rgbColour, opacity); + drawTransparentVerticalLine(leftX + width - 1, topY + 1, height - 2, rgbColour, opacity); + } + } + + /** + * Draws a transparent coloured horizontal line in the drawingArea. + * @param xPosition The start X-Position of the line. + * @param yPosition The Y-Position of the line. + * @param width The width of the line. + * @param rgbColour The colour of the line. + * @param opacity The opacity value ranging from 0 to 256. + */ + public static void drawTransparentHorizontalLine(int xPosition, int yPosition, int width, int rgbColour, int opacity) { + if(yPosition < topY || yPosition >= bottomY) { + return; + } + if(xPosition < leftX) { + width -= leftX - xPosition; + xPosition = leftX; + } + if(xPosition + width > bottomX) { + width = bottomX - xPosition; + } + final int transparency = 256 - opacity; + final int red = (rgbColour >> 16 & 0xff) * opacity; + final int green = (rgbColour >> 8 & 0xff) * opacity; + final int blue = (rgbColour & 0xff) * opacity; + int pixelIndex = xPosition + yPosition * Rasterizer2D.width; + for(int i = 0; i < width; i++) { + final int otherRed = (pixels[pixelIndex] >> 16 & 0xff) * transparency; + final int otherGreen = (pixels[pixelIndex] >> 8 & 0xff) * transparency; + final int otherBlue = (pixels[pixelIndex] & 0xff) * transparency; + final int transparentColour = (red + otherRed >> 8 << 16) + (green + otherGreen >> 8 << 8) + (blue + otherBlue >> 8); + pixels[pixelIndex++] = transparentColour; + } + } + + /** + * Draws a transparent coloured vertical line in the drawingArea. + * @param xPosition The X-Position of the line. + * @param yPosition The start Y-Position of the line. + * @param height The height of the line. + * @param rgbColour The colour of the line. + * @param opacity The opacity value ranging from 0 to 256. + */ + public static void drawTransparentVerticalLine(int xPosition, int yPosition, int height, int rgbColour, int opacity) { + if(xPosition < leftX || xPosition >= bottomX) { + return; + } + if(yPosition < topY) { + height -= topY - yPosition; + yPosition = topY; + } + if(yPosition + height > bottomY) { + height = bottomY - yPosition; + } + final int transparency = 256 - opacity; + final int red = (rgbColour >> 16 & 0xff) * opacity; + final int green = (rgbColour >> 8 & 0xff) * opacity; + final int blue = (rgbColour & 0xff) * opacity; + int pixelIndex = xPosition + yPosition * width; + for(int i = 0; i < height; i++) { + final int otherRed = (pixels[pixelIndex] >> 16 & 0xff) * transparency; + final int otherGreen = (pixels[pixelIndex] >> 8 & 0xff) * transparency; + final int otherBlue = (pixels[pixelIndex] & 0xff) * transparency; + final int transparentColour = (red + otherRed >> 8 << 16) + (green + otherGreen >> 8 << 8) + (blue + otherBlue >> 8); + pixels[pixelIndex] = transparentColour; + pixelIndex += width; + } + } + public static float depthBuffer[]; + public static int pixels[]; + public static int width; + public static int height; + public static int topY; + public static int bottomY; + public static int leftX; + public static int bottomX; + public static int lastX; + public static int viewportCenterX; + public static int viewportCenterY; +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/draw/Rasterizer3D.java b/src/main/java/org/rebotted/draw/Rasterizer3D.java new file mode 100644 index 0000000..d1dc5ff --- /dev/null +++ b/src/main/java/org/rebotted/draw/Rasterizer3D.java @@ -0,0 +1,2679 @@ +package org.rebotted.draw; + +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.graphics.IndexedImage; +import org.rebotted.scene.SceneGraph; + +public final class Rasterizer3D extends Rasterizer2D { + + public static void clear() { + anIntArray1468 = null; + anIntArray1468 = null; + anIntArray1470 = null; + COSINE = null; + scanOffsets = null; + textures = null; + textureIsTransparant = null; + averageTextureColours = null; + textureRequestPixelBuffer = null; + texturesPixelBuffer = null; + textureLastUsed = null; + hslToRgb = null; + currentPalette = null; + } + + public static void useViewport() { + scanOffsets = new int[Rasterizer2D.height]; + + for (int j = 0; j < Rasterizer2D.height; j++) { + scanOffsets[j] = Rasterizer2D.width * j; + } + + originViewX = Rasterizer2D.width / 2; + originViewY = Rasterizer2D.height / 2; + } + + public static void reposition(int width, int length) { + scanOffsets = new int[length]; + for (int x = 0; x < length; x++) { + scanOffsets[x] = width * x; + } + originViewX = width / 2; + originViewY = length / 2; + } + + public static void clearTextureCache() { + textureRequestPixelBuffer = null; + for (int i = 0; i < 50; i++) + texturesPixelBuffer[i] = null; + } + + public static void initiateRequestBuffers() { + if (textureRequestPixelBuffer == null) { + textureRequestBufferPointer = 20; + if (lowMem) + textureRequestPixelBuffer = new int[textureRequestBufferPointer][16384]; + else + textureRequestPixelBuffer = new int[textureRequestBufferPointer][0x10000]; + for (int i = 0; i < 50; i++) + texturesPixelBuffer[i] = null; + } + } + + public static void loadTextures(FileArchive archive) { + textureCount = 0; + for (int index = 0; index < 51; index++) { + try { + textures[index] = new IndexedImage(archive, String.valueOf(index), 0); + if (lowMem && textures[index].resizeWidth == 128) { + textures[index].downscale(); + } else { + textures[index].resize(); + } + textureCount++; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + public static int getOverallColour(int textureId) { + if (averageTextureColours[textureId] != 0) + return averageTextureColours[textureId]; + int totalRed = 0; + int totalGreen = 0; + int totalBlue = 0; + int colourCount = currentPalette[textureId].length; + for (int ptr = 0; ptr < colourCount; ptr++) { + totalRed += currentPalette[textureId][ptr] >> 16 & 0xff; + totalGreen += currentPalette[textureId][ptr] >> 8 & 0xff; + totalBlue += currentPalette[textureId][ptr] & 0xff; + } + + int avgPaletteColour = (totalRed / colourCount << 16) + (totalGreen / colourCount << 8) + totalBlue / colourCount; + avgPaletteColour = adjustBrightness(avgPaletteColour, 1.3999999999999999D); + if (avgPaletteColour == 0) + avgPaletteColour = 1; + averageTextureColours[textureId] = avgPaletteColour; + return avgPaletteColour; + } + + public static void requestTextureUpdate(int textureId) { + if (texturesPixelBuffer[textureId] == null) { + return; + } + textureRequestPixelBuffer[textureRequestBufferPointer++] = texturesPixelBuffer[textureId]; + texturesPixelBuffer[textureId] = null; + } + + private static int[] getTexturePixels(int textureId) { + textureLastUsed[textureId] = lastTextureRetrievalCount++; + if (texturesPixelBuffer[textureId] != null) + return texturesPixelBuffer[textureId]; + int texturePixels[]; + if (textureRequestBufferPointer > 0) { + texturePixels = textureRequestPixelBuffer[--textureRequestBufferPointer]; + textureRequestPixelBuffer[textureRequestBufferPointer] = null; + } else { + int lastUsed = 0; + int target = -1; + for (int l = 0; l < textureCount; l++) + if (texturesPixelBuffer[l] != null && (textureLastUsed[l] < lastUsed || target == -1)) { + lastUsed = textureLastUsed[l]; + target = l; + } + + texturePixels = texturesPixelBuffer[target]; + texturesPixelBuffer[target] = null; + } + texturesPixelBuffer[textureId] = texturePixels; + IndexedImage background = textures[textureId]; + int texturePalette[] = currentPalette[textureId]; + if (lowMem) { + textureIsTransparant[textureId] = false; + for (int i1 = 0; i1 < 4096; i1++) { + int colour = texturePixels[i1] = texturePalette[background.palettePixels[i1]] & 0xf8f8ff; + if (colour == 0) + textureIsTransparant[textureId] = true; + texturePixels[4096 + i1] = colour - (colour >>> 3) & 0xf8f8ff; + texturePixels[8192 + i1] = colour - (colour >>> 2) & 0xf8f8ff; + texturePixels[12288 + i1] = colour - (colour >>> 2) - (colour >>> 3) & 0xf8f8ff; + } + + } else { + if (background.width == 64) { + for (int x = 0; x < 128; x++) { + for (int y = 0; y < 128; y++) + texturePixels[y + (x << 7)] = texturePalette[background.palettePixels[(y >> 1) + ((x >> 1) << 6)]]; + } + } else { + for (int i = 0; i < 16384; i++) + texturePixels[i] = texturePalette[background.palettePixels[i]]; + } + textureIsTransparant[textureId] = false; + for (int i = 0; i < 16384; i++) { + texturePixels[i] &= 0xf8f8ff; + int colour = texturePixels[i]; + if (colour == 0) + textureIsTransparant[textureId] = true; + texturePixels[16384 + i] = colour - (colour >>> 3) & 0xf8f8ff; + texturePixels[32768 + i] = colour - (colour >>> 2) & 0xf8f8ff; + texturePixels[49152 + i] = colour - (colour >>> 2) - (colour >>> 3) & 0xf8f8ff; + } + + } + return texturePixels; + } + + public static void setBrightness(double brightness) { + int j = 0; + for (int k = 0; k < 512; k++) { + double d1 = (double) (k / 8) / 64D + 0.0078125D; + double d2 = (double) (k & 7) / 8D + 0.0625D; + for (int k1 = 0; k1 < 128; k1++) { + double d3 = (double) k1 / 128D; + double r = d3; + double g = d3; + double b = d3; + if (d2 != 0.0D) { + double d7; + if (d3 < 0.5D) + d7 = d3 * (1.0D + d2); + else + d7 = (d3 + d2) - d3 * d2; + double d8 = 2D * d3 - d7; + double d9 = d1 + 0.33333333333333331D; + if (d9 > 1.0D) + d9--; + double d10 = d1; + double d11 = d1 - 0.33333333333333331D; + if (d11 < 0.0D) + d11++; + if (6D * d9 < 1.0D) + r = d8 + (d7 - d8) * 6D * d9; + else if (2D * d9 < 1.0D) + r = d7; + else if (3D * d9 < 2D) + r = d8 + (d7 - d8) * (0.66666666666666663D - d9) * 6D; + else + r = d8; + if (6D * d10 < 1.0D) + g = d8 + (d7 - d8) * 6D * d10; + else if (2D * d10 < 1.0D) + g = d7; + else if (3D * d10 < 2D) + g = d8 + (d7 - d8) * (0.66666666666666663D - d10) * 6D; + else + g = d8; + if (6D * d11 < 1.0D) + b = d8 + (d7 - d8) * 6D * d11; + else if (2D * d11 < 1.0D) + b = d7; + else if (3D * d11 < 2D) + b = d8 + (d7 - d8) * (0.66666666666666663D - d11) * 6D; + else + b = d8; + } + int byteR = (int) (r * 256D); + int byteG = (int) (g * 256D); + int byteB = (int) (b * 256D); + int rgb = (byteR << 16) + (byteG << 8) + byteB; + rgb = adjustBrightness(rgb, brightness); + if (rgb == 0) + rgb = 1; + hslToRgb[j++] = rgb; + } + + } + + for (int textureId = 0; textureId < 51; textureId++) + if (textures[textureId] != null) { + int originalPalette[] = textures[textureId].palette; + currentPalette[textureId] = new int[originalPalette.length]; + for (int colourId = 0; colourId < originalPalette.length; colourId++) { + currentPalette[textureId][colourId] = adjustBrightness(originalPalette[colourId], brightness); + if ((currentPalette[textureId][colourId] & 0xf8f8ff) == 0 && colourId != 0) + currentPalette[textureId][colourId] = 1; + } + + } + + for (int textureId = 0; textureId < 51; textureId++) + requestTextureUpdate(textureId); + + } + + private static int adjustBrightness(int rgb, double intensity) { + double r = (double) (rgb >> 16) / 256D; + double g = (double) (rgb >> 8 & 0xff) / 256D; + double b = (double) (rgb & 0xff) / 256D; + r = Math.pow(r, intensity); + g = Math.pow(g, intensity); + b = Math.pow(b, intensity); + int r_byte = (int) (r * 256D); + int g_byte = (int) (g * 256D); + int b_byte = (int) (b * 256D); + return (r_byte << 16) + (g_byte << 8) + b_byte; + } + + public static void drawShadedTriangle(int y_a, int y_b, int y_c, int x_a, int x_b, int x_c, int hsl1, int hsl2, int hsl3, float z_a, float z_b, float z_c) { + if (z_a < 0 || z_b < 0 || z_c < 0) + return; + int rgb1 = hslToRgb[hsl1]; + int rgb2 = hslToRgb[hsl2]; + int rgb3 = hslToRgb[hsl3]; + int r1 = rgb1 >> 16 & 0xff; + int g1 = rgb1 >> 8 & 0xff; + int b1 = rgb1 & 0xff; + int r2 = rgb2 >> 16 & 0xff; + int g2 = rgb2 >> 8 & 0xff; + int b2 = rgb2 & 0xff; + int r3 = rgb3 >> 16 & 0xff; + int g3 = rgb3 >> 8 & 0xff; + int b3 = rgb3 & 0xff; + int a_to_b = 0; + int dr1 = 0; + int dg1 = 0; + int db1 = 0; + if (y_b != y_a) { + a_to_b = (x_b - x_a << 16) / (y_b - y_a); + dr1 = (r2 - r1 << 16) / (y_b - y_a); + dg1 = (g2 - g1 << 16) / (y_b - y_a); + db1 = (b2 - b1 << 16) / (y_b - y_a); + } + int b_to_c = 0; + int dr2 = 0; + int dg2 = 0; + int db2 = 0; + if (y_c != y_b) { + b_to_c = (x_c - x_b << 16) / (y_c - y_b); + dr2 = (r3 - r2 << 16) / (y_c - y_b); + dg2 = (g3 - g2 << 16) / (y_c - y_b); + db2 = (b3 - b2 << 16) / (y_c - y_b); + } + int c_to_a = 0; + int dr3 = 0; + int dg3 = 0; + int db3 = 0; + if (y_c != y_a) { + c_to_a = (x_a - x_c << 16) / (y_a - y_c); + dr3 = (r1 - r3 << 16) / (y_a - y_c); + dg3 = (g1 - g3 << 16) / (y_a - y_c); + db3 = (b1 - b3 << 16) / (y_a - y_c); + } + float b_aX = x_b - x_a; + float b_aY = y_b - y_a; + float c_aX = x_c - x_a; + float c_aY = y_c - y_a; + float b_aZ = z_b - z_a; + float c_aZ = z_c - z_a; + + float div = b_aX * c_aY - c_aX * b_aY; + float depth_slope = (b_aZ * c_aY - c_aZ * b_aY) / div; + float depth_increment = (c_aZ * b_aX - b_aZ * c_aX) / div; + if (y_a <= y_b && y_a <= y_c) { + if (y_a >= Rasterizer2D.bottomY) { + return; + } + if (y_b > Rasterizer2D.bottomY) { + y_b = Rasterizer2D.bottomY; + } + if (y_c > Rasterizer2D.bottomY) { + y_c = Rasterizer2D.bottomY; + } + z_a = z_a - depth_slope * x_a + depth_slope; + if (y_b < y_c) { + x_c = x_a <<= 16; + r3 = r1 <<= 16; + g3 = g1 <<= 16; + b3 = b1 <<= 16; + if (y_a < 0) { + x_c -= c_to_a * y_a; + x_a -= a_to_b * y_a; + r3 -= dr3 * y_a; + g3 -= dg3 * y_a; + b3 -= db3 * y_a; + r1 -= dr1 * y_a; + g1 -= dg1 * y_a; + b1 -= db1 * y_a; + z_a -= depth_increment * y_a; + y_a = 0; + } + x_b <<= 16; + r2 <<= 16; + g2 <<= 16; + b2 <<= 16; + if (y_b < 0) { + x_b -= b_to_c * y_b; + r2 -= dr2 * y_b; + g2 -= dg2 * y_b; + b2 -= db2 * y_b; + y_b = 0; + } + if (y_a != y_b && c_to_a < a_to_b || y_a == y_b && c_to_a > b_to_c) { + y_c -= y_b; + y_b -= y_a; + for (y_a = scanOffsets[y_a]; --y_b >= 0; y_a += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_c >> 16, x_a >> 16, r3, g3, b3, r1, g1, b1, z_a, + depth_slope); + x_c += c_to_a; + x_a += a_to_b; + r3 += dr3; + g3 += dg3; + b3 += db3; + r1 += dr1; + g1 += dg1; + b1 += db1; + z_a += depth_increment; + } + while (--y_c >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_c >> 16, x_b >> 16, r3, g3, b3, r2, g2, b2, z_a, + depth_slope); + x_c += c_to_a; + x_b += b_to_c; + r3 += dr3; + g3 += dg3; + b3 += db3; + r2 += dr2; + g2 += dg2; + b2 += db2; + y_a += Rasterizer2D.width; + z_a += depth_increment; + } + return; + } + y_c -= y_b; + y_b -= y_a; + for (y_a = scanOffsets[y_a]; --y_b >= 0; y_a += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_a >> 16, x_c >> 16, r1, g1, b1, r3, g3, b3, z_a, + depth_slope); + x_c += c_to_a; + x_a += a_to_b; + r3 += dr3; + g3 += dg3; + b3 += db3; + r1 += dr1; + g1 += dg1; + b1 += db1; + z_a += depth_increment; + } + while (--y_c >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_b >> 16, x_c >> 16, r2, g2, b2, r3, g3, b3, z_a, + depth_slope); + x_c += c_to_a; + x_b += b_to_c; + r3 += dr3; + g3 += dg3; + b3 += db3; + r2 += dr2; + g2 += dg2; + b2 += db2; + y_a += Rasterizer2D.width; + z_a += depth_increment; + } + return; + } + x_b = x_a <<= 16; + r2 = r1 <<= 16; + g2 = g1 <<= 16; + b2 = b1 <<= 16; + if (y_a < 0) { + x_b -= c_to_a * y_a; + x_a -= a_to_b * y_a; + r2 -= dr3 * y_a; + g2 -= dg3 * y_a; + b2 -= db3 * y_a; + r1 -= dr1 * y_a; + g1 -= dg1 * y_a; + b1 -= db1 * y_a; + z_a -= depth_increment * y_a; + y_a = 0; + } + x_c <<= 16; + r3 <<= 16; + g3 <<= 16; + b3 <<= 16; + if (y_c < 0) { + x_c -= b_to_c * y_c; + r3 -= dr2 * y_c; + g3 -= dg2 * y_c; + b3 -= db2 * y_c; + y_c = 0; + } + if (y_a != y_c && c_to_a < a_to_b || y_a == y_c && b_to_c > a_to_b) { + y_b -= y_c; + y_c -= y_a; + for (y_a = scanOffsets[y_a]; --y_c >= 0; y_a += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_b >> 16, x_a >> 16, r2, g2, b2, r1, g1, b1, z_a, + depth_slope); + x_b += c_to_a; + x_a += a_to_b; + r2 += dr3; + g2 += dg3; + b2 += db3; + r1 += dr1; + g1 += dg1; + b1 += db1; + z_a += depth_increment; + } + while (--y_b >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_c >> 16, x_a >> 16, r3, g3, b3, r1, g1, b1, z_a, + depth_slope); + x_c += b_to_c; + x_a += a_to_b; + r3 += dr2; + g3 += dg2; + b3 += db2; + r1 += dr1; + g1 += dg1; + b1 += db1; + y_a += Rasterizer2D.width; + z_a += depth_increment; + } + return; + } + y_b -= y_c; + y_c -= y_a; + for (y_a = scanOffsets[y_a]; --y_c >= 0; y_a += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_a >> 16, x_b >> 16, r1, g1, b1, r2, g2, b2, z_a, depth_slope); + x_b += c_to_a; + x_a += a_to_b; + r2 += dr3; + g2 += dg3; + b2 += db3; + r1 += dr1; + g1 += dg1; + b1 += db1; + z_a += depth_increment; + } + while (--y_b >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_a, x_a >> 16, x_c >> 16, r1, g1, b1, r3, g3, b3, z_a, depth_slope); + x_c += b_to_c; + x_a += a_to_b; + r3 += dr2; + g3 += dg2; + b3 += db2; + r1 += dr1; + g1 += dg1; + b1 += db1; + y_a += Rasterizer2D.width; + z_a += depth_increment; + } + return; + } + if (y_b <= y_c) { + if (y_b >= Rasterizer2D.bottomY) { + return; + } + if (y_c > Rasterizer2D.bottomY) { + y_c = Rasterizer2D.bottomY; + } + if (y_a > Rasterizer2D.bottomY) { + y_a = Rasterizer2D.bottomY; + } + z_b = z_b - depth_slope * x_b + depth_slope; + if (y_c < y_a) { + x_a = x_b <<= 16; + r1 = r2 <<= 16; + g1 = g2 <<= 16; + b1 = b2 <<= 16; + if (y_b < 0) { + x_a -= a_to_b * y_b; + x_b -= b_to_c * y_b; + r1 -= dr1 * y_b; + g1 -= dg1 * y_b; + b1 -= db1 * y_b; + r2 -= dr2 * y_b; + g2 -= dg2 * y_b; + b2 -= db2 * y_b; + z_b -= depth_increment * y_b; + y_b = 0; + } + x_c <<= 16; + r3 <<= 16; + g3 <<= 16; + b3 <<= 16; + if (y_c < 0) { + x_c -= c_to_a * y_c; + r3 -= dr3 * y_c; + g3 -= dg3 * y_c; + b3 -= db3 * y_c; + y_c = 0; + } + if (y_b != y_c && a_to_b < b_to_c || y_b == y_c && a_to_b > c_to_a) { + y_a -= y_c; + y_c -= y_b; + for (y_b = scanOffsets[y_b]; --y_c >= 0; y_b += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_a >> 16, x_b >> 16, r1, g1, b1, r2, g2, b2, z_b, + depth_slope); + x_a += a_to_b; + x_b += b_to_c; + r1 += dr1; + g1 += dg1; + b1 += db1; + r2 += dr2; + g2 += dg2; + b2 += db2; + z_b += depth_increment; + } + while (--y_a >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_a >> 16, x_c >> 16, r1, g1, b1, r3, g3, b3, z_b, + depth_slope); + x_a += a_to_b; + x_c += c_to_a; + r1 += dr1; + g1 += dg1; + b1 += db1; + r3 += dr3; + g3 += dg3; + b3 += db3; + y_b += Rasterizer2D.width; + z_b += depth_increment; + } + return; + } + y_a -= y_c; + y_c -= y_b; + for (y_b = scanOffsets[y_b]; --y_c >= 0; y_b += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_b >> 16, x_a >> 16, r2, g2, b2, r1, g1, b1, z_b, + depth_slope); + x_a += a_to_b; + x_b += b_to_c; + r1 += dr1; + g1 += dg1; + b1 += db1; + r2 += dr2; + g2 += dg2; + b2 += db2; + z_b += depth_increment; + } + while (--y_a >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_c >> 16, x_a >> 16, r3, g3, b3, r1, g1, b1, z_b, + depth_slope); + x_a += a_to_b; + x_c += c_to_a; + r1 += dr1; + g1 += dg1; + b1 += db1; + r3 += dr3; + g3 += dg3; + b3 += db3; + y_b += Rasterizer2D.width; + z_b += depth_increment; + } + return; + } + x_c = x_b <<= 16; + r3 = r2 <<= 16; + g3 = g2 <<= 16; + b3 = b2 <<= 16; + if (y_b < 0) { + x_c -= a_to_b * y_b; + x_b -= b_to_c * y_b; + r3 -= dr1 * y_b; + g3 -= dg1 * y_b; + b3 -= db1 * y_b; + r2 -= dr2 * y_b; + g2 -= dg2 * y_b; + b2 -= db2 * y_b; + z_b -= depth_increment * y_b; + y_b = 0; + } + x_a <<= 16; + r1 <<= 16; + g1 <<= 16; + b1 <<= 16; + if (y_a < 0) { + x_a -= c_to_a * y_a; + r1 -= dr3 * y_a; + g1 -= dg3 * y_a; + b1 -= db3 * y_a; + y_a = 0; + } + if (a_to_b < b_to_c) { + y_c -= y_a; + y_a -= y_b; + for (y_b = scanOffsets[y_b]; --y_a >= 0; y_b += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_c >> 16, x_b >> 16, r3, g3, b3, r2, g2, b2, z_b, + depth_slope); + x_c += a_to_b; + x_b += b_to_c; + r3 += dr1; + g3 += dg1; + b3 += db1; + r2 += dr2; + g2 += dg2; + b2 += db2; + z_b += depth_increment; + } + while (--y_c >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_a >> 16, x_b >> 16, r1, g1, b1, r2, g2, b2, z_b, + depth_slope); + x_a += c_to_a; + x_b += b_to_c; + r1 += dr3; + g1 += dg3; + b1 += db3; + r2 += dr2; + g2 += dg2; + b2 += db2; + y_b += Rasterizer2D.width; + z_b += depth_increment; + } + return; + } + y_c -= y_a; + y_a -= y_b; + for (y_b = scanOffsets[y_b]; --y_a >= 0; y_b += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_b >> 16, x_c >> 16, r2, g2, b2, r3, g3, b3, z_b, depth_slope); + x_c += a_to_b; + x_b += b_to_c; + r3 += dr1; + g3 += dg1; + b3 += db1; + r2 += dr2; + g2 += dg2; + b2 += db2; + z_b += depth_increment; + } + while (--y_c >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_b, x_b >> 16, x_a >> 16, r2, g2, b2, r1, g1, b1, z_b, depth_slope); + x_a += c_to_a; + x_b += b_to_c; + r1 += dr3; + g1 += dg3; + b1 += db3; + r2 += dr2; + g2 += dg2; + b2 += db2; + y_b += Rasterizer2D.width; + z_b += depth_increment; + } + return; + } + if (y_c >= Rasterizer2D.bottomY) { + return; + } + if (y_a > Rasterizer2D.bottomY) { + y_a = Rasterizer2D.bottomY; + } + if (y_b > Rasterizer2D.bottomY) { + y_b = Rasterizer2D.bottomY; + } + z_c = z_c - depth_slope * x_c + depth_slope; + if (y_a < y_b) { + x_b = x_c <<= 16; + r2 = r3 <<= 16; + g2 = g3 <<= 16; + b2 = b3 <<= 16; + if (y_c < 0) { + x_b -= b_to_c * y_c; + x_c -= c_to_a * y_c; + r2 -= dr2 * y_c; + g2 -= dg2 * y_c; + b2 -= db2 * y_c; + r3 -= dr3 * y_c; + g3 -= dg3 * y_c; + b3 -= db3 * y_c; + z_c -= depth_increment * y_c; + y_c = 0; + } + x_a <<= 16; + r1 <<= 16; + g1 <<= 16; + b1 <<= 16; + if (y_a < 0) { + x_a -= a_to_b * y_a; + r1 -= dr1 * y_a; + g1 -= dg1 * y_a; + b1 -= db1 * y_a; + y_a = 0; + } + if (b_to_c < c_to_a) { + y_b -= y_a; + y_a -= y_c; + for (y_c = scanOffsets[y_c]; --y_a >= 0; y_c += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_b >> 16, x_c >> 16, r2, g2, b2, r3, g3, b3, z_c, + depth_slope); + x_b += b_to_c; + x_c += c_to_a; + r2 += dr2; + g2 += dg2; + b2 += db2; + r3 += dr3; + g3 += dg3; + b3 += db3; + z_c += depth_increment; + } + while (--y_b >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_b >> 16, x_a >> 16, r2, g2, b2, r1, g1, b1, z_c, + depth_slope); + x_b += b_to_c; + x_a += a_to_b; + r2 += dr2; + g2 += dg2; + b2 += db2; + r1 += dr1; + g1 += dg1; + b1 += db1; + y_c += Rasterizer2D.width; + z_c += depth_increment; + } + return; + } + y_b -= y_a; + y_a -= y_c; + for (y_c = scanOffsets[y_c]; --y_a >= 0; y_c += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_c >> 16, x_b >> 16, r3, g3, b3, r2, g2, b2, z_c, depth_slope); + x_b += b_to_c; + x_c += c_to_a; + r2 += dr2; + g2 += dg2; + b2 += db2; + r3 += dr3; + g3 += dg3; + b3 += db3; + z_c += depth_increment; + } + while (--y_b >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_a >> 16, x_b >> 16, r1, g1, b1, r2, g2, b2, z_c, depth_slope); + x_b += b_to_c; + x_a += a_to_b; + r2 += dr2; + g2 += dg2; + b2 += db2; + r1 += dr1; + g1 += dg1; + b1 += db1; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + return; + } + x_a = x_c <<= 16; + r1 = r3 <<= 16; + g1 = g3 <<= 16; + b1 = b3 <<= 16; + if (y_c < 0) { + x_a -= b_to_c * y_c; + x_c -= c_to_a * y_c; + r1 -= dr2 * y_c; + g1 -= dg2 * y_c; + b1 -= db2 * y_c; + r3 -= dr3 * y_c; + g3 -= dg3 * y_c; + b3 -= db3 * y_c; + z_c -= depth_increment * y_c; + y_c = 0; + } + x_b <<= 16; + r2 <<= 16; + g2 <<= 16; + b2 <<= 16; + if (y_b < 0) { + x_b -= a_to_b * y_b; + r2 -= dr1 * y_b; + g2 -= dg1 * y_b; + b2 -= db1 * y_b; + y_b = 0; + } + if (b_to_c < c_to_a) { + y_a -= y_b; + y_b -= y_c; + for (y_c = scanOffsets[y_c]; --y_b >= 0; y_c += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_a >> 16, x_c >> 16, r1, g1, b1, r3, g3, b3, z_c, depth_slope); + x_a += b_to_c; + x_c += c_to_a; + r1 += dr2; + g1 += dg2; + b1 += db2; + r3 += dr3; + g3 += dg3; + b3 += db3; + z_c += depth_increment; + } + while (--y_a >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_b >> 16, x_c >> 16, r2, g2, b2, r3, g3, b3, z_c, depth_slope); + x_b += a_to_b; + x_c += c_to_a; + r2 += dr1; + g2 += dg1; + b2 += db1; + r3 += dr3; + g3 += dg3; + b3 += db3; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + return; + } + y_a -= y_b; + y_b -= y_c; + for (y_c = scanOffsets[y_c]; --y_b >= 0; y_c += Rasterizer2D.width) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_c >> 16, x_a >> 16, r3, g3, b3, r1, g1, b1, z_c, depth_slope); + x_a += b_to_c; + x_c += c_to_a; + r1 += dr2; + g1 += dg2; + b1 += db2; + r3 += dr3; + g3 += dg3; + b3 += db3; + z_c += depth_increment; + } + while (--y_a >= 0) { + drawShadedScanline(Rasterizer2D.pixels, y_c, x_c >> 16, x_b >> 16, r3, g3, b3, r2, g2, b2, z_c, depth_slope); + x_b += a_to_b; + x_c += c_to_a; + r2 += dr1; + g2 += dg1; + b2 += db1; + r3 += dr3; + g3 += dg3; + b3 += db3; + y_c += Rasterizer2D.width; + z_c += depth_increment; + } + } + + public static void drawShadedScanline(int[] dest, int offset, int x1, int x2, int r1, int g1, int b1, int r2, int g2, int b2, float depth, float depth_slope) { + int n = x2 - x1; + if (n <= 0) { + return; + } + r2 = (r2 - r1) / n; + g2 = (g2 - g1) / n; + b2 = (b2 - b1) / n; + if (textureOutOfDrawingBounds) { + if (x2 > Rasterizer2D.lastX) { + n -= x2 - Rasterizer2D.lastX; + x2 = Rasterizer2D.lastX; + } + if (x1 < 0) { + n = x2; + r1 -= x1 * r2; + g1 -= x1 * g2; + b1 -= x1 * b2; + x1 = 0; + } + } + if (x1 < x2) { + offset += x1; + depth += depth_slope * (float) x1; + if (alpha == 0) { + while (--n >= 0) { + if (true) { + dest[offset] = (r1 & 0xff0000) | (g1 >> 8 & 0xff00) | (b1 >> 16 & 0xff); + Rasterizer2D.depthBuffer[offset] = depth; + } + depth += depth_slope; + r1 += r2; + g1 += g2; + b1 += b2; + offset++; + } + } else { + final int a1 = alpha; + final int a2 = 256 - alpha; + int rgb; + int dst; + while (--n >= 0) { + rgb = (r1 & 0xff0000) | (g1 >> 8 & 0xff00) | (b1 >> 16 & 0xff); + rgb = ((rgb & 0xff00ff) * a2 >> 8 & 0xff00ff) + ((rgb & 0xff00) * a2 >> 8 & 0xff00); + dst = dest[offset]; + if (true) { + dest[offset] = rgb + ((dst & 0xff00ff) * a1 >> 8 & 0xff00ff) + + ((dst & 0xff00) * a1 >> 8 & 0xff00); + Rasterizer2D.depthBuffer[offset] = depth; + } + depth += depth_slope; + r1 += r2; + g1 += g2; + b1 += b2; + offset++; + } + } + } + } + + public static void drawFlatTriangle(int y_a, int y_b, int y_c, int x_a, int x_b, int x_c, int k1, float z_a, + float z_b, float z_c) { + if (z_a < 0 || z_b < 0 || z_c < 0) { + return; + } + int a_to_b = 0; + if (y_b != y_a) { + a_to_b = (x_b - x_a << 16) / (y_b - y_a); + } + int b_to_c = 0; + if (y_c != y_b) { + b_to_c = (x_c - x_b << 16) / (y_c - y_b); + } + int c_to_a = 0; + if (y_c != y_a) { + c_to_a = (x_a - x_c << 16) / (y_a - y_c); + } + float b_aX = x_b - x_a; + float b_aY = y_b - y_a; + float c_aX = x_c - x_a; + float c_aY = y_c - y_a; + float b_aZ = z_b - z_a; + float c_aZ = z_c - z_a; + + float div = b_aX * c_aY - c_aX * b_aY; + float depth_slope = (b_aZ * c_aY - c_aZ * b_aY) / div; + float depth_increment = (c_aZ * b_aX - b_aZ * c_aX) / div; + if (y_a <= y_b && y_a <= y_c) { + if (y_a >= Rasterizer2D.bottomY) + return; + if (y_b > Rasterizer2D.bottomY) + y_b = Rasterizer2D.bottomY; + if (y_c > Rasterizer2D.bottomY) + y_c = Rasterizer2D.bottomY; + z_a = z_a - depth_slope * x_a + depth_slope; + if (y_b < y_c) { + x_c = x_a <<= 16; + if (y_a < 0) { + x_c -= c_to_a * y_a; + x_a -= a_to_b * y_a; + z_a -= depth_increment * y_a; + y_a = 0; + } + x_b <<= 16; + if (y_b < 0) { + x_b -= b_to_c * y_b; + y_b = 0; + } + if (y_a != y_b && c_to_a < a_to_b || y_a == y_b && c_to_a > b_to_c) { + y_c -= y_b; + y_b -= y_a; + for (y_a = scanOffsets[y_a]; --y_b >= 0; y_a += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_c >> 16, x_a >> 16, z_a, depth_slope); + x_c += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + } + + while (--y_c >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_c >> 16, x_b >> 16, z_a, depth_slope); + x_c += c_to_a; + x_b += b_to_c; + y_a += Rasterizer2D.width; + z_a += depth_increment; + } + return; + } + y_c -= y_b; + y_b -= y_a; + for (y_a = scanOffsets[y_a]; --y_b >= 0; y_a += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_a >> 16, x_c >> 16, z_a, depth_slope); + x_c += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + } + + while (--y_c >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_b >> 16, x_c >> 16, z_a, depth_slope); + x_c += c_to_a; + x_b += b_to_c; + y_a += Rasterizer2D.width; + z_a += depth_increment; + } + return; + } + x_b = x_a <<= 16; + if (y_a < 0) { + x_b -= c_to_a * y_a; + x_a -= a_to_b * y_a; + z_a -= depth_increment * y_a; + y_a = 0; + + } + x_c <<= 16; + if (y_c < 0) { + x_c -= b_to_c * y_c; + y_c = 0; + } + if (y_a != y_c && c_to_a < a_to_b || y_a == y_c && b_to_c > a_to_b) { + y_b -= y_c; + y_c -= y_a; + for (y_a = scanOffsets[y_a]; --y_c >= 0; y_a += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_b >> 16, x_a >> 16, z_a, depth_slope); + z_a += depth_increment; + x_b += c_to_a; + x_a += a_to_b; + } + + while (--y_b >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_c >> 16, x_a >> 16, z_a, depth_slope); + z_a += depth_increment; + x_c += b_to_c; + x_a += a_to_b; + y_a += Rasterizer2D.width; + } + return; + } + y_b -= y_c; + y_c -= y_a; + for (y_a = scanOffsets[y_a]; --y_c >= 0; y_a += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_a >> 16, x_b >> 16, z_a, depth_slope); + z_a += depth_increment; + x_b += c_to_a; + x_a += a_to_b; + } + + while (--y_b >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_a, k1, x_a >> 16, x_c >> 16, z_a, depth_slope); + z_a += depth_increment; + x_c += b_to_c; + x_a += a_to_b; + y_a += Rasterizer2D.width; + } + return; + } + if (y_b <= y_c) { + if (y_b >= Rasterizer2D.bottomY) + return; + if (y_c > Rasterizer2D.bottomY) + y_c = Rasterizer2D.bottomY; + if (y_a > Rasterizer2D.bottomY) + y_a = Rasterizer2D.bottomY; + z_b = z_b - depth_slope * x_b + depth_slope; + if (y_c < y_a) { + x_a = x_b <<= 16; + if (y_b < 0) { + x_a -= a_to_b * y_b; + x_b -= b_to_c * y_b; + z_b -= depth_increment * y_b; + y_b = 0; + } + x_c <<= 16; + if (y_c < 0) { + x_c -= c_to_a * y_c; + y_c = 0; + } + if (y_b != y_c && a_to_b < b_to_c || y_b == y_c && a_to_b > c_to_a) { + y_a -= y_c; + y_c -= y_b; + for (y_b = scanOffsets[y_b]; --y_c >= 0; y_b += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_a >> 16, x_b >> 16, z_b, depth_slope); + z_b += depth_increment; + x_a += a_to_b; + x_b += b_to_c; + } + + while (--y_a >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_a >> 16, x_c >> 16, z_b, depth_slope); + z_b += depth_increment; + x_a += a_to_b; + x_c += c_to_a; + y_b += Rasterizer2D.width; + } + return; + } + y_a -= y_c; + y_c -= y_b; + for (y_b = scanOffsets[y_b]; --y_c >= 0; y_b += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_b >> 16, x_a >> 16, z_b, depth_slope); + z_b += depth_increment; + x_a += a_to_b; + x_b += b_to_c; + } + + while (--y_a >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_c >> 16, x_a >> 16, z_b, depth_slope); + z_b += depth_increment; + x_a += a_to_b; + x_c += c_to_a; + y_b += Rasterizer2D.width; + } + return; + } + x_c = x_b <<= 16; + if (y_b < 0) { + x_c -= a_to_b * y_b; + x_b -= b_to_c * y_b; + z_b -= depth_increment * y_b; + y_b = 0; + } + x_a <<= 16; + if (y_a < 0) { + x_a -= c_to_a * y_a; + y_a = 0; + } + if (a_to_b < b_to_c) { + y_c -= y_a; + y_a -= y_b; + for (y_b = scanOffsets[y_b]; --y_a >= 0; y_b += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_c >> 16, x_b >> 16, z_b, depth_slope); + z_b += depth_increment; + x_c += a_to_b; + x_b += b_to_c; + } + + while (--y_c >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_a >> 16, x_b >> 16, z_b, depth_slope); + z_b += depth_increment; + x_a += c_to_a; + x_b += b_to_c; + y_b += Rasterizer2D.width; + } + return; + } + y_c -= y_a; + y_a -= y_b; + for (y_b = scanOffsets[y_b]; --y_a >= 0; y_b += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_b >> 16, x_c >> 16, z_b, depth_slope); + z_b += depth_increment; + x_c += a_to_b; + x_b += b_to_c; + } + + while (--y_c >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_b, k1, x_b >> 16, x_a >> 16, z_b, depth_slope); + z_b += depth_increment; + x_a += c_to_a; + x_b += b_to_c; + y_b += Rasterizer2D.width; + } + return; + } + if (y_c >= Rasterizer2D.bottomY) + return; + if (y_a > Rasterizer2D.bottomY) + y_a = Rasterizer2D.bottomY; + if (y_b > Rasterizer2D.bottomY) + y_b = Rasterizer2D.bottomY; + z_c = z_c - depth_slope * x_c + depth_slope; + if (y_a < y_b) { + x_b = x_c <<= 16; + if (y_c < 0) { + x_b -= b_to_c * y_c; + x_c -= c_to_a * y_c; + z_c -= depth_increment * y_c; + y_c = 0; + } + x_a <<= 16; + if (y_a < 0) { + x_a -= a_to_b * y_a; + y_a = 0; + } + if (b_to_c < c_to_a) { + y_b -= y_a; + y_a -= y_c; + for (y_c = scanOffsets[y_c]; --y_a >= 0; y_c += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_b >> 16, x_c >> 16, z_c, depth_slope); + z_c += depth_increment; + x_b += b_to_c; + x_c += c_to_a; + } + + while (--y_b >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_b >> 16, x_a >> 16, z_c, depth_slope); + z_c += depth_increment; + x_b += b_to_c; + x_a += a_to_b; + y_c += Rasterizer2D.width; + } + return; + } + y_b -= y_a; + y_a -= y_c; + for (y_c = scanOffsets[y_c]; --y_a >= 0; y_c += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_c >> 16, x_b >> 16, z_c, depth_slope); + z_c += depth_increment; + x_b += b_to_c; + x_c += c_to_a; + } + + while (--y_b >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_a >> 16, x_b >> 16, z_c, depth_slope); + z_c += depth_increment; + x_b += b_to_c; + x_a += a_to_b; + y_c += Rasterizer2D.width; + } + return; + } + x_a = x_c <<= 16; + if (y_c < 0) { + x_a -= b_to_c * y_c; + x_c -= c_to_a * y_c; + z_c -= depth_increment * y_c; + y_c = 0; + } + x_b <<= 16; + if (y_b < 0) { + x_b -= a_to_b * y_b; + y_b = 0; + } + if (b_to_c < c_to_a) { + y_a -= y_b; + y_b -= y_c; + for (y_c = scanOffsets[y_c]; --y_b >= 0; y_c += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_a >> 16, x_c >> 16, z_c, depth_slope); + z_c += depth_increment; + x_a += b_to_c; + x_c += c_to_a; + } + + while (--y_a >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_b >> 16, x_c >> 16, z_c, depth_slope); + z_c += depth_increment; + x_b += a_to_b; + x_c += c_to_a; + y_c += Rasterizer2D.width; + } + return; + } + y_a -= y_b; + y_b -= y_c; + for (y_c = scanOffsets[y_c]; --y_b >= 0; y_c += Rasterizer2D.width) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_c >> 16, x_a >> 16, z_c, depth_slope); + z_c += depth_increment; + x_a += b_to_c; + x_c += c_to_a; + } + + while (--y_a >= 0) { + drawFlatTexturedScanline(Rasterizer2D.pixels, y_c, k1, x_c >> 16, x_b >> 16, z_c, depth_slope); + z_c += depth_increment; + x_b += a_to_b; + x_c += c_to_a; + y_c += Rasterizer2D.width; + } + } + + private static void drawFlatTexturedScanline(int dest[], int dest_off, int loops, int start_x, int end_x, + float depth, float depth_slope) { + int rgb; + if (textureOutOfDrawingBounds) { + if (end_x > Rasterizer2D.lastX) + end_x = Rasterizer2D.lastX; + if (start_x < 0) + start_x = 0; + } + if (start_x >= end_x) + return; + dest_off += start_x; + rgb = end_x - start_x >> 2; + depth += depth_slope * (float) start_x; + if (alpha == 0) { + while (--rgb >= 0) { + for (int i = 0; i < 4; i++) { + if (true) { + dest[dest_off] = loops; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + } + } + for (rgb = end_x - start_x & 3; --rgb >= 0;) { + if (true) { + dest[dest_off] = loops; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + } + return; + } + int dest_alpha = alpha; + int src_alpha = 256 - alpha; + loops = ((loops & 0xff00ff) * src_alpha >> 8 & 0xff00ff) + ((loops & 0xff00) * src_alpha >> 8 & 0xff00); + while (--rgb >= 0) { + for (int i = 0; i < 4; i++) { + if (true) { + dest[dest_off] = loops + ((dest[dest_off] & 0xff00ff) * dest_alpha >> 8 & 0xff00ff) + + ((dest[dest_off] & 0xff00) * dest_alpha >> 8 & 0xff00); + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + } + } + for (rgb = end_x - start_x & 3; --rgb >= 0;) { + if (true) { + dest[dest_off] = loops + ((dest[dest_off] & 0xff00ff) * dest_alpha >> 8 & 0xff00ff) + + ((dest[dest_off] & 0xff00) * dest_alpha >> 8 & 0xff00); + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + } + } + + public static void drawTexturedTriangle(int y_a, int y_b, int y_c, int x_a, int x_b, int x_c, int k1, int l1, + int i2, int Px, int Mx, int Nx, int Pz, int Mz, int Nz, int Py, int My, int Ny, int k4, float z_a, + float z_b, float z_c) { + if (z_a < 0 || z_b < 0 || z_c < 0) + return; + int texture[] = getTexturePixels(k4); + aBoolean1463 = !textureIsTransparant[k4]; + Mx = Px - Mx; + Mz = Pz - Mz; + My = Py - My; + Nx -= Px; + Nz -= Pz; + Ny -= Py; + int Oa = Nx * Pz - Nz * Px << (SceneGraph.viewDistance == 9 ? 14 : 15); + int Ha = Nz * Py - Ny * Pz << 8; + int Va = Ny * Px - Nx * Py << 5; + int Ob = Mx * Pz - Mz * Px << (SceneGraph.viewDistance == 9 ? 14 : 15); + int Hb = Mz * Py - My * Pz << 8; + int Vb = My * Px - Mx * Py << 5; + int Oc = Mz * Nx - Mx * Nz << (SceneGraph.viewDistance == 9 ? 14 : 15); + int Hc = My * Nz - Mz * Ny << 8; + int Vc = Mx * Ny - My * Nx << 5; + int a_to_b = 0; + int grad_a_off = 0; + if (y_b != y_a) { + a_to_b = (x_b - x_a << 16) / (y_b - y_a); + grad_a_off = (l1 - k1 << 16) / (y_b - y_a); + } + int b_to_c = 0; + int grad_b_off = 0; + if (y_c != y_b) { + b_to_c = (x_c - x_b << 16) / (y_c - y_b); + grad_b_off = (i2 - l1 << 16) / (y_c - y_b); + } + int c_to_a = 0; + int grad_c_off = 0; + if (y_c != y_a) { + c_to_a = (x_a - x_c << 16) / (y_a - y_c); + grad_c_off = (k1 - i2 << 16) / (y_a - y_c); + } + float b_aX = x_b - x_a; + float b_aY = y_b - y_a; + float c_aX = x_c - x_a; + float c_aY = y_c - y_a; + float b_aZ = z_b - z_a; + float c_aZ = z_c - z_a; + + float div = b_aX * c_aY - c_aX * b_aY; + float depth_slope = (b_aZ * c_aY - c_aZ * b_aY) / div; + float depth_increment = (c_aZ * b_aX - b_aZ * c_aX) / div; + if (y_a <= y_b && y_a <= y_c) { + if (y_a >= Rasterizer2D.bottomY) + return; + if (y_b > Rasterizer2D.bottomY) + y_b = Rasterizer2D.bottomY; + if (y_c > Rasterizer2D.bottomY) + y_c = Rasterizer2D.bottomY; + z_a = z_a - depth_slope * x_a + depth_slope; + if (y_b < y_c) { + x_c = x_a <<= 16; + i2 = k1 <<= 16; + if (y_a < 0) { + x_c -= c_to_a * y_a; + x_a -= a_to_b * y_a; + z_a -= depth_increment * y_a; + i2 -= grad_c_off * y_a; + k1 -= grad_a_off * y_a; + y_a = 0; + } + x_b <<= 16; + l1 <<= 16; + if (y_b < 0) { + x_b -= b_to_c * y_b; + l1 -= grad_b_off * y_b; + y_b = 0; + } + int k8 = y_a - originViewY; + Oa += Va * k8; + Ob += Vb * k8; + Oc += Vc * k8; + if (y_a != y_b && c_to_a < a_to_b || y_a == y_b && c_to_a > b_to_c) { + y_c -= y_b; + y_b -= y_a; + y_a = scanOffsets[y_a]; + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_c >> 16, x_a >> 16, i2 >> 8, k1 >> 8, Oa, + Ob, Oc, Ha, Hb, Hc, z_a, depth_slope); + x_c += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + i2 += grad_c_off; + k1 += grad_a_off; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_c >> 16, x_b >> 16, i2 >> 8, l1 >> 8, Oa, + Ob, Oc, Ha, Hb, Hc, z_a, depth_slope); + x_c += c_to_a; + x_b += b_to_c; + z_a += depth_increment; + i2 += grad_c_off; + l1 += grad_b_off; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + y_c -= y_b; + y_b -= y_a; + y_a = scanOffsets[y_a]; + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_a >> 16, x_c >> 16, k1 >> 8, i2 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_a, depth_slope); + x_c += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + i2 += grad_c_off; + k1 += grad_a_off; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_b >> 16, x_c >> 16, l1 >> 8, i2 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_a, depth_slope); + x_c += c_to_a; + x_b += b_to_c; + z_a += depth_increment; + i2 += grad_c_off; + l1 += grad_b_off; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + x_b = x_a <<= 16; + l1 = k1 <<= 16; + if (y_a < 0) { + x_b -= c_to_a * y_a; + x_a -= a_to_b * y_a; + z_a -= depth_increment * y_a; + l1 -= grad_c_off * y_a; + k1 -= grad_a_off * y_a; + y_a = 0; + } + x_c <<= 16; + i2 <<= 16; + if (y_c < 0) { + x_c -= b_to_c * y_c; + i2 -= grad_b_off * y_c; + y_c = 0; + } + int l8 = y_a - originViewY; + Oa += Va * l8; + Ob += Vb * l8; + Oc += Vc * l8; + if (y_a != y_c && c_to_a < a_to_b || y_a == y_c && b_to_c > a_to_b) { + y_b -= y_c; + y_c -= y_a; + y_a = scanOffsets[y_a]; + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_b >> 16, x_a >> 16, l1 >> 8, k1 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_a, depth_slope); + x_b += c_to_a; + x_a += a_to_b; + l1 += grad_c_off; + k1 += grad_a_off; + z_a += depth_increment; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_c >> 16, x_a >> 16, i2 >> 8, k1 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_a, depth_slope); + x_c += b_to_c; + x_a += a_to_b; + i2 += grad_b_off; + k1 += grad_a_off; + z_a += depth_increment; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + y_b -= y_c; + y_c -= y_a; + y_a = scanOffsets[y_a]; + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_a >> 16, x_b >> 16, k1 >> 8, l1 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_a, depth_slope); + x_b += c_to_a; + x_a += a_to_b; + l1 += grad_c_off; + k1 += grad_a_off; + z_a += depth_increment; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_a, x_a >> 16, x_c >> 16, k1 >> 8, i2 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_a, depth_slope); + x_c += b_to_c; + x_a += a_to_b; + i2 += grad_b_off; + k1 += grad_a_off; + z_a += depth_increment; + y_a += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + if (y_b <= y_c) { + if (y_b >= Rasterizer2D.bottomY) + return; + if (y_c > Rasterizer2D.bottomY) + y_c = Rasterizer2D.bottomY; + if (y_a > Rasterizer2D.bottomY) + y_a = Rasterizer2D.bottomY; + z_b = z_b - depth_slope * x_b + depth_slope; + if (y_c < y_a) { + x_a = x_b <<= 16; + k1 = l1 <<= 16; + if (y_b < 0) { + x_a -= a_to_b * y_b; + x_b -= b_to_c * y_b; + z_b -= depth_increment * y_b; + k1 -= grad_a_off * y_b; + l1 -= grad_b_off * y_b; + y_b = 0; + } + x_c <<= 16; + i2 <<= 16; + if (y_c < 0) { + x_c -= c_to_a * y_c; + i2 -= grad_c_off * y_c; + y_c = 0; + } + int i9 = y_b - originViewY; + Oa += Va * i9; + Ob += Vb * i9; + Oc += Vc * i9; + if (y_b != y_c && a_to_b < b_to_c || y_b == y_c && a_to_b > c_to_a) { + y_a -= y_c; + y_c -= y_b; + y_b = scanOffsets[y_b]; + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_a >> 16, x_b >> 16, k1 >> 8, l1 >> 8, Oa, + Ob, Oc, Ha, Hb, Hc, z_b, depth_slope); + x_a += a_to_b; + x_b += b_to_c; + k1 += grad_a_off; + l1 += grad_b_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_a >> 16, x_c >> 16, k1 >> 8, i2 >> 8, Oa, + Ob, Oc, Ha, Hb, Hc, z_b, depth_slope); + x_a += a_to_b; + x_c += c_to_a; + k1 += grad_a_off; + i2 += grad_c_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + y_a -= y_c; + y_c -= y_b; + y_b = scanOffsets[y_b]; + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_b >> 16, x_a >> 16, l1 >> 8, k1 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_b, depth_slope); + x_a += a_to_b; + x_b += b_to_c; + k1 += grad_a_off; + l1 += grad_b_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_c >> 16, x_a >> 16, i2 >> 8, k1 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_b, depth_slope); + x_a += a_to_b; + x_c += c_to_a; + k1 += grad_a_off; + i2 += grad_c_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + x_c = x_b <<= 16; + i2 = l1 <<= 16; + if (y_b < 0) { + x_c -= a_to_b * y_b; + x_b -= b_to_c * y_b; + z_b -= depth_increment * y_b; + i2 -= grad_a_off * y_b; + l1 -= grad_b_off * y_b; + y_b = 0; + } + x_a <<= 16; + k1 <<= 16; + if (y_a < 0) { + x_a -= c_to_a * y_a; + k1 -= grad_c_off * y_a; + y_a = 0; + } + int j9 = y_b - originViewY; + Oa += Va * j9; + Ob += Vb * j9; + Oc += Vc * j9; + if (a_to_b < b_to_c) { + y_c -= y_a; + y_a -= y_b; + y_b = scanOffsets[y_b]; + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_c >> 16, x_b >> 16, i2 >> 8, l1 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_b, depth_slope); + x_c += a_to_b; + x_b += b_to_c; + i2 += grad_a_off; + l1 += grad_b_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_a >> 16, x_b >> 16, k1 >> 8, l1 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_b, depth_slope); + x_a += c_to_a; + x_b += b_to_c; + k1 += grad_c_off; + l1 += grad_b_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + y_c -= y_a; + y_a -= y_b; + y_b = scanOffsets[y_b]; + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_b >> 16, x_c >> 16, l1 >> 8, i2 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_b, depth_slope); + x_c += a_to_b; + x_b += b_to_c; + i2 += grad_a_off; + l1 += grad_b_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_c >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_b, x_b >> 16, x_a >> 16, l1 >> 8, k1 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_b, depth_slope); + x_a += c_to_a; + x_b += b_to_c; + k1 += grad_c_off; + l1 += grad_b_off; + z_b += depth_increment; + y_b += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + if (y_c >= Rasterizer2D.bottomY) + return; + if (y_a > Rasterizer2D.bottomY) + y_a = Rasterizer2D.bottomY; + if (y_b > Rasterizer2D.bottomY) + y_b = Rasterizer2D.bottomY; + z_c = z_c - depth_slope * x_c + depth_slope; + if (y_a < y_b) { + x_b = x_c <<= 16; + l1 = i2 <<= 16; + if (y_c < 0) { + x_b -= b_to_c * y_c; + x_c -= c_to_a * y_c; + z_c -= depth_increment * y_c; + l1 -= grad_b_off * y_c; + i2 -= grad_c_off * y_c; + y_c = 0; + } + x_a <<= 16; + k1 <<= 16; + if (y_a < 0) { + x_a -= a_to_b * y_a; + k1 -= grad_a_off * y_a; + y_a = 0; + } + int k9 = y_c - originViewY; + Oa += Va * k9; + Ob += Vb * k9; + Oc += Vc * k9; + if (b_to_c < c_to_a) { + y_b -= y_a; + y_a -= y_c; + y_c = scanOffsets[y_c]; + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_b >> 16, x_c >> 16, l1 >> 8, i2 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_c, depth_slope); + x_b += b_to_c; + x_c += c_to_a; + l1 += grad_b_off; + i2 += grad_c_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_b >> 16, x_a >> 16, l1 >> 8, k1 >> 8, Oa, Ob, + Oc, Ha, Hb, Hc, z_c, depth_slope); + x_b += b_to_c; + x_a += a_to_b; + l1 += grad_b_off; + k1 += grad_a_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + y_b -= y_a; + y_a -= y_c; + y_c = scanOffsets[y_c]; + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_c >> 16, x_b >> 16, i2 >> 8, l1 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_c, depth_slope); + x_b += b_to_c; + x_c += c_to_a; + l1 += grad_b_off; + i2 += grad_c_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_a >> 16, x_b >> 16, k1 >> 8, l1 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_c, depth_slope); + x_b += b_to_c; + x_a += a_to_b; + l1 += grad_b_off; + k1 += grad_a_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + x_a = x_c <<= 16; + k1 = i2 <<= 16; + if (y_c < 0) { + x_a -= b_to_c * y_c; + x_c -= c_to_a * y_c; + z_c -= depth_increment * y_c; + k1 -= grad_b_off * y_c; + i2 -= grad_c_off * y_c; + y_c = 0; + } + x_b <<= 16; + l1 <<= 16; + if (y_b < 0) { + x_b -= a_to_b * y_b; + l1 -= grad_a_off * y_b; + y_b = 0; + } + int l9 = y_c - originViewY; + Oa += Va * l9; + Ob += Vb * l9; + Oc += Vc * l9; + if (b_to_c < c_to_a) { + y_a -= y_b; + y_b -= y_c; + y_c = scanOffsets[y_c]; + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_a >> 16, x_c >> 16, k1 >> 8, i2 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_c, depth_slope); + x_a += b_to_c; + x_c += c_to_a; + k1 += grad_b_off; + i2 += grad_c_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_b >> 16, x_c >> 16, l1 >> 8, i2 >> 8, Oa, Ob, Oc, + Ha, Hb, Hc, z_c, depth_slope); + x_b += a_to_b; + x_c += c_to_a; + l1 += grad_a_off; + i2 += grad_c_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + return; + } + y_a -= y_b; + y_b -= y_c; + y_c = scanOffsets[y_c]; + while (--y_b >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_c >> 16, x_a >> 16, i2 >> 8, k1 >> 8, Oa, Ob, Oc, Ha, + Hb, Hc, z_c, depth_slope); + x_a += b_to_c; + x_c += c_to_a; + k1 += grad_b_off; + i2 += grad_c_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + while (--y_a >= 0) { + drawTexturedScanline(Rasterizer2D.pixels, texture, y_c, x_c >> 16, x_b >> 16, i2 >> 8, l1 >> 8, Oa, Ob, Oc, Ha, + Hb, Hc, z_c, depth_slope); + x_b += a_to_b; + x_c += c_to_a; + l1 += grad_a_off; + i2 += grad_c_off; + z_c += depth_increment; + y_c += Rasterizer2D.width; + Oa += Va; + Ob += Vb; + Oc += Vc; + } + } + + public static void drawTexturedScanline(int dest[], int texture[], int dest_off, int start_x, int end_x, + int shadeValue, int gradient, int l1, int i2, int j2, int k2, int l2, int i3, float depth, + float depth_slope) { + int rgb = 0; + int loops = 0; + if (start_x >= end_x) + return; + int j3; + int k3; + if (textureOutOfDrawingBounds) { + j3 = (gradient - shadeValue) / (end_x - start_x); + if (end_x > Rasterizer2D.lastX) + end_x = Rasterizer2D.lastX; + if (start_x < 0) { + shadeValue -= start_x * j3; + start_x = 0; + } + if (start_x >= end_x) + return; + k3 = end_x - start_x >> 3; + j3 <<= 12; + shadeValue <<= 9; + } else { + if (end_x - start_x > 7) { + k3 = end_x - start_x >> 3; + j3 = (gradient - shadeValue) * anIntArray1468[k3] >> 6; + } else { + k3 = 0; + j3 = 0; + } + shadeValue <<= 9; + } + dest_off += start_x; + depth += depth_slope * (float) start_x; + if (lowMem) { + int i4 = 0; + int k4 = 0; + int k6 = start_x - originViewX; + l1 += (k2 >> 3) * k6; + i2 += (l2 >> 3) * k6; + j2 += (i3 >> 3) * k6; + int i5 = j2 >> 12; + if (i5 != 0) { + rgb = l1 / i5; + loops = i2 / i5; + if (rgb < 0) + rgb = 0; + else if (rgb > 4032) + rgb = 4032; + } + l1 += k2; + i2 += l2; + j2 += i3; + i5 = j2 >> 12; + if (i5 != 0) { + i4 = l1 / i5; + k4 = i2 / i5; + if (i4 < 7) + i4 = 7; + else if (i4 > 4032) + i4 = 4032; + } + int i7 = i4 - rgb >> 3; + int k7 = k4 - loops >> 3; + rgb += (shadeValue & 0x600000) >> 3; + int i8 = shadeValue >> 23; + if (aBoolean1463) { + while (k3-- > 0) { + for (int i = 0; i < 8; i++) { + if (true) { + dest[dest_off] = texture[(loops & 0xfc0) + (rgb >> 6)] >>> i8; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + rgb += i7; + loops += k7; + } + rgb = i4; + loops = k4; + l1 += k2; + i2 += l2; + j2 += i3; + int j5 = j2 >> 12; + if (j5 != 0) { + i4 = l1 / j5; + k4 = i2 / j5; + if (i4 < 7) + i4 = 7; + else if (i4 > 4032) + i4 = 4032; + } + i7 = i4 - rgb >> 3; + k7 = k4 - loops >> 3; + shadeValue += j3; + rgb += (shadeValue & 0x600000) >> 3; + i8 = shadeValue >> 23; + } + for (k3 = end_x - start_x & 7; k3-- > 0;) { + if (true) { + dest[dest_off] = texture[(loops & 0xfc0) + (rgb >> 6)] >>> i8; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + rgb += i7; + loops += k7; + } + + return; + } + while (k3-- > 0) { + int k8; + for (int i = 0; i < 8; i++) { + if ((k8 = texture[(loops & 0xfc0) + (rgb >> 6)] >>> i8) != 0) { + dest[dest_off] = k8; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + rgb += i7; + loops += k7; + } + + rgb = i4; + loops = k4; + l1 += k2; + i2 += l2; + j2 += i3; + int k5 = j2 >> 12; + if (k5 != 0) { + i4 = l1 / k5; + k4 = i2 / k5; + if (i4 < 7) + i4 = 7; + else if (i4 > 4032) + i4 = 4032; + } + i7 = i4 - rgb >> 3; + k7 = k4 - loops >> 3; + shadeValue += j3; + rgb += (shadeValue & 0x600000) >> 3; + i8 = shadeValue >> 23; + } + for (k3 = end_x - start_x & 7; k3-- > 0;) { + int l8; + if ((l8 = texture[(loops & 0xfc0) + (rgb >> 6)] >>> i8) != 0) { + dest[dest_off] = l8; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + rgb += i7; + loops += k7; + } + + return; + } + int j4 = 0; + int l4 = 0; + int l6 = start_x - originViewX; + l1 += (k2 >> 3) * l6; + i2 += (l2 >> 3) * l6; + j2 += (i3 >> 3) * l6; + int l5 = j2 >> 14; + if (l5 != 0) { + rgb = l1 / l5; + loops = i2 / l5; + if (rgb < 0) + rgb = 0; + else if (rgb > 16256) + rgb = 16256; + } + l1 += k2; + i2 += l2; + j2 += i3; + l5 = j2 >> 14; + if (l5 != 0) { + j4 = l1 / l5; + l4 = i2 / l5; + if (j4 < 7) + j4 = 7; + else if (j4 > 16256) + j4 = 16256; + } + int j7 = j4 - rgb >> 3; + int l7 = l4 - loops >> 3; + rgb += shadeValue & 0x600000; + int j8 = shadeValue >> 23; + if (aBoolean1463) { + while (k3-- > 0) { + for (int i = 0; i < 8; i++) { + if (true) { + dest[dest_off] = texture[(loops & 0x3f80) + (rgb >> 7)] >>> j8; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + rgb += j7; + loops += l7; + } + rgb = j4; + loops = l4; + l1 += k2; + i2 += l2; + j2 += i3; + int i6 = j2 >> 14; + if (i6 != 0) { + j4 = l1 / i6; + l4 = i2 / i6; + if (j4 < 7) + j4 = 7; + else if (j4 > 16256) + j4 = 16256; + } + j7 = j4 - rgb >> 3; + l7 = l4 - loops >> 3; + shadeValue += j3; + rgb += shadeValue & 0x600000; + j8 = shadeValue >> 23; + } + for (k3 = end_x - start_x & 7; k3-- > 0;) { + if (true) { + dest[dest_off] = texture[(loops & 0x3f80) + (rgb >> 7)] >>> j8; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + rgb += j7; + loops += l7; + } + + return; + } + while (k3-- > 0) { + int i9; + for (int i = 0; i < 8; i++) { + if ((i9 = texture[(loops & 0x3f80) + (rgb >> 7)] >>> j8) != 0) { + dest[dest_off] = i9; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + dest_off++; + depth += depth_slope; + rgb += j7; + loops += l7; + } + rgb = j4; + loops = l4; + l1 += k2; + i2 += l2; + j2 += i3; + int j6 = j2 >> 14; + if (j6 != 0) { + j4 = l1 / j6; + l4 = i2 / j6; + if (j4 < 7) + j4 = 7; + else if (j4 > 16256) + j4 = 16256; + } + j7 = j4 - rgb >> 3; + l7 = l4 - loops >> 3; + shadeValue += j3; + rgb += shadeValue & 0x600000; + j8 = shadeValue >> 23; + } + for (int l3 = end_x - start_x & 7; l3-- > 0;) { + int j9; + if ((j9 = texture[(loops & 0x3f80) + (rgb >> 7)] >>> j8) != 0) { + dest[dest_off] = j9; + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + rgb += j7; + loops += l7; + } + } + + public static void drawDepthTriangle(int x_a, int x_b, int x_c, int y_a, int y_b, int y_c, float z_a, float z_b, + float z_c) { + int a_to_b = 0; + if (y_b != y_a) { + a_to_b = (x_b - x_a << 16) / (y_b - y_a); + } + int b_to_c = 0; + if (y_c != y_b) { + b_to_c = (x_c - x_b << 16) / (y_c - y_b); + } + int c_to_a = 0; + if (y_c != y_a) { + c_to_a = (x_a - x_c << 16) / (y_a - y_c); + } + + float b_aX = x_b - x_a; + float b_aY = y_b - y_a; + float c_aX = x_c - x_a; + float c_aY = y_c - y_a; + float b_aZ = z_b - z_a; + float c_aZ = z_c - z_a; + + float div = b_aX * c_aY - c_aX * b_aY; + float depth_slope = (b_aZ * c_aY - c_aZ * b_aY) / div; + float depth_increment = (c_aZ * b_aX - b_aZ * c_aX) / div; + if (y_a <= y_b && y_a <= y_c) { + if (y_a < Rasterizer2D.bottomY) { + if (y_b > Rasterizer2D.bottomY) + y_b = Rasterizer2D.bottomY; + if (y_c > Rasterizer2D.bottomY) + y_c = Rasterizer2D.bottomY; + z_a = z_a - depth_slope * x_a + depth_slope; + if (y_b < y_c) { + x_c = x_a <<= 16; + if (y_a < 0) { + x_c -= c_to_a * y_a; + x_a -= a_to_b * y_a; + z_a -= depth_increment * y_a; + y_a = 0; + } + x_b <<= 16; + if (y_b < 0) { + x_b -= b_to_c * y_b; + y_b = 0; + } + if (y_a != y_b && c_to_a < a_to_b || y_a == y_b && c_to_a > b_to_c) { + y_c -= y_b; + y_b -= y_a; + y_a = scanOffsets[y_a]; + while (--y_b >= 0) { + drawDepthTriangleScanline(y_a, x_c >> 16, x_a >> 16, z_a, depth_slope); + x_c += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + while (--y_c >= 0) { + drawDepthTriangleScanline(y_a, x_c >> 16, x_b >> 16, z_a, depth_slope); + x_c += c_to_a; + x_b += b_to_c; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + } else { + y_c -= y_b; + y_b -= y_a; + y_a = scanOffsets[y_a]; + while (--y_b >= 0) { + drawDepthTriangleScanline(y_a, x_a >> 16, x_c >> 16, z_a, depth_slope); + x_c += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + while (--y_c >= 0) { + drawDepthTriangleScanline(y_a, x_b >> 16, x_c >> 16, z_a, depth_slope); + x_c += c_to_a; + x_b += b_to_c; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + } + } else { + x_b = x_a <<= 16; + if (y_a < 0) { + x_b -= c_to_a * y_a; + x_a -= a_to_b * y_a; + z_a -= depth_increment * y_a; + y_a = 0; + } + x_c <<= 16; + if (y_c < 0) { + x_c -= b_to_c * y_c; + y_c = 0; + } + if (y_a != y_c && c_to_a < a_to_b || y_a == y_c && b_to_c > a_to_b) { + y_b -= y_c; + y_c -= y_a; + y_a = scanOffsets[y_a]; + while (--y_c >= 0) { + drawDepthTriangleScanline(y_a, x_b >> 16, x_a >> 16, z_a, depth_slope); + x_b += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + while (--y_b >= 0) { + drawDepthTriangleScanline(y_a, x_c >> 16, x_a >> 16, z_a, depth_slope); + x_c += b_to_c; + x_a += a_to_b; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + } else { + y_b -= y_c; + y_c -= y_a; + y_a = scanOffsets[y_a]; + while (--y_c >= 0) { + drawDepthTriangleScanline(y_a, x_a >> 16, x_b >> 16, z_a, depth_slope); + x_b += c_to_a; + x_a += a_to_b; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + while (--y_b >= 0) { + drawDepthTriangleScanline(y_a, x_a >> 16, x_c >> 16, z_a, depth_slope); + x_c += b_to_c; + x_a += a_to_b; + z_a += depth_increment; + y_a += Rasterizer2D.width; + } + } + } + } + } else if (y_b <= y_c) { + if (y_b < Rasterizer2D.bottomY) { + if (y_c > Rasterizer2D.bottomY) + y_c = Rasterizer2D.bottomY; + if (y_a > Rasterizer2D.bottomY) + y_a = Rasterizer2D.bottomY; + z_b = z_b - depth_slope * x_b + depth_slope; + if (y_c < y_a) { + x_a = x_b <<= 16; + if (y_b < 0) { + x_a -= a_to_b * y_b; + x_b -= b_to_c * y_b; + z_b -= depth_increment * y_b; + y_b = 0; + } + x_c <<= 16; + if (y_c < 0) { + x_c -= c_to_a * y_c; + y_c = 0; + } + if (y_b != y_c && a_to_b < b_to_c || y_b == y_c && a_to_b > c_to_a) { + y_a -= y_c; + y_c -= y_b; + y_b = scanOffsets[y_b]; + while (--y_c >= 0) { + drawDepthTriangleScanline(y_b, x_a >> 16, x_b >> 16, z_b, depth_slope); + x_a += a_to_b; + x_b += b_to_c; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + while (--y_a >= 0) { + drawDepthTriangleScanline(y_b, x_a >> 16, x_c >> 16, z_b, depth_slope); + x_a += a_to_b; + x_c += c_to_a; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + } else { + y_a -= y_c; + y_c -= y_b; + y_b = scanOffsets[y_b]; + while (--y_c >= 0) { + drawDepthTriangleScanline(y_b, x_b >> 16, x_a >> 16, z_b, depth_slope); + x_a += a_to_b; + x_b += b_to_c; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + while (--y_a >= 0) { + drawDepthTriangleScanline(y_b, x_c >> 16, x_a >> 16, z_b, depth_slope); + x_a += a_to_b; + x_c += c_to_a; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + } + } else { + x_c = x_b <<= 16; + if (y_b < 0) { + x_c -= a_to_b * y_b; + x_b -= b_to_c * y_b; + z_b -= depth_increment * y_b; + y_b = 0; + } + x_a <<= 16; + if (y_a < 0) { + x_a -= c_to_a * y_a; + y_a = 0; + } + if (a_to_b < b_to_c) { + y_c -= y_a; + y_a -= y_b; + y_b = scanOffsets[y_b]; + while (--y_a >= 0) { + drawDepthTriangleScanline(y_b, x_c >> 16, x_b >> 16, z_b, depth_slope); + x_c += a_to_b; + x_b += b_to_c; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + while (--y_c >= 0) { + drawDepthTriangleScanline(y_b, x_a >> 16, x_b >> 16, z_b, depth_slope); + x_a += c_to_a; + x_b += b_to_c; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + } else { + y_c -= y_a; + y_a -= y_b; + y_b = scanOffsets[y_b]; + while (--y_a >= 0) { + drawDepthTriangleScanline(y_b, x_b >> 16, x_c >> 16, z_b, depth_slope); + x_c += a_to_b; + x_b += b_to_c; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + while (--y_c >= 0) { + drawDepthTriangleScanline(y_b, x_b >> 16, x_a >> 16, z_b, depth_slope); + x_a += c_to_a; + x_b += b_to_c; + z_b += depth_increment; + y_b += Rasterizer2D.width; + } + } + } + } + } else if (y_c < Rasterizer2D.bottomY) { + if (y_a > Rasterizer2D.bottomY) + y_a = Rasterizer2D.bottomY; + if (y_b > Rasterizer2D.bottomY) + y_b = Rasterizer2D.bottomY; + z_c = z_c - depth_slope * x_c + depth_slope; + if (y_a < y_b) { + x_b = x_c <<= 16; + if (y_c < 0) { + x_b -= b_to_c * y_c; + x_c -= c_to_a * y_c; + z_c -= depth_increment * y_c; + y_c = 0; + } + x_a <<= 16; + if (y_a < 0) { + x_a -= a_to_b * y_a; + y_a = 0; + } + if (b_to_c < c_to_a) { + y_b -= y_a; + y_a -= y_c; + y_c = scanOffsets[y_c]; + while (--y_a >= 0) { + drawDepthTriangleScanline(y_c, x_b >> 16, x_c >> 16, z_c, depth_slope); + x_b += b_to_c; + x_c += c_to_a; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + while (--y_b >= 0) { + drawDepthTriangleScanline(y_c, x_b >> 16, x_a >> 16, z_c, depth_slope); + x_b += b_to_c; + x_a += a_to_b; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + } else { + y_b -= y_a; + y_a -= y_c; + y_c = scanOffsets[y_c]; + while (--y_a >= 0) { + drawDepthTriangleScanline(y_c, x_c >> 16, x_b >> 16, z_c, depth_slope); + x_b += b_to_c; + x_c += c_to_a; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + while (--y_b >= 0) { + drawDepthTriangleScanline(y_c, x_a >> 16, x_b >> 16, z_c, depth_slope); + x_b += b_to_c; + x_a += a_to_b; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + } + } else { + x_a = x_c <<= 16; + if (y_c < 0) { + x_a -= b_to_c * y_c; + x_c -= c_to_a * y_c; + z_c -= depth_increment * y_c; + y_c = 0; + } + x_b <<= 16; + if (y_b < 0) { + x_b -= a_to_b * y_b; + y_b = 0; + } + if (b_to_c < c_to_a) { + y_a -= y_b; + y_b -= y_c; + y_c = scanOffsets[y_c]; + while (--y_b >= 0) { + drawDepthTriangleScanline(y_c, x_a >> 16, x_c >> 16, z_c, depth_slope); + x_a += b_to_c; + x_c += c_to_a; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + while (--y_a >= 0) { + drawDepthTriangleScanline(y_c, x_b >> 16, x_c >> 16, z_c, depth_slope); + x_b += a_to_b; + x_c += c_to_a; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + } else { + y_a -= y_b; + y_b -= y_c; + y_c = scanOffsets[y_c]; + while (--y_b >= 0) { + drawDepthTriangleScanline(y_c, x_c >> 16, x_a >> 16, z_c, depth_slope); + x_a += b_to_c; + x_c += c_to_a; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + while (--y_a >= 0) { + drawDepthTriangleScanline(y_c, x_c >> 16, x_b >> 16, z_c, depth_slope); + x_b += a_to_b; + x_c += c_to_a; + z_c += depth_increment; + y_c += Rasterizer2D.width; + } + } + } + } + } + + private static void drawDepthTriangleScanline(int dest_off, int start_x, int end_x, float depth, + float depth_slope) { + int dbl = Rasterizer2D.depthBuffer.length; + if (textureOutOfDrawingBounds) { + if (end_x > Rasterizer2D.width) { + end_x = Rasterizer2D.width; + } + if (start_x < 0) { + start_x = 0; + } + } + if (start_x >= end_x) { + return; + } + dest_off += start_x - 1; + int loops = end_x - start_x >> 2; + depth += depth_slope * (float) start_x; + if (alpha == 0) { + while (--loops >= 0) { + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + } + for (loops = end_x - start_x & 3; --loops >= 0;) { + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + } + return; + } + while (--loops >= 0) { + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + } + for (loops = end_x - start_x & 3; --loops >= 0;) { + dest_off++; + if (dest_off >= 0 && dest_off < dbl) { + Rasterizer2D.depthBuffer[dest_off] = depth; + } + depth += depth_slope; + } + } + + public static boolean lowMem = true; + public static boolean textureOutOfDrawingBounds; + private static boolean aBoolean1463; + public static boolean aBoolean1464 = true; + public static int alpha; + public static int originViewX; + public static int originViewY; + private static int[] anIntArray1468; + public static final int[] anIntArray1469; + public static int anIntArray1470[]; + public static int COSINE[]; + public static int scanOffsets[]; + private static int textureCount; + public static IndexedImage textures[] = new IndexedImage[51]; + private static boolean[] textureIsTransparant = new boolean[51]; + private static int[] averageTextureColours = new int[51]; + private static int textureRequestBufferPointer; + private static int[][] textureRequestPixelBuffer; + private static int[][] texturesPixelBuffer = new int[51][]; + public static int textureLastUsed[] = new int[51]; + public static int lastTextureRetrievalCount; + public static int hslToRgb[] = new int[0x10000]; + private static int[][] currentPalette = new int[51][]; + + static { + anIntArray1468 = new int[512]; + anIntArray1469 = new int[2048]; + anIntArray1470 = new int[2048]; + COSINE = new int[2048]; + for (int i = 1; i < 512; i++) { + anIntArray1468[i] = 32768 / i; + } + for (int j = 1; j < 2048; j++) { + anIntArray1469[j] = 0x10000 / j; + } + for (int k = 0; k < 2048; k++) { + anIntArray1470[k] = (int) (65536D * Math.sin((double) k * 0.0030679614999999999D)); + COSINE[k] = (int) (65536D * Math.cos((double) k * 0.0030679614999999999D)); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/entity/GameObject.java b/src/main/java/org/rebotted/entity/GameObject.java new file mode 100644 index 0000000..2ccaa5a --- /dev/null +++ b/src/main/java/org/rebotted/entity/GameObject.java @@ -0,0 +1,25 @@ +package org.rebotted.entity; + +/** + * ObjectGenre = 2 + */ +public final class GameObject { + + public int zLoc; + public int tileHeight; + public int xPos; + public int yPos; + public Renderable renderable; + public int turnValue; + public int xLocLow; + public int xLocHigh; + public int yLocHigh; + public int yLocLow; + public int anInt527; + public int anInt528; + public int uid; + /** + * mask = (byte)((objectRotation << 6) + objectType); + */ + public byte mask; +} diff --git a/src/main/java/org/rebotted/entity/GroundItemTile.java b/src/main/java/org/rebotted/entity/GroundItemTile.java new file mode 100644 index 0000000..5552198 --- /dev/null +++ b/src/main/java/org/rebotted/entity/GroundItemTile.java @@ -0,0 +1,13 @@ +package org.rebotted.entity; + +public final class GroundItemTile { + + public int zPos; + public int xPos; + public int yPos; + public Renderable topNode; + public Renderable lowerNode; + public Renderable middleNode; + public int uid; + public int itemDropHeight; +} diff --git a/src/main/java/org/rebotted/entity/Item.java b/src/main/java/org/rebotted/entity/Item.java new file mode 100644 index 0000000..838457a --- /dev/null +++ b/src/main/java/org/rebotted/entity/Item.java @@ -0,0 +1,17 @@ +package org.rebotted.entity; + +import org.rebotted.cache.def.ItemDefinition; +import org.rebotted.entity.model.Model; + +public final class Item extends Renderable { + + public final Model getRotatedModel() { + ItemDefinition itemDef = ItemDefinition.lookup(ID); + return itemDef.getModel(itemCount); + } + + public int ID; + public int x; + public int y; + public int itemCount; +} diff --git a/src/main/java/org/rebotted/entity/Mob.java b/src/main/java/org/rebotted/entity/Mob.java new file mode 100644 index 0000000..724dc58 --- /dev/null +++ b/src/main/java/org/rebotted/entity/Mob.java @@ -0,0 +1,473 @@ +package org.rebotted.entity; + +import org.rebotted.Client; +import org.rebotted.Configuration; +import org.rebotted.cache.anim.Animation; +import org.rebotted.cache.anim.Graphic; + +public class Mob extends Renderable { + + public final int[] pathX; + public final int[] pathY; + public int interactingEntity; + public int anInt1503; + public int degreesToTurn; + public int runAnimIndex; + public String spokenText; + public int height; + public int nextStepOrientation; + public int idleAnimation; + public int standTurnAnimIndex; + public int textColour; + public final int[] hitDamages; + public final int[] hitMarkTypes; + public final int[] hitsLoopCycle; + public int movementAnimation; + public int displayedMovementFrames; + public int anInt1519; + public int graphic; + public int currentAnimation; + public int anInt1522; + public int graphicDelay; + public int graphicHeight; + public int remainingPath; + public int emoteAnimation; + public int displayedEmoteFrames; + public int emoteTimeRemaining; + public int animationDelay; + public int currentAnimationLoops; + public int textEffect; + public int loopCycleStatus; + public int currentHealth; + public int maxHealth; + public int textCycle; + public int time; + public int faceX; + public int faceY; + public int size; + public boolean animationStretches; + public int anInt1542; + public int initialX; + public int destinationX; + public int initialY; + public int destinationY; + public int startForceMovement; + public int endForceMovement; + public int direction; + public int x; + public int y; + public int orientation; + public final boolean[] pathRun; + public int walkAnimIndex; + public int turn180AnimIndex; + public int turn90CWAnimIndex; + public int turn90CCWAnimIndex; + + public int nextAnimationFrame; + public int nextGraphicsAnimationFrame; + public int nextIdleAnimationFrame; + public int nextSpotAnimFrame; + + public Mob() { + pathX = new int[10]; + pathY = new int[10]; + interactingEntity = -1; + degreesToTurn = 32; + runAnimIndex = -1; + height = 200; + idleAnimation = -1; + standTurnAnimIndex = -1; + hitDamages = new int[4]; + hitMarkTypes = new int[4]; + hitsLoopCycle = new int[4]; + movementAnimation = -1; + graphic = -1; + emoteAnimation = -1; + loopCycleStatus = -1000; + textCycle = 100; + size = 1; + animationStretches = false; + pathRun = new boolean[10]; + walkAnimIndex = -1; + turn180AnimIndex = -1; + turn90CWAnimIndex = -1; + turn90CCWAnimIndex = -1; + } + + public final void setPos(int x, int y, boolean flag) { + if (emoteAnimation != -1 && Animation.animations[emoteAnimation].priority == 1) + emoteAnimation = -1; + + if (!flag) { + int dx = x - pathX[0]; + int dy = y - pathY[0]; + if (dx >= -8 && dx <= 8 && dy >= -8 && dy <= 8) { + if (remainingPath < 9) + remainingPath++; + for (int i1 = remainingPath; i1 > 0; i1--) { + pathX[i1] = pathX[i1 - 1]; + pathY[i1] = pathY[i1 - 1]; + pathRun[i1] = pathRun[i1 - 1]; + } + + pathX[0] = x; + pathY[0] = y; + pathRun[0] = false; + return; + } + } + remainingPath = 0; + anInt1542 = 0; + anInt1503 = 0; + pathX[0] = x; + pathY[0] = y; + this.x = pathX[0] * 128 + size * 64; + this.y = pathY[0] * 128 + size * 64; + } + + public final void resetPath() { + remainingPath = 0; + anInt1542 = 0; + } + + public final void updateHitData(int hitType, int hitDamage, int currentTime) { + for (int hitPtr = 0; hitPtr < 4; hitPtr++) + if (hitsLoopCycle[hitPtr] <= currentTime) { + hitDamages[hitPtr] = hitDamage; + hitMarkTypes[hitPtr] = hitType; + hitsLoopCycle[hitPtr] = currentTime + 70; + return; + } + } + + public void nextPreForcedStep() { + int remaining = startForceMovement - Client.tick; + int tempX = initialX * 128 + size * 64; + int tempY = initialY * 128 + size * 64; + x += (tempX - x) / remaining; + y += (tempY - y) / remaining; + + anInt1503 = 0; + + if (direction == 0) { + nextStepOrientation = 1024; + } + + if (direction == 1) { + nextStepOrientation = 1536; + } + + if (direction == 2) { + nextStepOrientation = 0; + } + + if (direction == 3) { + nextStepOrientation = 512; + } + } + + public void nextForcedMovementStep() { + if (endForceMovement == Client.tick || emoteAnimation == -1 + || animationDelay != 0 + || emoteTimeRemaining + + 1 > Animation.animations[emoteAnimation] + .duration(displayedEmoteFrames)) { + int remaining = endForceMovement - startForceMovement; + int elapsed = Client.tick - startForceMovement; + int initialX = this.initialX * 128 + size * 64; + int initialY = this.initialY * 128 + size * 64; + int endX = destinationX * 128 + size * 64; + int endY = destinationY * 128 + size * 64; + x = (initialX * (remaining - elapsed) + endX * elapsed) / remaining; + y = (initialY * (remaining - elapsed) + endY * elapsed) / remaining; + } + anInt1503 = 0; + + if (direction == 0) { + nextStepOrientation = 1024; + } + + if (direction == 1) { + nextStepOrientation = 1536; + } + + if (direction == 2) { + nextStepOrientation = 0; + } + + if (direction == 3) { + nextStepOrientation = 512; + } + + orientation = nextStepOrientation; + } + + public void nextStep() { + movementAnimation = idleAnimation; + + if (remainingPath == 0) { + anInt1503 = 0; + return; + } + + if(emoteAnimation > Animation.animations.length) { + emoteAnimation = -1; + return; + } + + if (emoteAnimation != -1 && animationDelay == 0) { + Animation animation = Animation.animations[emoteAnimation]; + if (anInt1542 > 0 && animation.animatingPrecedence == 0) { + anInt1503++; + return; + } + if (anInt1542 <= 0 && animation.priority == 0) { + anInt1503++; + return; + } + } + int tempX = x; + int tempY = y; + int nextX = pathX[remainingPath - 1] * 128 + size * 64; + int nextY = pathY[remainingPath - 1] * 128 + size * 64; + if (nextX - tempX > 256 || nextX - tempX < -256 || nextY - tempY > 256 || nextY - tempY < -256) { + x = nextX; + y = nextY; + return; + } + if (tempX < nextX) { + if (tempY < nextY) { + nextStepOrientation = 1280; + } else if (tempY > nextY) { + nextStepOrientation = 1792; + } else { + nextStepOrientation = 1536; + } + } else if (tempX > nextX) { + if (tempY < nextY) { + nextStepOrientation = 768; + } else if (tempY > nextY) { + nextStepOrientation = 256; + } else { + nextStepOrientation = 512; + } + } else if (tempY < nextY) { + nextStepOrientation = 1024; + } else { + nextStepOrientation = 0; + } + + int rotation = nextStepOrientation - orientation & 0x7ff; + + if (rotation > 1024) { + rotation -= 2048; + } + + int animation = turn180AnimIndex; + + if (rotation >= -256 && rotation <= 256) { + animation = walkAnimIndex; + } else if (rotation >= 256 && rotation < 768) { + animation = turn90CCWAnimIndex; + } else if (rotation >= -768 && rotation <= -256) { + animation = turn90CWAnimIndex; + } + + if (animation == -1) { + animation = walkAnimIndex; + } + + movementAnimation = animation; + + int positionDelta = 4; + + if (orientation != nextStepOrientation && interactingEntity == -1 + && degreesToTurn != 0) { + positionDelta = 2; + } + + if (remainingPath > 2) { + positionDelta = 6; + } + + if (remainingPath > 3) { + positionDelta = 8; + } + + if (anInt1503 > 0 && remainingPath > 1) { + positionDelta = 8; + anInt1503--; + } + + if (pathRun[remainingPath - 1]) { + positionDelta <<= 1; + } + + if (positionDelta >= 8 && movementAnimation == walkAnimIndex + && runAnimIndex != -1) { + movementAnimation = runAnimIndex; + } + + if (tempX < nextX) { + x += positionDelta; + if (x > nextX) { + x = nextX; + } + } else if (tempX > nextX) { + x -= positionDelta; + if (x < nextX) { + x = nextX; + } + } + if (tempY < nextY) { + y += positionDelta; + if (y > nextY) { + y = nextY; + } + } else if (tempY > nextY) { + y -= positionDelta; + + if (y < nextY) { + y = nextY; + } + } + if (x == nextX && y == nextY) { + remainingPath--; + + if (anInt1542 > 0) { + anInt1542--; + } + } + } + + public final void moveInDir(boolean run, int direction) { + int x = pathX[0]; + int y = pathY[0]; + if (direction == 0) { + x--; + y++; + } + if (direction == 1) + y++; + if (direction == 2) { + x++; + y++; + } + if (direction == 3) + x--; + if (direction == 4) + x++; + if (direction == 5) { + x--; + y--; + } + if (direction == 6) + y--; + if (direction == 7) { + x++; + y--; + } + if (emoteAnimation != -1 && Animation.animations[emoteAnimation].priority == 1) + emoteAnimation = -1; + if (remainingPath < 9) + remainingPath++; + for (int l = remainingPath; l > 0; l--) { + pathX[l] = pathX[l - 1]; + pathY[l] = pathY[l - 1]; + pathRun[l] = pathRun[l - 1]; + } + pathX[0] = x; + pathY[0] = y; + pathRun[0] = run; + } + + public void updateAnimation() { + + try { + if (movementAnimation > 13798) { + movementAnimation = -1; + } + animationStretches = false; + if (movementAnimation != -1) { + Animation animation = Animation.animations[movementAnimation]; + anInt1519++; + if (displayedMovementFrames < animation.frameCount && anInt1519 > animation.duration(displayedMovementFrames)) { + anInt1519 = 1; + displayedMovementFrames++; + nextIdleAnimationFrame++; + } + nextIdleAnimationFrame = displayedMovementFrames + 1; + if (nextIdleAnimationFrame >= animation.frameCount) { + if (nextIdleAnimationFrame >= animation.frameCount) { + nextIdleAnimationFrame = 0; + } + } + if (displayedMovementFrames >= animation.frameCount) { + anInt1519 = 1; + displayedMovementFrames = 0; + } + } + if (graphic != -1 && Client.tick >= graphicDelay) { + if (currentAnimation < 0) + currentAnimation = 0; + Animation animation_1 = Graphic.cache[graphic].animationSequence; + + for (anInt1522++; currentAnimation < animation_1.frameCount && anInt1522 > animation_1.duration(currentAnimation); currentAnimation++) + anInt1522 -= animation_1.duration(currentAnimation); + + + if (currentAnimation >= animation_1.frameCount && (currentAnimation < 0 || currentAnimation >= animation_1.frameCount)) { + graphic = -1; + } + if (Configuration.enableTweening) { + nextIdleAnimationFrame = displayedMovementFrames + 1; + } + if (nextSpotAnimFrame >= animation_1.frameCount) { + nextSpotAnimFrame = -1; + } + } + if (emoteAnimation != -1 && animationDelay <= 1) { + Animation animation_2 = Animation.animations[emoteAnimation]; + if (animation_2.animatingPrecedence == 1 && anInt1542 > 0 && startForceMovement <= Client.tick && endForceMovement < Client.tick) { + animationDelay = 1; + return; + } + } + if (emoteAnimation != -1 && animationDelay == 0) { + Animation animation_3 = Animation.animations[emoteAnimation]; + for (emoteTimeRemaining++; displayedEmoteFrames < animation_3.frameCount && emoteTimeRemaining > animation_3.duration(displayedEmoteFrames); displayedEmoteFrames++) + emoteTimeRemaining -= animation_3.duration(displayedEmoteFrames); + + if (displayedEmoteFrames >= animation_3.frameCount) { + displayedEmoteFrames -= animation_3.loopOffset; + currentAnimationLoops++; + if (currentAnimationLoops >= animation_3.maximumLoops) + emoteAnimation = -1; + if (displayedEmoteFrames < 0 || displayedEmoteFrames >= animation_3.frameCount) + emoteAnimation = -1; + } + if (Configuration.enableTweening) { + nextAnimationFrame = displayedEmoteFrames + 1; + } + if (nextAnimationFrame >= animation_3.frameCount) { + nextAnimationFrame = -1; + } + animationStretches = animation_3.stretches; + } + if (animationDelay > 0) + animationDelay--; + + + } catch(Exception e) { + e.printStackTrace(); + } + } + + public int entScreenX; + public int entScreenY; + public int index = -1; + + public boolean isVisible() { + return false; + } +} diff --git a/src/main/java/org/rebotted/entity/Npc.java b/src/main/java/org/rebotted/entity/Npc.java new file mode 100644 index 0000000..fb49c7c --- /dev/null +++ b/src/main/java/org/rebotted/entity/Npc.java @@ -0,0 +1,84 @@ +package org.rebotted.entity; + +import org.rebotted.Client; +import org.rebotted.cache.anim.Animation; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.anim.Graphic; +import org.rebotted.cache.def.NpcDefinition; +import org.rebotted.entity.model.Model; + +public final class Npc extends Mob { + + public NpcDefinition desc; + public int headIcon = -1; + public int ownerIndex = -1; + + public boolean showActions() { + if(ownerIndex == -1) { + return true; + } + return (Client.instance.localPlayerIndex == ownerIndex); + } + + public int getHeadIcon() { + if(headIcon == -1) { + if(desc != null) { + return desc.headIcon; + } + } + return headIcon; + } + + private Model getAnimatedModel() { + if (super.emoteAnimation >= 0 && super.animationDelay == 0) { + int emote = Animation.animations[super.emoteAnimation].primaryFrames[super.displayedEmoteFrames]; + int movement = -1; + if (super.movementAnimation >= 0 && super.movementAnimation != super.idleAnimation) + movement = Animation.animations[super.movementAnimation].primaryFrames[super.displayedMovementFrames]; + return desc.getAnimatedModel(movement, emote, + Animation.animations[super.emoteAnimation].interleaveOrder); + } + int movement = -1; + if (super.movementAnimation >= 0) { + movement = Animation.animations[super.movementAnimation].primaryFrames[super.displayedMovementFrames]; + } + return desc.getAnimatedModel(-1, movement, null); + } + + public Model getRotatedModel() { + if (desc == null) + return null; + Model animatedModel = getAnimatedModel(); + if (animatedModel == null) + return null; + super.height = animatedModel.modelBaseY; + if (super.graphic != -1 && super.currentAnimation != -1) { + Graphic spotAnim = Graphic.cache[super.graphic]; + Model graphicModel = spotAnim.getModel(); + if (graphicModel != null) { + int frame = spotAnim.animationSequence.primaryFrames[super.currentAnimation]; + Model model = new Model(true, Frame.noAnimationInProgress(frame), + false, graphicModel); + model.translate(0, -super.graphicHeight, 0); + model.skin(); + model.applyTransform(frame); + model.faceGroups = null; + model.vertexGroups = null; + if (spotAnim.resizeXY != 128 || spotAnim.resizeZ != 128) + model.scale(spotAnim.resizeXY, spotAnim.resizeXY, + spotAnim.resizeZ); + model.light(64 + spotAnim.modelBrightness, + 850 + spotAnim.modelShadow, -30, -50, -30, true); + Model models[] = { animatedModel, model }; + animatedModel = new Model(models); + } + } + if (desc.size == 1) + animatedModel.fits_on_single_square = true; + return animatedModel; + } + + public boolean isVisible() { + return desc != null; + } +} diff --git a/src/main/java/org/rebotted/entity/Player.java b/src/main/java/org/rebotted/entity/Player.java new file mode 100644 index 0000000..90af152 --- /dev/null +++ b/src/main/java/org/rebotted/entity/Player.java @@ -0,0 +1,459 @@ +package org.rebotted.entity; + +import org.rebotted.Client; +import org.rebotted.Configuration; +import org.rebotted.cache.anim.Animation; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.anim.Graphic; +import org.rebotted.cache.def.ItemDefinition; +import org.rebotted.cache.def.NpcDefinition; +import org.rebotted.cache.idk.IdentityKit; +import org.rebotted.collection.ReferenceCache; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; +import org.rebotted.util.StringUtils; + +public final class Player extends Mob { + + private long cachedModel = -1L; + public NpcDefinition npcDefinition; + public boolean aBoolean1699; + public final int[] appearanceColors = new int[5]; + public int team; + private int gender; + public String name; + public static ReferenceCache models = new ReferenceCache(260); + public int combatLevel; + public int headIcon; + public int skullIcon; + public int hintIcon; + public int objectModelStart; + public int objectModelStop; + public int anInt1709; + public boolean visible; + public int objectXPos; + public int objectCenterHeight; + public int objectYPos; + public Model playerModel; + public final int[] equipment = new int[12]; + private long appearanceOffset ; + public int objectAnInt1719LesserXLoc; + public int objectAnInt1720LesserYLoc; + public int objectAnInt1721GreaterXLoc; + public int objectAnInt1722GreaterYLoc; + public int skill; + public String clanName = "None"; + public int privelage; + + public Model getRotatedModel() { + + if (!visible) { + return null; + } + + Model animatedModel = getAnimatedModel(); + + if (animatedModel == null) { + return null; + } + + super.height = animatedModel.modelBaseY; + animatedModel.fits_on_single_square = true; + + if (aBoolean1699) { + return animatedModel; + } + + if (super.graphic != -1 && super.currentAnimation != -1) { + Graphic spotAnim = Graphic.cache[super.graphic]; + + Model spotAnimationModel = spotAnim.getModel(); + + if (spotAnimationModel != null) { + Model model_3 = new Model(true, Frame.noAnimationInProgress(super.currentAnimation), false, spotAnimationModel ); + int nextFrame = spotAnim.animationSequence.primaryFrames[super.nextGraphicsAnimationFrame]; + int cycle1 = spotAnim.animationSequence.durations[super.currentAnimation]; + int cycle2 = super.anInt1522; + model_3.translate(0, -super.graphicHeight, 0); + model_3.skin(); + model_3.applyAnimationFrame(spotAnim.animationSequence.primaryFrames[super.currentAnimation], nextFrame, + cycle1, cycle2); + model_3.faceGroups = null; + model_3.vertexGroups = null; + if (spotAnim.resizeXY != 128 || spotAnim.resizeZ != 128) + model_3.scale(spotAnim.resizeXY, spotAnim.resizeXY, spotAnim.resizeZ); + model_3.light(64 + spotAnim.modelBrightness, 850 + spotAnim.modelShadow, -30, -50, -30, true); + Model models [] = { animatedModel, model_3 }; + animatedModel = new Model(models ); + } else { + return null; + } + } + if (playerModel != null) { + if (Client.tick >= objectModelStop) + playerModel = null; + if (Client.tick >= objectModelStart && Client.tick < objectModelStop) { + Model model_1 = playerModel; + model_1.translate(objectXPos - super.x, objectCenterHeight - anInt1709, objectYPos - super.y); + if (super.nextStepOrientation == 512) { + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + } else if (super.nextStepOrientation == 1024) { + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + } else if (super.nextStepOrientation == 1536) + model_1.rotate90Degrees(); + Model models[] = { animatedModel, model_1 }; + animatedModel = new Model(models); + if (super.nextStepOrientation == 512) + model_1.rotate90Degrees(); + else if (super.nextStepOrientation == 1024) { + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + } else if (super.nextStepOrientation == 1536) { + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + } + model_1.translate(super.x - objectXPos, anInt1709 - objectCenterHeight, super.y - objectYPos); + } + } + animatedModel.fits_on_single_square = true; + return animatedModel; + } + + public void updateAppearance(Buffer buffer) { + buffer.currentPosition = 0; + gender = buffer.readUnsignedByte(); + headIcon = buffer.readUnsignedByte(); + skullIcon = buffer.readUnsignedByte(); + npcDefinition = null; + team = 0; + + for (int bodyPart = 0; bodyPart < 12; bodyPart++) { + + int reset = buffer.readUnsignedByte(); + + if (reset == 0) { + equipment[bodyPart] = 0; + continue; + } + + int id = buffer.readUnsignedByte(); + + equipment[bodyPart] = (reset << 8) + id; + + if (bodyPart == 0 && equipment[0] == 65535) { + npcDefinition = NpcDefinition.lookup(buffer.readUShort()); + break; + } + + if (equipment[bodyPart] >= 512 && equipment[bodyPart] - 512 < ItemDefinition.itemCount) { + int team = ItemDefinition.lookup(equipment[bodyPart] - 512).team; + + if (team != 0) { + this.team = team; + } + + } + + } + + for (int part = 0; part < 5; part++) { + int color = buffer.readUnsignedByte(); + if (color < 0 || color >= Client.PLAYER_BODY_RECOLOURS[part].length) { + color = 0; + } + appearanceColors[part] = color; + } + + super.idleAnimation = buffer.readUShort(); + if (super.idleAnimation == 65535) { + super.idleAnimation = -1; + } + + super.standTurnAnimIndex = buffer.readUShort(); + if (super.standTurnAnimIndex == 65535) { + super.standTurnAnimIndex = -1; + } + + super.walkAnimIndex = buffer.readUShort(); + if (super.walkAnimIndex == 65535) { + super.walkAnimIndex = -1; + } + + super.turn180AnimIndex = buffer.readUShort(); + if (super.turn180AnimIndex == 65535) { + super.turn180AnimIndex = -1; + } + + super.turn90CWAnimIndex = buffer.readUShort(); + if (super.turn90CWAnimIndex == 65535) { + super.turn90CWAnimIndex = -1; + } + + super.turn90CCWAnimIndex = buffer.readUShort(); + if (super.turn90CCWAnimIndex == 65535) { + super.turn90CCWAnimIndex = -1; + } + + super.runAnimIndex = buffer.readUShort(); + if (super.runAnimIndex == 65535) { + super.runAnimIndex = -1; + } + + name = StringUtils.formatUsername(StringUtils.decodeBase37(buffer.readLong())); + combatLevel = buffer.readUnsignedByte(); + skill = buffer.readUShort(); + visible = true; + appearanceOffset = 0L; + + for (int index = 0; index < 12; index++) { + appearanceOffset <<= 4; + + if (equipment[index] >= 256) { + appearanceOffset += equipment[index] - 256; + } + + } + + if (equipment[0] >= 256) { + appearanceOffset += equipment[0] - 256 >> 4; + } + + if (equipment[1] >= 256) { + appearanceOffset += equipment[1] - 256 >> 8; + } + + for (int index = 0; index < 5; index++) { + appearanceOffset <<= 3; + appearanceOffset += appearanceColors[index]; + } + + appearanceOffset <<= 1; + appearanceOffset += gender; + } + + public Model getAnimatedModel() { + if (npcDefinition != null) { + int currentFrame = -1; + int nextFrame = -1; + int cycle1 = 0; + int cycle2 = 0; + + if (super.emoteAnimation >= 0 && super.animationDelay == 0) { + Animation animation = Animation.animations[super.emoteAnimation]; + currentFrame = animation.primaryFrames[super.displayedEmoteFrames]; + if (Configuration.enableTweening && super.nextAnimationFrame != -1) { + nextFrame = animation.primaryFrames[super.nextAnimationFrame]; + cycle1 = animation.durations[super.displayedEmoteFrames]; + cycle2 = super.emoteTimeRemaining; + } + } else if (super.movementAnimation >= 0) { + Animation animation = Animation.animations[super.movementAnimation]; + currentFrame = animation.primaryFrames[super.displayedMovementFrames]; + if (Configuration.enableTweening && super.nextIdleAnimationFrame != -1) { + nextFrame = animation.primaryFrames[super.nextIdleAnimationFrame]; + cycle1 = animation.durations[super.displayedMovementFrames]; + cycle2 = super.anInt1519; + } + } + Model model = npcDefinition.method164(-1, currentFrame, null, nextFrame, cycle1, cycle2); + return model; + } + + + long l = appearanceOffset ; + int currentFrame = -1; + int nextFrame = -1; + int cycle1 = 0; + int cycle2 = 0; + int i1 = -1; + int j1 = -1; + int k1 = -1; + if (super.emoteAnimation >= 0 && super.animationDelay == 0) { + Animation animation = Animation.animations[super.emoteAnimation]; + currentFrame = animation.primaryFrames[super.displayedEmoteFrames]; + if (Configuration.enableTweening && super.nextAnimationFrame != -1) { + nextFrame = animation.primaryFrames[super.nextAnimationFrame]; + cycle1 = animation.durations[super.displayedEmoteFrames]; + cycle2 = super.emoteTimeRemaining; + } + if (super.movementAnimation >= 0 && super.movementAnimation != super.idleAnimation) + i1 = Animation.animations[super.movementAnimation].primaryFrames[super.displayedMovementFrames]; + if (animation.rightHand >= 0) { + j1 = animation.rightHand; + l += j1 - equipment[5] << 40; + } + if (animation.leftHand >= 0) { + k1 = animation.leftHand; + l += k1 - equipment[3] << 48; + } + } else if (super.movementAnimation >= 0) { + Animation animation = Animation.animations[super.movementAnimation]; + currentFrame = animation.primaryFrames[super.displayedMovementFrames]; + + /** DISABLED BECAUSE IT CAUSES FLICKERING WITH SOME GFXS **/ + /*if (Configuration.enableTweening && super.nextIdleAnimationFrame != -1) { + nextFrame = animation.primaryFrames[super.nextIdleAnimationFrame]; + cycle1 = animation.durations[super.displayedMovementFrames]; + cycle2 = super.anInt1519; + }*/ + } + Model model_1 = (Model) models.get(l); + if (model_1 == null) { + boolean flag = false; + for (int i2 = 0; i2 < 12; i2++) { + int k2 = equipment[i2]; + if (k1 >= 0 && i2 == 3) + k2 = k1; + if (j1 >= 0 && i2 == 5) + k2 = j1; + if (k2 >= 256 && k2 < 512 && !IdentityKit.kits[k2 - 256].bodyLoaded()) + flag = true; + if (k2 >= 512 && !ItemDefinition.lookup(k2 - 512).isEquippedModelCached(gender)) + flag = true; + } + + if (flag) { + if (cachedModel != -1L) + model_1 = (Model) models.get(cachedModel ); + if (model_1 == null) + return null; + } + } + if (model_1 == null) { + Model aclass30_sub2_sub4_sub6s[] = new Model[14]; + int j2 = 0; + for (int l2 = 0; l2 < 12; l2++) { + int i3 = equipment[l2]; + if (k1 >= 0 && l2 == 3) + i3 = k1; + if (j1 >= 0 && l2 == 5) + i3 = j1; + if (i3 >= 256 && i3 < 512) { + Model model_3 = IdentityKit.kits[i3 - 256].bodyModel(); + if (model_3 != null) + aclass30_sub2_sub4_sub6s[j2++] = model_3; + } + if (i3 >= 512) { + Model model_4 = ItemDefinition.lookup(i3 - 512).getEquippedModel(gender); + if (model_4 != null) + aclass30_sub2_sub4_sub6s[j2++] = model_4; + } + } + model_1 = new Model(j2, aclass30_sub2_sub4_sub6s); + for (int j3 = 0; j3 < 5; j3++) + if (appearanceColors[j3] != 0) { + model_1.recolor(Client.PLAYER_BODY_RECOLOURS[j3][0], + Client.PLAYER_BODY_RECOLOURS[j3][appearanceColors[j3]]); + if (j3 == 1) + model_1.recolor(Client.anIntArray1204[0], Client.anIntArray1204[appearanceColors[j3]]); + } + + model_1.skin(); + model_1.scale(132, 132, 132); + model_1.light(64, 850, -30, -50, -30, true); + models.put(model_1, l); + cachedModel = l; + } + + if (aBoolean1699) { + return model_1; + } + + Model emptyModel = Model.EMPTY_MODEL; + + emptyModel.method464(model_1, Frame.noAnimationInProgress(currentFrame) & Frame.noAnimationInProgress(i1)); + if (currentFrame != -1 && i1 != -1) { + emptyModel.applyAnimationFrames(Animation.animations[super.emoteAnimation].interleaveOrder, i1, currentFrame); + } else if(currentFrame != -1) { + //emptyModel.apply(currentFrame); + emptyModel.applyAnimationFrame(currentFrame, nextFrame, cycle1, cycle2); + } + + /*else if (currentFrame != -1 && nextFrame != -1) { + emptyModel.applyAnimationFrame(currentFrame, nextFrame, cycle1, cycle2); + } else { + emptyModel.apply(currentFrame); + }*/ + emptyModel.calculateDistances(); + emptyModel.faceGroups = null; + emptyModel.vertexGroups = null; + return emptyModel; + } + + public Model getHeadModel() { + if (!visible) { + return null; + } + + if (npcDefinition != null) { + return npcDefinition.model(); + } + + boolean cached = false; + + for (int index = 0; index < 12; index++) { + int appearanceId = equipment[index]; + + if (appearanceId >= 256 && appearanceId < 512 && !IdentityKit.kits[appearanceId - 256].headLoaded()) { + cached = true; + } + + if (appearanceId >= 512 && !ItemDefinition.lookup(appearanceId - 512).isDialogueModelCached(gender)) { + cached = true; + } + } + + if (cached) { + return null; + } + + Model headModels[] = new Model[12]; + + int headModelsOffset = 0; + + for (int modelIndex = 0; modelIndex < 12; modelIndex ++) { + int appearanceId = equipment[modelIndex ]; + + if (appearanceId >= 256 && appearanceId < 512) { + + Model subModel = IdentityKit.kits[appearanceId - 256].headModel(); + + if (subModel != null) { + headModels[headModelsOffset ++] = subModel; + } + + } + if (appearanceId >= 512) { + Model subModel = ItemDefinition.lookup(appearanceId - 512).getChatEquipModel(gender); + + if (subModel != null) { + headModels[headModelsOffset ++] = subModel; + } + + } + } + + Model headModel = new Model(headModelsOffset , headModels); + + for (int index = 0; index < 5; index ++) { + if (appearanceColors[index ] != 0) { + headModel.recolor(Client.PLAYER_BODY_RECOLOURS[index ][0], + Client.PLAYER_BODY_RECOLOURS[index ][appearanceColors[index ]]); + if (index == 1) { + headModel.recolor(Client.anIntArray1204[0], Client.anIntArray1204[appearanceColors[index ]]); + } + } + } + + return headModel; + } + + public boolean isVisible() { + return visible; + } + +} diff --git a/src/main/java/org/rebotted/entity/Renderable.java b/src/main/java/org/rebotted/entity/Renderable.java new file mode 100644 index 0000000..32654f0 --- /dev/null +++ b/src/main/java/org/rebotted/entity/Renderable.java @@ -0,0 +1,26 @@ +package org.rebotted.entity; +import org.rebotted.collection.Cacheable; +import org.rebotted.entity.model.Model; +import org.rebotted.entity.model.VertexNormal; + +public class Renderable extends Cacheable { + + public int modelBaseY; + public VertexNormal vertexNormals[]; + + public void renderAtPoint(int i, int j, int k, int l, int i1, int j1, int k1, int l1, int i2) { + Model model = getRotatedModel(); + if(model != null) { + modelBaseY = model.modelBaseY; + model.renderAtPoint(i, j, k, l, i1, j1, k1, l1, i2); + } + } + + public Model getRotatedModel() { + return null; + } + + public Renderable() { + modelBaseY = 1000; + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/entity/model/Model.java b/src/main/java/org/rebotted/entity/model/Model.java new file mode 100644 index 0000000..b8031bc --- /dev/null +++ b/src/main/java/org/rebotted/entity/model/Model.java @@ -0,0 +1,3047 @@ +package org.rebotted.entity.model; +import org.rebotted.Configuration; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.anim.FrameBase; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.draw.Rasterizer3D; +import org.rebotted.entity.Renderable; +import org.rebotted.io.Buffer; +import org.rebotted.net.requester.Provider; +import org.rebotted.scene.SceneGraph; + +public class Model extends Renderable { + + public static void clear() { + aClass21Array1661 = null; + hasAnEdgeToRestrict = null; + outOfReach = null; + projected_vertex_y = null; + projected_vertex_z = null; + anIntArray1668 = null; + camera_vertex_y = null; + camera_vertex_x = null; + depthListIndices = null; + faceLists = null; + anIntArray1673 = null; + anIntArrayArray1674 = null; + anIntArray1675 = null; + anIntArray1676 = null; + anIntArray1677 = null; + SINE = null; + COSINE = null; + modelIntArray3 = null; + modelIntArray4 = null; + } + + + public Model(int modelId) { + byte[] is = aClass21Array1661[modelId].aByteArray368; + if (is[is.length - 1] == -1 && is[is.length - 2] == -1) + read622Model(is, modelId); + else + readOldModel(modelId); + if (newmodel[modelId]) { + if (face_render_priorities != null) { + if (modelId >= 1 && modelId <= 65535) { + for (int index = 0; index < face_render_priorities.length; index++) { + face_render_priorities[index] = 10; + } + } + } + } + } + + public void setTexture(int tex) { + numberOfTexturesFaces = numTriangles; + int set2 = 0; + if (faceDrawType == null) + faceDrawType = new int[numTriangles]; + if (triangleColours == null) + triangleColours = new int[numTriangles]; + vertexX = new int[numTriangles]; + vertexY = new int[numTriangles]; + vertexZ = new int[numTriangles]; + + for (int i = 0; i < numTriangles; i++) { + triangleColours[i] = tex; + faceDrawType[i] = 3 + set2; + set2 += 4; + vertexX[i] = facePointA[i]; + vertexY[i] = facePointB[i]; + vertexZ[i] = facePointC[i]; + } + } + + + public void readOldModel(int modelId) { + int j = -870; + aBoolean1618 = true; + fits_on_single_square = false; + anInt1620++; + ModelHeader modelHeader = aClass21Array1661[modelId]; + numVertices = modelHeader.anInt369; + numTriangles = modelHeader.anInt370; + numberOfTexturesFaces = modelHeader.anInt371; + vertexX = new int[numVertices]; + vertexY = new int[numVertices]; + vertexZ = new int[numVertices]; + facePointA = new int[numTriangles]; + facePointB = new int[numTriangles]; + while (j >= 0) + aBoolean1618 = !aBoolean1618; + facePointC = new int[numTriangles]; + textures_face_a = new int[numberOfTexturesFaces]; + textures_face_b = new int[numberOfTexturesFaces]; + textures_face_c = new int[numberOfTexturesFaces]; + if (modelHeader.anInt376 >= 0) + vertexVSkin = new int[numVertices]; + if (modelHeader.anInt380 >= 0) + faceDrawType = new int[numTriangles]; + if (modelHeader.anInt381 >= 0) + face_render_priorities = new int[numTriangles]; + else + face_priority = -modelHeader.anInt381 - 1; + if (modelHeader.anInt382 >= 0) + face_alpha = new int[numTriangles]; + if (modelHeader.anInt383 >= 0) + triangleTSkin = new int[numTriangles]; + triangleColours = new int[numTriangles]; + Buffer buffer = new Buffer(modelHeader.aByteArray368); + buffer.currentPosition = modelHeader.anInt372; + Buffer stream_1 = new Buffer(modelHeader.aByteArray368); + stream_1.currentPosition = modelHeader.anInt373; + Buffer stream_2 = new Buffer(modelHeader.aByteArray368); + stream_2.currentPosition = modelHeader.anInt374; + Buffer stream_3 = new Buffer(modelHeader.aByteArray368); + stream_3.currentPosition = modelHeader.anInt375; + Buffer stream_4 = new Buffer(modelHeader.aByteArray368); + stream_4.currentPosition = modelHeader.anInt376; + int k = 0; + int l = 0; + int i1 = 0; + for (int j1 = 0; j1 < numVertices; j1++) { + int k1 = buffer.readUnsignedByte(); + int i2 = 0; + if ((k1 & 1) != 0) + i2 = stream_1.readSmart(); + int k2 = 0; + if ((k1 & 2) != 0) + k2 = stream_2.readSmart(); + int i3 = 0; + if ((k1 & 4) != 0) + i3 = stream_3.readSmart(); + vertexX[j1] = k + i2; + vertexY[j1] = l + k2; + vertexZ[j1] = i1 + i3; + k = vertexX[j1]; + l = vertexY[j1]; + i1 = vertexZ[j1]; + if (vertexVSkin != null) + vertexVSkin[j1] = stream_4.readUnsignedByte(); + } + buffer.currentPosition = modelHeader.anInt379; + stream_1.currentPosition = modelHeader.anInt380; + stream_2.currentPosition = modelHeader.anInt381; + stream_3.currentPosition = modelHeader.anInt382; + stream_4.currentPosition = modelHeader.anInt383; + for (int l1 = 0; l1 < numTriangles; l1++) { + triangleColours[l1] = buffer.readUShort(); + if (faceDrawType != null) + faceDrawType[l1] = stream_1.readUnsignedByte(); + if (face_render_priorities != null) + face_render_priorities[l1] = stream_2.readUnsignedByte(); + if (face_alpha != null) { + face_alpha[l1] = stream_3.readUnsignedByte(); + } + if (triangleTSkin != null) + triangleTSkin[l1] = stream_4.readUnsignedByte(); + } + buffer.currentPosition = modelHeader.anInt377; + stream_1.currentPosition = modelHeader.anInt378; + int j2 = 0; + int l2 = 0; + int j3 = 0; + int k3 = 0; + for (int l3 = 0; l3 < numTriangles; l3++) { + int i4 = stream_1.readUnsignedByte(); + if (i4 == 1) { + j2 = buffer.readSmart() + k3; + k3 = j2; + l2 = buffer.readSmart() + k3; + k3 = l2; + j3 = buffer.readSmart() + k3; + k3 = j3; + facePointA[l3] = j2; + facePointB[l3] = l2; + facePointC[l3] = j3; + } + if (i4 == 2) { + l2 = j3; + j3 = buffer.readSmart() + k3; + k3 = j3; + facePointA[l3] = j2; + facePointB[l3] = l2; + facePointC[l3] = j3; + } + if (i4 == 3) { + j2 = j3; + j3 = buffer.readSmart() + k3; + k3 = j3; + facePointA[l3] = j2; + facePointB[l3] = l2; + facePointC[l3] = j3; + } + if (i4 == 4) { + int k4 = j2; + j2 = l2; + l2 = k4; + j3 = buffer.readSmart() + k3; + k3 = j3; + facePointA[l3] = j2; + facePointB[l3] = l2; + facePointC[l3] = j3; + } + } + buffer.currentPosition = modelHeader.anInt384; + for (int j4 = 0; j4 < numberOfTexturesFaces; j4++) { + textures_face_a[j4] = buffer.readUShort(); + textures_face_b[j4] = buffer.readUShort(); + textures_face_c[j4] = buffer.readUShort(); + } + } + + public void scale2(int i) { + for (int i1 = 0; i1 < numVertices; i1++) { + vertexX[i1] = vertexX[i1] / i; + vertexY[i1] = vertexY[i1] / i; + vertexZ[i1] = vertexZ[i1] / i; + } + } + + public static void method460(byte abyte0[], int j) { + try { + if (abyte0 == null) { + ModelHeader class21 = aClass21Array1661[j] = new ModelHeader(); + class21.anInt369 = 0; + class21.anInt370 = 0; + class21.anInt371 = 0; + return; + } + Buffer stream = new Buffer(abyte0); + stream.currentPosition = abyte0.length - 18; + ModelHeader class21_1 = aClass21Array1661[j] = new ModelHeader(); + class21_1.aByteArray368 = abyte0; + class21_1.anInt369 = stream.readUShort(); + class21_1.anInt370 = stream.readUShort(); + class21_1.anInt371 = stream.readUnsignedByte(); + int k = stream.readUnsignedByte(); + int l = stream.readUnsignedByte(); + int i1 = stream.readUnsignedByte(); + int j1 = stream.readUnsignedByte(); + int k1 = stream.readUnsignedByte(); + int l1 = stream.readUShort(); + int i2 = stream.readUShort(); + int j2 = stream.readUShort(); + int k2 = stream.readUShort(); + int l2 = 0; + class21_1.anInt372 = l2; + l2 += class21_1.anInt369; + class21_1.anInt378 = l2; + l2 += class21_1.anInt370; + class21_1.anInt381 = l2; + if (l == 255) + l2 += class21_1.anInt370; + else + class21_1.anInt381 = -l - 1; + class21_1.anInt383 = l2; + if (j1 == 1) + l2 += class21_1.anInt370; + else + class21_1.anInt383 = -1; + class21_1.anInt380 = l2; + if (k == 1) + l2 += class21_1.anInt370; + else + class21_1.anInt380 = -1; + class21_1.anInt376 = l2; + if (k1 == 1) + l2 += class21_1.anInt369; + else + class21_1.anInt376 = -1; + class21_1.anInt382 = l2; + if (i1 == 1) + l2 += class21_1.anInt370; + else + class21_1.anInt382 = -1; + class21_1.anInt377 = l2; + l2 += k2; + class21_1.anInt379 = l2; + l2 += class21_1.anInt370 * 2; + class21_1.anInt384 = l2; + l2 += class21_1.anInt371 * 6; + class21_1.anInt373 = l2; + l2 += l1; + class21_1.anInt374 = l2; + l2 += i2; + class21_1.anInt375 = l2; + l2 += j2; + } catch (Exception _ex) { + } + } + + public void read622Model(byte abyte0[], int modelID) { + Buffer nc1 = new Buffer(abyte0); + Buffer nc2 = new Buffer(abyte0); + Buffer nc3 = new Buffer(abyte0); + Buffer nc4 = new Buffer(abyte0); + Buffer nc5 = new Buffer(abyte0); + Buffer nc6 = new Buffer(abyte0); + Buffer nc7 = new Buffer(abyte0); + nc1.currentPosition = abyte0.length - 23; + int numVertices = nc1.readUShort(); + int numTriangles = nc1.readUShort(); + int numTexTriangles = nc1.readUnsignedByte(); + ModelHeader ModelDef_1 = aClass21Array1661[modelID] = new ModelHeader(); + ModelDef_1.aByteArray368 = abyte0; + ModelDef_1.anInt369 = numVertices; + ModelDef_1.anInt370 = numTriangles; + ModelDef_1.anInt371 = numTexTriangles; + int l1 = nc1.readUnsignedByte(); + boolean bool = (0x1 & l1 ^ 0xffffffff) == -2; + boolean bool_26_ = (0x8 & l1) == 8; + if (!bool_26_) { + read525Model(abyte0, modelID); + return; + } + int newformat = 0; + if (bool_26_) { + nc1.currentPosition -= 7; + newformat = nc1.readUnsignedByte(); + nc1.currentPosition += 6; + } + if (newformat == 15) + newmodel[modelID] = true; + int i2 = nc1.readUnsignedByte(); + int j2 = nc1.readUnsignedByte(); + int k2 = nc1.readUnsignedByte(); + int l2 = nc1.readUnsignedByte(); + int i3 = nc1.readUnsignedByte(); + int j3 = nc1.readUShort(); + int k3 = nc1.readUShort(); + int l3 = nc1.readUShort(); + int i4 = nc1.readUShort(); + int j4 = nc1.readUShort(); + int k4 = 0; + int l4 = 0; + int i5 = 0; + byte[] textureCoordinates = null; + byte[] O = null; + byte[] J = null; + byte[] F = null; + byte[] cb = null; + byte[] gb = null; + byte[] lb = null; + int[] kb = null; + int[] y = null; + int[] N = null; + short[] textureIds = null; + int[] triangleColours2 = new int[numTriangles]; + if (numTexTriangles > 0) { + O = new byte[numTexTriangles]; + nc1.currentPosition = 0; + for (int j5 = 0; j5 < numTexTriangles; j5++) { + byte byte0 = O[j5] = nc1.readSignedByte(); + if (byte0 == 0) + k4++; + if (byte0 >= 1 && byte0 <= 3) + l4++; + if (byte0 == 2) + i5++; + } + } + int k5 = numTexTriangles; + int l5 = k5; + k5 += numVertices; + int i6 = k5; + if (bool) + k5 += numTriangles; + if (l1 == 1) + k5 += numTriangles; + int j6 = k5; + k5 += numTriangles; + int k6 = k5; + if (i2 == 255) + k5 += numTriangles; + int l6 = k5; + if (k2 == 1) + k5 += numTriangles; + int i7 = k5; + if (i3 == 1) + k5 += numVertices; + int j7 = k5; + if (j2 == 1) + k5 += numTriangles; + int k7 = k5; + k5 += i4; + int l7 = k5; + if (l2 == 1) + k5 += numTriangles * 2; + int i8 = k5; + k5 += j4; + int j8 = k5; + k5 += numTriangles * 2; + int k8 = k5; + k5 += j3; + int l8 = k5; + k5 += k3; + int i9 = k5; + k5 += l3; + int j9 = k5; + k5 += k4 * 6; + int k9 = k5; + k5 += l4 * 6; + int i_59_ = 6; + if (newformat != 14) { + if (newformat >= 15) + i_59_ = 9; + } else + i_59_ = 7; + int l9 = k5; + k5 += i_59_ * l4; + int i10 = k5; + k5 += l4; + int j10 = k5; + k5 += l4; + int k10 = k5; + k5 += l4 + i5 * 2; + int[] vertexX = new int[numVertices]; + int[] vertexY = new int[numVertices]; + int[] vertexZ = new int[numVertices]; + int[] facePoint1 = new int[numTriangles]; + int[] facePoint2 = new int[numTriangles]; + int[] facePoint3 = new int[numTriangles]; + vertexVSkin = new int[numVertices]; + faceDrawType = new int[numTriangles]; + face_render_priorities = new int[numTriangles]; + face_alpha = new int[numTriangles]; + triangleTSkin = new int[numTriangles]; + if (i3 == 1) + vertexVSkin = new int[numVertices]; + if (bool) + faceDrawType = new int[numTriangles]; + if (i2 == 255) + face_render_priorities = new int[numTriangles]; + else { + } + if (j2 == 1) + face_alpha = new int[numTriangles]; + if (k2 == 1) + triangleTSkin = new int[numTriangles]; + if (l2 == 1) + textureIds = new short[numTriangles]; + if (l2 == 1 && numTexTriangles > 0) { + textureCoordinates = texture_coordinates = new byte[numTriangles]; + } + triangleColours2 = new int[numTriangles]; + int[] texTrianglesPoint1 = null; + int[] texTrianglesPoint2 = null; + int[] texTrianglesPoint3 = null; + if (numTexTriangles > 0) { + texTrianglesPoint1 = new int[numTexTriangles]; + texTrianglesPoint2 = new int[numTexTriangles]; + texTrianglesPoint3 = new int[numTexTriangles]; + if (l4 > 0) { + kb = new int[l4]; + N = new int[l4]; + y = new int[l4]; + gb = new byte[l4]; + lb = new byte[l4]; + F = new byte[l4]; + } + if (i5 > 0) { + cb = new byte[i5]; + J = new byte[i5]; + } + } + nc1.currentPosition = l5; + nc2.currentPosition = k8; + nc3.currentPosition = l8; + nc4.currentPosition = i9; + nc5.currentPosition = i7; + int l10 = 0; + int i11 = 0; + int j11 = 0; + for (int k11 = 0; k11 < numVertices; k11++) { + int l11 = nc1.readUnsignedByte(); + int j12 = 0; + if ((l11 & 1) != 0) + j12 = nc2.readSmart(); + int l12 = 0; + if ((l11 & 2) != 0) + l12 = nc3.readSmart(); + int j13 = 0; + if ((l11 & 4) != 0) + j13 = nc4.readSmart(); + vertexX[k11] = l10 + j12; + vertexY[k11] = i11 + l12; + vertexZ[k11] = j11 + j13; + l10 = vertexX[k11]; + i11 = vertexY[k11]; + j11 = vertexZ[k11]; + if (vertexVSkin != null) + vertexVSkin[k11] = nc5.readUnsignedByte(); + } + nc1.currentPosition = j8; + nc2.currentPosition = i6; + nc3.currentPosition = k6; + nc4.currentPosition = j7; + nc5.currentPosition = l6; + nc6.currentPosition = l7; + nc7.currentPosition = i8; + for (int i12 = 0; i12 < numTriangles; i12++) { + triangleColours2[i12] = nc1.readUShort(); + if (l1 == 1) { + faceDrawType[i12] = nc2.readSignedByte(); + if (faceDrawType[i12] == 2) + triangleColours2[i12] = 65535; + faceDrawType[i12] = 0; + } + if (i2 == 255) { + face_render_priorities[i12] = nc3.readSignedByte(); + } + if (j2 == 1) { + face_alpha[i12] = nc4.readSignedByte(); + if (face_alpha[i12] < 0) + face_alpha[i12] = (256 + face_alpha[i12]); + } + if (k2 == 1) + triangleTSkin[i12] = nc5.readUnsignedByte(); + if (l2 == 1) + textureIds[i12] = (short) (nc6.readUShort() - 1); + if (textureCoordinates != null) + if (textureIds[i12] != -1) + textureCoordinates[i12] = texture_coordinates[i12] = (byte) (nc7.readUnsignedByte() - 1); + else + textureCoordinates[i12] = texture_coordinates[i12] = -1; + } + nc1.currentPosition = k7; + nc2.currentPosition = j6; + int k12 = 0; + int i13 = 0; + int k13 = 0; + int l13 = 0; + for (int i14 = 0; i14 < numTriangles; i14++) { + int j14 = nc2.readUnsignedByte(); + if (j14 == 1) { + k12 = nc1.readSmart() + l13; + l13 = k12; + i13 = nc1.readSmart() + l13; + l13 = i13; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + if (j14 == 2) { + i13 = k13; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + if (j14 == 3) { + k12 = k13; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + if (j14 == 4) { + int l14 = k12; + k12 = i13; + i13 = l14; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + } + nc1.currentPosition = j9; + nc2.currentPosition = k9; + nc3.currentPosition = l9; + nc4.currentPosition = i10; + nc5.currentPosition = j10; + nc6.currentPosition = k10; + for (int k14 = 0; k14 < numTexTriangles; k14++) { + int i15 = O[k14] & 0xff; + if (i15 == 0) { + texTrianglesPoint1[k14] = nc1.readUShort(); + texTrianglesPoint2[k14] = nc1.readUShort(); + texTrianglesPoint3[k14] = nc1.readUShort(); + } + if (i15 == 1) { + texTrianglesPoint1[k14] = nc2.readUShort(); + texTrianglesPoint2[k14] = nc2.readUShort(); + texTrianglesPoint3[k14] = nc2.readUShort(); + if (newformat < 15) { + kb[k14] = nc3.readUShort(); + if (newformat >= 14) + N[k14] = nc3.readUTriByte(-1); + else + N[k14] = nc3.readUShort(); + y[k14] = nc3.readUShort(); + } else { + kb[k14] = nc3.readUTriByte(-1); + N[k14] = nc3.readUTriByte(-1); + y[k14] = nc3.readUTriByte(-1); + } + gb[k14] = nc4.readSignedByte(); + lb[k14] = nc5.readSignedByte(); + F[k14] = nc6.readSignedByte(); + } + if (i15 == 2) { + texTrianglesPoint1[k14] = nc2.readUShort(); + texTrianglesPoint2[k14] = nc2.readUShort(); + texTrianglesPoint3[k14] = nc2.readUShort(); + if (newformat >= 15) { + kb[k14] = nc3.readUTriByte(-1); + N[k14] = nc3.readUTriByte(-1); + y[k14] = nc3.readUTriByte(-1); + } else { + kb[k14] = nc3.readUShort(); + if (newformat < 14) + N[k14] = nc3.readUShort(); + else + N[k14] = nc3.readUTriByte(-1); + y[k14] = nc3.readUShort(); + } + gb[k14] = nc4.readSignedByte(); + lb[k14] = nc5.readSignedByte(); + F[k14] = nc6.readSignedByte(); + cb[k14] = nc6.readSignedByte(); + J[k14] = nc6.readSignedByte(); + } + if (i15 == 3) { + texTrianglesPoint1[k14] = nc2.readUShort(); + texTrianglesPoint2[k14] = nc2.readUShort(); + texTrianglesPoint3[k14] = nc2.readUShort(); + if (newformat < 15) { + kb[k14] = nc3.readUShort(); + if (newformat < 14) + N[k14] = nc3.readUShort(); + else + N[k14] = nc3.readUTriByte(-1); + y[k14] = nc3.readUShort(); + } else { + kb[k14] = nc3.readUTriByte(-1); + N[k14] = nc3.readUTriByte(-1); + y[k14] = nc3.readUTriByte(-1); + } + gb[k14] = nc4.readSignedByte(); + lb[k14] = nc5.readSignedByte(); + F[k14] = nc6.readSignedByte(); + } + } + if (i2 != 255) { + for (int i12 = 0; i12 < numTriangles; i12++) + face_render_priorities[i12] = i2; + } + triangleColours = triangleColours2; + this.numVertices = numVertices; + this.numTriangles = numTriangles; + this.vertexX = vertexX; + this.vertexY = vertexY; + this.vertexZ = vertexZ; + facePointA = facePoint1; + facePointB = facePoint2; + facePointC = facePoint3; + scale2(4); + convertTexturesTo317(textureIds, texTrianglesPoint1, texTrianglesPoint2, texTrianglesPoint3, false); + } + + public void read525Model(byte abyte0[], int modelID) { + Buffer nc1 = new Buffer(abyte0); + Buffer nc2 = new Buffer(abyte0); + Buffer nc3 = new Buffer(abyte0); + Buffer nc4 = new Buffer(abyte0); + Buffer nc5 = new Buffer(abyte0); + Buffer nc6 = new Buffer(abyte0); + Buffer nc7 = new Buffer(abyte0); + nc1.currentPosition = abyte0.length - 23; + int numVertices = nc1.readUShort(); + int numTriangles = nc1.readUShort(); + int numTexTriangles = nc1.readUnsignedByte(); + ModelHeader ModelDef_1 = aClass21Array1661[modelID] = new ModelHeader(); + ModelDef_1.aByteArray368 = abyte0; + ModelDef_1.anInt369 = numVertices; + ModelDef_1.anInt370 = numTriangles; + ModelDef_1.anInt371 = numTexTriangles; + int l1 = nc1.readUnsignedByte(); + boolean bool = (0x1 & l1 ^ 0xffffffff) == -2; + int i2 = nc1.readUnsignedByte(); + int j2 = nc1.readUnsignedByte(); + int k2 = nc1.readUnsignedByte(); + int l2 = nc1.readUnsignedByte(); + int i3 = nc1.readUnsignedByte(); + int j3 = nc1.readUShort(); + int k3 = nc1.readUShort(); + int l3 = nc1.readUShort(); + int i4 = nc1.readUShort(); + int j4 = nc1.readUShort(); + int k4 = 0; + int l4 = 0; + int i5 = 0; + byte[] textureCoordinates = null; + byte[] O = null; + byte[] J = null; + byte[] F = null; + byte[] cb = null; + byte[] gb = null; + byte[] lb = null; + int[] kb = null; + int[] y = null; + int[] N = null; + short[] textureIds = null; + int[] triangleColours2 = new int[numTriangles]; + if (numTexTriangles > 0) { + O = new byte[numTexTriangles]; + nc1.currentPosition = 0; + for (int j5 = 0; j5 < numTexTriangles; j5++) { + byte byte0 = O[j5] = nc1.readSignedByte(); + if (byte0 == 0) + k4++; + if (byte0 >= 1 && byte0 <= 3) + l4++; + if (byte0 == 2) + i5++; + } + } + int k5 = numTexTriangles; + int l5 = k5; + k5 += numVertices; + int i6 = k5; + if (l1 == 1) + k5 += numTriangles; + int j6 = k5; + k5 += numTriangles; + int k6 = k5; + if (i2 == 255) + k5 += numTriangles; + int l6 = k5; + if (k2 == 1) + k5 += numTriangles; + int i7 = k5; + if (i3 == 1) + k5 += numVertices; + int j7 = k5; + if (j2 == 1) + k5 += numTriangles; + int k7 = k5; + k5 += i4; + int l7 = k5; + if (l2 == 1) + k5 += numTriangles * 2; + int i8 = k5; + k5 += j4; + int j8 = k5; + k5 += numTriangles * 2; + int k8 = k5; + k5 += j3; + int l8 = k5; + k5 += k3; + int i9 = k5; + k5 += l3; + int j9 = k5; + k5 += k4 * 6; + int k9 = k5; + k5 += l4 * 6; + int l9 = k5; + k5 += l4 * 6; + int i10 = k5; + k5 += l4; + int j10 = k5; + k5 += l4; + int k10 = k5; + k5 += l4 + i5 * 2; + int[] vertexX = new int[numVertices]; + int[] vertexY = new int[numVertices]; + int[] vertexZ = new int[numVertices]; + int[] facePoint1 = new int[numTriangles]; + int[] facePoint2 = new int[numTriangles]; + int[] facePoint3 = new int[numTriangles]; + vertexVSkin = new int[numVertices]; + faceDrawType = new int[numTriangles]; + face_render_priorities = new int[numTriangles]; + face_alpha = new int[numTriangles]; + triangleTSkin = new int[numTriangles]; + if (i3 == 1) + vertexVSkin = new int[numVertices]; + if (bool) + faceDrawType = new int[numTriangles]; + if (i2 == 255) + face_render_priorities = new int[numTriangles]; + else { + } + if (j2 == 1) + face_alpha = new int[numTriangles]; + if (k2 == 1) + triangleTSkin = new int[numTriangles]; + if (l2 == 1) { + textureIds = new short[numTriangles]; + } + if (l2 == 1 && numTexTriangles > 0) { + textureCoordinates = texture_coordinates = new byte[numTriangles]; + } + triangleColours2 = new int[numTriangles]; + int[] texTrianglesPoint1 = null; + int[] texTrianglesPoint2 = null; + int[] texTrianglesPoint3 = null; + if (numTexTriangles > 0) { + texTrianglesPoint1 = new int[numTexTriangles]; + texTrianglesPoint2 = new int[numTexTriangles]; + texTrianglesPoint3 = new int[numTexTriangles]; + if (l4 > 0) { + kb = new int[l4]; + N = new int[l4]; + y = new int[l4]; + gb = new byte[l4]; + lb = new byte[l4]; + F = new byte[l4]; + } + if (i5 > 0) { + cb = new byte[i5]; + J = new byte[i5]; + } + } + nc1.currentPosition = l5; + nc2.currentPosition = k8; + nc3.currentPosition = l8; + nc4.currentPosition = i9; + nc5.currentPosition = i7; + int l10 = 0; + int i11 = 0; + int j11 = 0; + for (int k11 = 0; k11 < numVertices; k11++) { + int l11 = nc1.readUnsignedByte(); + int j12 = 0; + if ((l11 & 1) != 0) + j12 = nc2.readSmart(); + int l12 = 0; + if ((l11 & 2) != 0) + l12 = nc3.readSmart(); + int j13 = 0; + if ((l11 & 4) != 0) + j13 = nc4.readSmart(); + vertexX[k11] = l10 + j12; + vertexY[k11] = i11 + l12; + vertexZ[k11] = j11 + j13; + l10 = vertexX[k11]; + i11 = vertexY[k11]; + j11 = vertexZ[k11]; + if (vertexVSkin != null) + vertexVSkin[k11] = nc5.readUnsignedByte(); + } + nc1.currentPosition = j8; + nc2.currentPosition = i6; + nc3.currentPosition = k6; + nc4.currentPosition = j7; + nc5.currentPosition = l6; + nc6.currentPosition = l7; + nc7.currentPosition = i8; + for (int i12 = 0; i12 < numTriangles; i12++) { + triangleColours2[i12] = nc1.readUShort(); + if (l1 == 1) { + faceDrawType[i12] = nc2.readSignedByte(); + if (faceDrawType[i12] == 2) + triangleColours2[i12] = 65535; + faceDrawType[i12] = 0; + } + if (i2 == 255) { + face_render_priorities[i12] = nc3.readSignedByte(); + } + if (j2 == 1) { + face_alpha[i12] = nc4.readSignedByte(); + if (face_alpha[i12] < 0) + face_alpha[i12] = (256 + face_alpha[i12]); + } + if (k2 == 1) + triangleTSkin[i12] = nc5.readUnsignedByte(); + if (l2 == 1) + textureIds[i12] = (short) (nc6.readUShort() - 1); + + if (textureCoordinates != null) + if (textureIds[i12] != -1) + textureCoordinates[i12] = texture_coordinates[i12] = (byte) (nc7.readUnsignedByte() - 1); + else + textureCoordinates[i12] = texture_coordinates[i12] = -1; + } + nc1.currentPosition = k7; + nc2.currentPosition = j6; + int k12 = 0; + int i13 = 0; + int k13 = 0; + int l13 = 0; + for (int i14 = 0; i14 < numTriangles; i14++) { + int j14 = nc2.readUnsignedByte(); + if (j14 == 1) { + k12 = nc1.readSmart() + l13; + l13 = k12; + i13 = nc1.readSmart() + l13; + l13 = i13; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + if (j14 == 2) { + i13 = k13; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + if (j14 == 3) { + k12 = k13; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + if (j14 == 4) { + int l14 = k12; + k12 = i13; + i13 = l14; + k13 = nc1.readSmart() + l13; + l13 = k13; + facePoint1[i14] = k12; + facePoint2[i14] = i13; + facePoint3[i14] = k13; + } + } + nc1.currentPosition = j9; + nc2.currentPosition = k9; + nc3.currentPosition = l9; + nc4.currentPosition = i10; + nc5.currentPosition = j10; + nc6.currentPosition = k10; + for (int k14 = 0; k14 < numTexTriangles; k14++) { + int i15 = O[k14] & 0xff; + if (i15 == 0) { + texTrianglesPoint1[k14] = nc1.readUShort(); + texTrianglesPoint2[k14] = nc1.readUShort(); + texTrianglesPoint3[k14] = nc1.readUShort(); + } + if (i15 == 1) { + texTrianglesPoint1[k14] = nc2.readUShort(); + texTrianglesPoint2[k14] = nc2.readUShort(); + texTrianglesPoint3[k14] = nc2.readUShort(); + kb[k14] = nc3.readUShort(); + N[k14] = nc3.readUShort(); + y[k14] = nc3.readUShort(); + gb[k14] = nc4.readSignedByte(); + lb[k14] = nc5.readSignedByte(); + F[k14] = nc6.readSignedByte(); + } + if (i15 == 2) { + texTrianglesPoint1[k14] = nc2.readUShort(); + texTrianglesPoint2[k14] = nc2.readUShort(); + texTrianglesPoint3[k14] = nc2.readUShort(); + kb[k14] = nc3.readUShort(); + N[k14] = nc3.readUShort(); + y[k14] = nc3.readUShort(); + gb[k14] = nc4.readSignedByte(); + lb[k14] = nc5.readSignedByte(); + F[k14] = nc6.readSignedByte(); + cb[k14] = nc6.readSignedByte(); + J[k14] = nc6.readSignedByte(); + } + if (i15 == 3) { + texTrianglesPoint1[k14] = nc2.readUShort(); + texTrianglesPoint2[k14] = nc2.readUShort(); + texTrianglesPoint3[k14] = nc2.readUShort(); + kb[k14] = nc3.readUShort(); + N[k14] = nc3.readUShort(); + y[k14] = nc3.readUShort(); + gb[k14] = nc4.readSignedByte(); + lb[k14] = nc5.readSignedByte(); + F[k14] = nc6.readSignedByte(); + } + } + if (i2 != 255) { + for (int i12 = 0; i12 < numTriangles; i12++) + face_render_priorities[i12] = i2; + } + triangleColours = triangleColours2; + this.numVertices = numVertices; + this.numTriangles = numTriangles; + this.vertexX = vertexX; + this.vertexY = vertexY; + this.vertexZ = vertexZ; + facePointA = facePoint1; + facePointB = facePoint2; + facePointC = facePoint3; + convertTexturesTo317(textureIds, texTrianglesPoint1, texTrianglesPoint2, texTrianglesPoint3, false); + } + + public static boolean newmodel[]; + + public static void method459(int i, + Provider onDemandFetcherParent) { + aClass21Array1661 = new ModelHeader[80000]; + newmodel = new boolean[100000]; + resourceProvider = onDemandFetcherParent; + } + + public static void method461(int j) { + aClass21Array1661[j] = null; + } + + public static Model getModel(int file) { + if (aClass21Array1661 == null) + return null; + ModelHeader class21 = aClass21Array1661[file]; + if (class21 == null) { + resourceProvider.provide(file); + return null; + } else { + return new Model(file); + } + } + + public static boolean isCached(int file) { + if (aClass21Array1661 == null) + return false; + + ModelHeader class21 = aClass21Array1661[file]; + if (class21 == null) { + resourceProvider.provide(file); + return false; + } else { + return true; + } + } + + private Model(boolean flag) { + aBoolean1618 = true; + fits_on_single_square = false; + if (!flag) + aBoolean1618 = !aBoolean1618; + } + + public Model(int i, Model amodel[]) { + aBoolean1618 = true; + fits_on_single_square = false; + anInt1620++; + boolean flag = false; + boolean flag1 = false; + boolean flag2 = false; + boolean flag3 = false; + numVertices = 0; + numTriangles = 0; + numberOfTexturesFaces = 0; + face_priority = -1; + for (int k = 0; k < i; k++) { + Model model = amodel[k]; + if (model != null) { + numVertices += model.numVertices; + numTriangles += model.numTriangles; + numberOfTexturesFaces += model.numberOfTexturesFaces; + flag |= model.faceDrawType != null; + if (model.face_render_priorities != null) { + flag1 = true; + } else { + if (face_priority == -1) + face_priority = model.face_priority; + if (face_priority != model.face_priority) + flag1 = true; + } + flag2 |= model.face_alpha != null; + flag3 |= model.triangleTSkin != null; + } + } + + vertexX = new int[numVertices]; + vertexY = new int[numVertices]; + vertexZ = new int[numVertices]; + vertexVSkin = new int[numVertices]; + facePointA = new int[numTriangles]; + facePointB = new int[numTriangles]; + facePointC = new int[numTriangles]; + textures_face_a = new int[numberOfTexturesFaces]; + textures_face_b = new int[numberOfTexturesFaces]; + textures_face_c = new int[numberOfTexturesFaces]; + if (flag) + faceDrawType = new int[numTriangles]; + if (flag1) + face_render_priorities = new int[numTriangles]; + if (flag2) + face_alpha = new int[numTriangles]; + if (flag3) + triangleTSkin = new int[numTriangles]; + triangleColours = new int[numTriangles]; + numVertices = 0; + numTriangles = 0; + numberOfTexturesFaces = 0; + int l = 0; + for (int i1 = 0; i1 < i; i1++) { + Model model_1 = amodel[i1]; + if (model_1 != null) { + for (int j1 = 0; j1 < model_1.numTriangles; j1++) { + if (flag) + if (model_1.faceDrawType == null) { + faceDrawType[numTriangles] = 0; + } else { + int k1 = model_1.faceDrawType[j1]; + if ((k1 & 2) == 2) + k1 += l << 2; + faceDrawType[numTriangles] = k1; + } + if (flag1) + if (model_1.face_render_priorities == null) + face_render_priorities[numTriangles] = model_1.face_priority; + else + face_render_priorities[numTriangles] = model_1.face_render_priorities[j1]; + if (flag2) + if (model_1.face_alpha == null) + face_alpha[numTriangles] = 0; + else + face_alpha[numTriangles] = model_1.face_alpha[j1]; + + if (flag3 && model_1.triangleTSkin != null) + triangleTSkin[numTriangles] = model_1.triangleTSkin[j1]; + triangleColours[numTriangles] = model_1.triangleColours[j1]; + facePointA[numTriangles] = method465(model_1, + model_1.facePointA[j1]); + facePointB[numTriangles] = method465(model_1, + model_1.facePointB[j1]); + facePointC[numTriangles] = method465(model_1, + model_1.facePointC[j1]); + numTriangles++; + } + + for (int l1 = 0; l1 < model_1.numberOfTexturesFaces; l1++) { + textures_face_a[numberOfTexturesFaces] = method465(model_1, + model_1.textures_face_a[l1]); + textures_face_b[numberOfTexturesFaces] = method465(model_1, + model_1.textures_face_b[l1]); + textures_face_c[numberOfTexturesFaces] = method465(model_1, + model_1.textures_face_c[l1]); + numberOfTexturesFaces++; + } + + l += model_1.numberOfTexturesFaces; + } + } + + } + + public Model(Model amodel[]) { + int i = 2; + aBoolean1618 = true; + fits_on_single_square = false; + anInt1620++; + boolean flag1 = false; + boolean flag2 = false; + boolean flag3 = false; + boolean flag4 = false; + numVertices = 0; + numTriangles = 0; + numberOfTexturesFaces = 0; + face_priority = -1; + for (int k = 0; k < i; k++) { + Model model = amodel[k]; + if (model != null) { + numVertices += model.numVertices; + numTriangles += model.numTriangles; + numberOfTexturesFaces += model.numberOfTexturesFaces; + flag1 |= model.faceDrawType != null; + if (model.face_render_priorities != null) { + flag2 = true; + } else { + if (face_priority == -1) + face_priority = model.face_priority; + if (face_priority != model.face_priority) + flag2 = true; + } + flag3 |= model.face_alpha != null; + flag4 |= model.triangleColours != null; + } + } + + vertexX = new int[numVertices]; + vertexY = new int[numVertices]; + vertexZ = new int[numVertices]; + facePointA = new int[numTriangles]; + facePointB = new int[numTriangles]; + facePointC = new int[numTriangles]; + faceHslA = new int[numTriangles]; + faceHslB = new int[numTriangles]; + faceHslC = new int[numTriangles]; + textures_face_a = new int[numberOfTexturesFaces]; + textures_face_b = new int[numberOfTexturesFaces]; + textures_face_c = new int[numberOfTexturesFaces]; + if (flag1) + faceDrawType = new int[numTriangles]; + if (flag2) + face_render_priorities = new int[numTriangles]; + if (flag3) + face_alpha = new int[numTriangles]; + if (flag4) + triangleColours = new int[numTriangles]; + numVertices = 0; + numTriangles = 0; + numberOfTexturesFaces = 0; + int i1 = 0; + for (int j1 = 0; j1 < i; j1++) { + Model model_1 = amodel[j1]; + if (model_1 != null) { + int k1 = numVertices; + for (int l1 = 0; l1 < model_1.numVertices; l1++) { + vertexX[numVertices] = model_1.vertexX[l1]; + vertexY[numVertices] = model_1.vertexY[l1]; + vertexZ[numVertices] = model_1.vertexZ[l1]; + numVertices++; + } + + for (int i2 = 0; i2 < model_1.numTriangles; i2++) { + facePointA[numTriangles] = model_1.facePointA[i2] + k1; + facePointB[numTriangles] = model_1.facePointB[i2] + k1; + facePointC[numTriangles] = model_1.facePointC[i2] + k1; + faceHslA[numTriangles] = model_1.faceHslA[i2]; + faceHslB[numTriangles] = model_1.faceHslB[i2]; + faceHslC[numTriangles] = model_1.faceHslC[i2]; + if (flag1) + if (model_1.faceDrawType == null) { + faceDrawType[numTriangles] = 0; + } else { + int j2 = model_1.faceDrawType[i2]; + if ((j2 & 2) == 2) + j2 += i1 << 2; + faceDrawType[numTriangles] = j2; + } + if (flag2) + if (model_1.face_render_priorities == null) + face_render_priorities[numTriangles] = model_1.face_priority; + else + face_render_priorities[numTriangles] = model_1.face_render_priorities[i2]; + if (flag3) + if (model_1.face_alpha == null) + face_alpha[numTriangles] = 0; + else + face_alpha[numTriangles] = model_1.face_alpha[i2]; + if (flag4 && model_1.triangleColours != null) + triangleColours[numTriangles] = model_1.triangleColours[i2]; + + numTriangles++; + } + + for (int k2 = 0; k2 < model_1.numberOfTexturesFaces; k2++) { + textures_face_a[numberOfTexturesFaces] = model_1.textures_face_a[k2] + k1; + textures_face_b[numberOfTexturesFaces] = model_1.textures_face_b[k2] + k1; + textures_face_c[numberOfTexturesFaces] = model_1.textures_face_c[k2] + k1; + numberOfTexturesFaces++; + } + + i1 += model_1.numberOfTexturesFaces; + } + } + + calculateDistances(); + } + + public Model(boolean flag, boolean flag1, boolean flag2, Model model) { + aBoolean1618 = true; + fits_on_single_square = false; + anInt1620++; + numVertices = model.numVertices; + numTriangles = model.numTriangles; + numberOfTexturesFaces = model.numberOfTexturesFaces; + if (flag2) { + vertexX = model.vertexX; + vertexY = model.vertexY; + vertexZ = model.vertexZ; + } else { + vertexX = new int[numVertices]; + vertexY = new int[numVertices]; + vertexZ = new int[numVertices]; + for (int j = 0; j < numVertices; j++) { + vertexX[j] = model.vertexX[j]; + vertexY[j] = model.vertexY[j]; + vertexZ[j] = model.vertexZ[j]; + } + + } + if (flag) { + triangleColours = model.triangleColours; + } else { + triangleColours = new int[numTriangles]; + for (int k = 0; k < numTriangles; k++) + triangleColours[k] = model.triangleColours[k]; + + } + if (flag1) { + face_alpha = model.face_alpha; + } else { + face_alpha = new int[numTriangles]; + if (model.face_alpha == null) { + for (int l = 0; l < numTriangles; l++) + face_alpha[l] = 0; + + } else { + for (int i1 = 0; i1 < numTriangles; i1++) + face_alpha[i1] = model.face_alpha[i1]; + + } + } + vertexVSkin = model.vertexVSkin; + triangleTSkin = model.triangleTSkin; + faceDrawType = model.faceDrawType; + facePointA = model.facePointA; + facePointB = model.facePointB; + facePointC = model.facePointC; + face_render_priorities = model.face_render_priorities; + face_priority = model.face_priority; + textures_face_a = model.textures_face_a; + textures_face_b = model.textures_face_b; + textures_face_c = model.textures_face_c; + } + + public Model(boolean flag, boolean flag1, Model model) { + aBoolean1618 = true; + fits_on_single_square = false; + anInt1620++; + numVertices = model.numVertices; + numTriangles = model.numTriangles; + numberOfTexturesFaces = model.numberOfTexturesFaces; + if (flag) { + vertexY = new int[numVertices]; + for (int j = 0; j < numVertices; j++) + vertexY[j] = model.vertexY[j]; + + } else { + vertexY = model.vertexY; + } + if (flag1) { + faceHslA = new int[numTriangles]; + faceHslB = new int[numTriangles]; + faceHslC = new int[numTriangles]; + for (int k = 0; k < numTriangles; k++) { + faceHslA[k] = model.faceHslA[k]; + faceHslB[k] = model.faceHslB[k]; + faceHslC[k] = model.faceHslC[k]; + } + + faceDrawType = new int[numTriangles]; + if (model.faceDrawType == null) { + for (int l = 0; l < numTriangles; l++) + faceDrawType[l] = 0; + + } else { + for (int i1 = 0; i1 < numTriangles; i1++) + faceDrawType[i1] = model.faceDrawType[i1]; + + } + super.vertexNormals = new VertexNormal[numVertices]; + for (int j1 = 0; j1 < numVertices; j1++) { + VertexNormal class33 = super.vertexNormals[j1] = new VertexNormal(); + VertexNormal class33_1 = model.vertexNormals[j1]; + class33.normalX = class33_1.normalX; + class33.normalY = class33_1.normalY; + class33.normalZ = class33_1.normalZ; + class33.magnitude = class33_1.magnitude; + } + + alsoVertexNormals = model.alsoVertexNormals; + } else { + faceHslA = model.faceHslA; + faceHslB = model.faceHslB; + faceHslC = model.faceHslC; + faceDrawType = model.faceDrawType; + } + vertexX = model.vertexX; + vertexZ = model.vertexZ; + triangleColours = model.triangleColours; + face_alpha = model.face_alpha; + face_render_priorities = model.face_render_priorities; + face_priority = model.face_priority; + facePointA = model.facePointA; + facePointB = model.facePointB; + facePointC = model.facePointC; + textures_face_a = model.textures_face_a; + textures_face_b = model.textures_face_b; + textures_face_c = model.textures_face_c; + super.modelBaseY = model.modelBaseY; + + maxVertexDistanceXZPlane = model.maxVertexDistanceXZPlane; + diagonal3DAboveOrigin = model.diagonal3DAboveOrigin; + maxRenderDepth = model.maxRenderDepth; + minimumXVertex = model.minimumXVertex; + maximumZVertex = model.maximumZVertex; + minimumZVertex = model.minimumZVertex; + maximumXVertex = model.maximumXVertex; + } + + public void method464(Model model, boolean flag) { + numVertices = model.numVertices; + numTriangles = model.numTriangles; + numberOfTexturesFaces = model.numberOfTexturesFaces; + if (anIntArray1622.length < numVertices) { + anIntArray1622 = new int[numVertices + 10000]; + anIntArray1623 = new int[numVertices + 10000]; + anIntArray1624 = new int[numVertices + 10000]; + } + vertexX = anIntArray1622; + vertexY = anIntArray1623; + vertexZ = anIntArray1624; + for (int k = 0; k < numVertices; k++) { + vertexX[k] = model.vertexX[k]; + vertexY[k] = model.vertexY[k]; + vertexZ[k] = model.vertexZ[k]; + } + + if (flag) { + face_alpha = model.face_alpha; + } else { + if (anIntArray1625.length < numTriangles) + anIntArray1625 = new int[numTriangles + 100]; + face_alpha = anIntArray1625; + if (model.face_alpha == null) { + for (int l = 0; l < numTriangles; l++) + face_alpha[l] = 0; + + } else { + for (int i1 = 0; i1 < numTriangles; i1++) + face_alpha[i1] = model.face_alpha[i1]; + + } + } + faceDrawType = model.faceDrawType; + triangleColours = model.triangleColours; + face_render_priorities = model.face_render_priorities; + face_priority = model.face_priority; + faceGroups = model.faceGroups; + vertexGroups = model.vertexGroups; + facePointA = model.facePointA; + facePointB = model.facePointB; + facePointC = model.facePointC; + faceHslA = model.faceHslA; + faceHslB = model.faceHslB; + faceHslC = model.faceHslC; + textures_face_a = model.textures_face_a; + textures_face_b = model.textures_face_b; + textures_face_c = model.textures_face_c; + } + + private final int method465(Model model, int i) { + int j = -1; + int k = model.vertexX[i]; + int l = model.vertexY[i]; + int i1 = model.vertexZ[i]; + for (int j1 = 0; j1 < numVertices; j1++) { + if (k != vertexX[j1] || l != vertexY[j1] + || i1 != vertexZ[j1]) + continue; + j = j1; + break; + } + + if (j == -1) { + vertexX[numVertices] = k; + vertexY[numVertices] = l; + vertexZ[numVertices] = i1; + if (model.vertexVSkin != null) + vertexVSkin[numVertices] = model.vertexVSkin[i]; + j = numVertices++; + } + return j; + } + + public void calculateDistances() { + super.modelBaseY = 0; + maxVertexDistanceXZPlane = 0; + maximumYVertex = 0; + for (int i = 0; i < numVertices; i++) { + int x = vertexX[i]; + int y = vertexY[i]; + int z = vertexZ[i]; + if (-y > super.modelBaseY) + super.modelBaseY = -y; + if (y > maximumYVertex) + maximumYVertex = y; + int sqDistance = x * x + z * z; + if (sqDistance > maxVertexDistanceXZPlane) + maxVertexDistanceXZPlane = sqDistance; + } + maxVertexDistanceXZPlane = (int) (Math.sqrt(maxVertexDistanceXZPlane) + 0.98999999999999999D); + diagonal3DAboveOrigin = (int) (Math.sqrt(maxVertexDistanceXZPlane * maxVertexDistanceXZPlane + super.modelBaseY * super.modelBaseY) + 0.98999999999999999D); + maxRenderDepth = diagonal3DAboveOrigin + (int) (Math.sqrt(maxVertexDistanceXZPlane * maxVertexDistanceXZPlane + maximumYVertex * maximumYVertex) + 0.98999999999999999D); + } + + public void computeSphericalBounds() { + super.modelBaseY = 0; + maximumYVertex = 0; + for (int i = 0; i < numVertices; i++) { + int j = vertexY[i]; + if (-j > super.modelBaseY) + super.modelBaseY = -j; + if (j > maximumYVertex) + maximumYVertex = j; + } + + diagonal3DAboveOrigin = (int) (Math.sqrt(maxVertexDistanceXZPlane * maxVertexDistanceXZPlane + super.modelBaseY + * super.modelBaseY) + 0.98999999999999999D); + maxRenderDepth = diagonal3DAboveOrigin + + (int) (Math.sqrt(maxVertexDistanceXZPlane * maxVertexDistanceXZPlane + maximumYVertex + * maximumYVertex) + 0.98999999999999999D); + } + + public void calculateVertexData() { + super.modelBaseY = 0; + maxVertexDistanceXZPlane = 0; + maximumYVertex = 0; + minimumXVertex = 999999; + maximumXVertex = -999999; + maximumZVertex = -99999; + minimumZVertex = 99999; + for (int idx = 0; idx < numVertices; idx++) { + int xVertex = vertexX[idx]; + int yVertex = vertexY[idx]; + int zVertex = vertexZ[idx]; + if (xVertex < minimumXVertex) + minimumXVertex = xVertex; + if (xVertex > maximumXVertex) + maximumXVertex = xVertex; + if (zVertex < minimumZVertex) + minimumZVertex = zVertex; + if (zVertex > maximumZVertex) + maximumZVertex = zVertex; + if (-yVertex > super.modelBaseY) + super.modelBaseY = -yVertex; + if (yVertex > maximumYVertex) + maximumYVertex = yVertex; + int vertexDistanceXZPlane = xVertex * xVertex + zVertex * zVertex; + if (vertexDistanceXZPlane > maxVertexDistanceXZPlane) + maxVertexDistanceXZPlane = vertexDistanceXZPlane; + } + + maxVertexDistanceXZPlane = (int) Math.sqrt(maxVertexDistanceXZPlane); + diagonal3DAboveOrigin = (int) Math.sqrt(maxVertexDistanceXZPlane * maxVertexDistanceXZPlane + super.modelBaseY * super.modelBaseY); + maxRenderDepth = diagonal3DAboveOrigin + (int) Math.sqrt(maxVertexDistanceXZPlane * maxVertexDistanceXZPlane + maximumYVertex * maximumYVertex); + } + + public void skin() { + if (vertexVSkin != null) { + int ai[] = new int[256]; + int j = 0; + for (int l = 0; l < numVertices; l++) { + int j1 = vertexVSkin[l]; + ai[j1]++; + if (j1 > j) + j = j1; + } + + vertexGroups = new int[j + 1][]; + for (int k1 = 0; k1 <= j; k1++) { + vertexGroups[k1] = new int[ai[k1]]; + ai[k1] = 0; + } + + for (int j2 = 0; j2 < numVertices; j2++) { + int l2 = vertexVSkin[j2]; + vertexGroups[l2][ai[l2]++] = j2; + } + + vertexVSkin = null; + } + if (triangleTSkin != null) { + int ai1[] = new int[256]; + int k = 0; + for (int i1 = 0; i1 < numTriangles; i1++) { + int l1 = triangleTSkin[i1]; + ai1[l1]++; + if (l1 > k) + k = l1; + } + + faceGroups = new int[k + 1][]; + for (int i2 = 0; i2 <= k; i2++) { + faceGroups[i2] = new int[ai1[i2]]; + ai1[i2] = 0; + } + + for (int k2 = 0; k2 < numTriangles; k2++) { + int i3 = triangleTSkin[k2]; + faceGroups[i3][ai1[i3]++] = k2; + } + + triangleTSkin = null; + } + } + + public void applyAnimationFrame(int frame, int nextFrame, int end, int cycle) { + if (!Configuration.enableTweening) { + applyTransform(frame); + return; + } + interpolateFrames(frame, nextFrame, end, cycle); + } + + + public void interpolateFrames(int frame, int nextFrame, int end, int cycle) { + + if ((vertexGroups != null && frame != -1)) { + Frame currentAnimation = Frame.method531(frame); + if (currentAnimation == null) + return; + FrameBase currentList = currentAnimation.base; + xAnimOffset = 0; + yAnimOffset = 0; + zAnimOffset = 0; + Frame nextAnimation = null; + FrameBase nextList = null; + if (nextFrame != -1) { + nextAnimation = Frame.method531(nextFrame); + if (nextAnimation == null || nextAnimation.base == null) + return; + FrameBase nextSkin = nextAnimation.base; + if (nextSkin != currentList) + nextAnimation = null; + nextList = nextSkin; + } + if (nextAnimation == null || nextList == null) { + for (int opcodeLinkTableIdx = 0; opcodeLinkTableIdx < currentAnimation.transformationCount; opcodeLinkTableIdx++) { + int i_264_ = currentAnimation.transformationIndices[opcodeLinkTableIdx]; + transformSkin(currentList.transformationType[i_264_], currentList.skinList[i_264_], currentAnimation.transformX[opcodeLinkTableIdx], currentAnimation.transformY[opcodeLinkTableIdx], currentAnimation.transformZ[opcodeLinkTableIdx]); + } + } else { + + for (int i1 = 0; i1 < currentAnimation.transformationCount; i1++) { + int n1 = currentAnimation.transformationIndices[i1]; + int opcode = currentList.transformationType[n1]; + int[] skin = currentList.skinList[n1]; + int x = currentAnimation.transformX[i1]; + int y = currentAnimation.transformY[i1]; + int z = currentAnimation.transformZ[i1]; + boolean found = false; + label0: for (int i2 = 0; i2 < nextAnimation.transformationCount; i2++) { + int n2 = nextAnimation.transformationIndices[i2]; + if (nextList.skinList[n2].equals(skin)) { + //Opcode 3 = Rotation + if (opcode != 2) { + x += (nextAnimation.transformX[i2] - x) * cycle / end; + y += (nextAnimation.transformY[i2] - y) * cycle / end; + z += (nextAnimation.transformZ[i2] - z) * cycle / end; + } else { + x &= 0xff; + y &= 0xff; + z &= 0xff; + int dx = nextAnimation.transformX[i2] - x & 0xff; + int dy = nextAnimation.transformY[i2] - y & 0xff; + int dz = nextAnimation.transformZ[i2] - z & 0xff; + if (dx >= 128) { + dx -= 256; + } + if (dy >= 128) { + dy -= 256; + } + if (dz >= 128) { + dz -= 256; + } + x = x + dx * cycle / end & 0xff; + y = y + dy * cycle / end & 0xff; + z = z + dz * cycle / end & 0xff; + } + found = true; + break label0; + } + } + if (!found) { + if (opcode != 3 && opcode != 2) { + x = x * (end - cycle) / end; + y = y * (end - cycle) / end; + z = z * (end - cycle) / end; + } else if (opcode == 3) { + x = (x * (end - cycle) + (cycle << 7)) / end; + y = (y * (end - cycle) + (cycle << 7)) / end; + z = (z * (end - cycle) + (cycle << 7)) / end; + } else { + x &= 0xff; + y &= 0xff; + z &= 0xff; + int dx = -x & 0xff; + int dy = -y & 0xff; + int dz = -z & 0xff; + if (dx >= 128) { + dx -= 256; + } + if (dy >= 128) { + dy -= 256; + } + if (dz >= 128) { + dz -= 256; + } + x = x + dx * cycle / end & 0xff; + y = y + dy * cycle / end & 0xff; + z = z + dz * cycle / end & 0xff; + } + } + transformSkin(opcode, skin, x, y, z); + } + } + } + } + + private void transformSkin(int animationType, int skin[], int x, int y, int z) { + + int i1 = skin.length; + if (animationType == 0) { + int j1 = 0; + xAnimOffset = 0; + yAnimOffset = 0; + zAnimOffset = 0; + for (int k2 = 0; k2 < i1; k2++) { + int l3 = skin[k2]; + if (l3 < vertexGroups.length) { + int ai5[] = vertexGroups[l3]; + for (int i5 = 0; i5 < ai5.length; i5++) { + int j6 = ai5[i5]; + xAnimOffset += vertexX[j6]; + yAnimOffset += vertexY[j6]; + zAnimOffset += vertexZ[j6]; + j1++; + } + + } + } + + if (j1 > 0) { + xAnimOffset = (int)(xAnimOffset / j1 + x); + yAnimOffset = (int)(yAnimOffset / j1 + y); + zAnimOffset = (int)(zAnimOffset / j1 + z); + return; + } else { + xAnimOffset = (int)x; + yAnimOffset = (int)y; + zAnimOffset = (int)z; + return; + } + } + if (animationType == 1) { + for (int k1 = 0; k1 < i1; k1++) { + int l2 = skin[k1]; + if (l2 < vertexGroups.length) { + int ai1[] = vertexGroups[l2]; + for (int i4 = 0; i4 < ai1.length; i4++) { + int j5 = ai1[i4]; + vertexX[j5] += x; + vertexY[j5] += y; + vertexZ[j5] += z; + } + + } + } + + return; + } + if (animationType == 2) { + for (int l1 = 0; l1 < i1; l1++) { + int i3 = skin[l1]; + if (i3 < vertexGroups.length) { + int ai2[] = vertexGroups[i3]; + for (int j4 = 0; j4 < ai2.length; j4++) { + int k5 = ai2[j4]; + vertexX[k5] -= xAnimOffset; + vertexY[k5] -= yAnimOffset; + vertexZ[k5] -= zAnimOffset; + int k6 = (x & 0xff) * 8; + int l6 = (y & 0xff) * 8; + int i7 = (z & 0xff) * 8; + if (i7 != 0) { + int j7 = SINE[i7]; + int i8 = COSINE[i7]; + int l8 = vertexY[k5] * j7 + vertexX[k5] * i8 >> 16; + vertexY[k5] = vertexY[k5] * i8 - vertexX[k5] * j7 >> 16; + vertexX[k5] = l8; + } + if (k6 != 0) { + int k7 = SINE[k6]; + int j8 = COSINE[k6]; + int i9 = vertexY[k5] * j8 - vertexZ[k5] * k7 >> 16; + vertexZ[k5] = vertexY[k5] * k7 + vertexZ[k5] * j8 >> 16; + vertexY[k5] = i9; + } + if (l6 != 0) { + int l7 = SINE[l6]; + int k8 = COSINE[l6]; + int j9 = vertexZ[k5] * l7 + vertexX[k5] * k8 >> 16; + vertexZ[k5] = vertexZ[k5] * k8 - vertexX[k5] * l7 >> 16; + vertexX[k5] = j9; + } + vertexX[k5] += xAnimOffset; + vertexY[k5] += yAnimOffset; + vertexZ[k5] += zAnimOffset; + } + + } + } + + return; + } + if (animationType == 3) { + for (int i2 = 0; i2 < i1; i2++) { + int j3 = skin[i2]; + if (j3 < vertexGroups.length) { + int ai3[] = vertexGroups[j3]; + for (int k4 = 0; k4 < ai3.length; k4++) { + int l5 = ai3[k4]; + vertexX[l5] -= xAnimOffset; + vertexY[l5] -= yAnimOffset; + vertexZ[l5] -= zAnimOffset; + vertexX[l5] = (int)((vertexX[l5] * x) / 128); + vertexY[l5] = (int)((vertexY[l5] * y) / 128); + vertexZ[l5] = (int)((vertexZ[l5] * z) / 128); + vertexX[l5] += xAnimOffset; + vertexY[l5] += yAnimOffset; + vertexZ[l5] += zAnimOffset; + } + + } + } + + return; + } + if (animationType == 5 && faceGroups != null && face_alpha != null) { + for (int j2 = 0; j2 < i1; j2++) { + int k3 = skin[j2]; + if (k3 < faceGroups.length) { + int ai4[] = faceGroups[k3]; + for (int l4 = 0; l4 < ai4.length; l4++) { + int i6 = ai4[l4]; + face_alpha[i6] += x * 8; + if (face_alpha[i6] < 0) + face_alpha[i6] = 0; + if (face_alpha[i6] > 255) + face_alpha[i6] = 255; + } + + } + } + + } + } + + public void applyTransform(int frameId) { + if (vertexGroups == null) + return; + if (frameId == -1) + return; + Frame animationFrame = Frame.method531(frameId); + if (animationFrame == null) + return; + FrameBase class18 = animationFrame.base; + xAnimOffset = 0; + yAnimOffset = 0; + zAnimOffset = 0; + for (int k = 0; k < animationFrame.transformationCount; k++) { + int l = animationFrame.transformationIndices[k]; + transformSkin(class18.transformationType[l], class18.skinList[l], + animationFrame.transformX[k], animationFrame.transformY[k], + animationFrame.transformZ[k]); + } + + } + + public void applyAnimationFrames(int ai[], int j, int k) { + if (k == -1) + return; + if (ai == null || j == -1) { + applyTransform(k); + return; + } + Frame class36 = Frame.method531(k); + if (class36 == null) + return; + Frame class36_1 = Frame.method531(j); + if (class36_1 == null) { + applyTransform(k); + return; + } + FrameBase class18 = class36.base; + xAnimOffset = 0; + yAnimOffset = 0; + zAnimOffset = 0; + int l = 0; + int i1 = ai[l++]; + for (int j1 = 0; j1 < class36.transformationCount; j1++) { + int k1; + for (k1 = class36.transformationIndices[j1]; k1 > i1; i1 = ai[l++]) + ; + if (k1 != i1 || class18.transformationType[k1] == 0) + transformSkin(class18.transformationType[k1], class18.skinList[k1], class36.transformX[j1], class36.transformY[j1], class36.transformZ[j1]); + } + + xAnimOffset = 0; + yAnimOffset = 0; + zAnimOffset = 0; + l = 0; + i1 = ai[l++]; + for (int l1 = 0; l1 < class36_1.transformationCount; l1++) { + int i2; + for (i2 = class36_1.transformationIndices[l1]; i2 > i1; i1 = ai[l++]) + ; + if (i2 == i1 || class18.transformationType[i2] == 0) + transformSkin(class18.transformationType[i2], class18.skinList[i2], class36_1.transformX[l1], class36_1.transformY[l1], class36_1.transformZ[l1]); + } + } + +/* private void transformSkin(int i, int ai[], int j, int k, int l) { + + int i1 = ai.length; + if (i == 0) { + int j1 = 0; + xAnimOffset = 0; + yAnimOffset = 0; + zAnimOffset = 0; + for (int k2 = 0; k2 < i1; k2++) { + int l3 = ai[k2]; + if (l3 < vertexGroups.length) { + int ai5[] = vertexGroups[l3]; + for (int i5 = 0; i5 < ai5.length; i5++) { + int j6 = ai5[i5]; + xAnimOffset += vertexX[j6]; + yAnimOffset += vertexY[j6]; + zAnimOffset += vertexZ[j6]; + j1++; + } + + } + } + + if (j1 > 0) { + xAnimOffset = xAnimOffset / j1 + j; + yAnimOffset = yAnimOffset / j1 + k; + zAnimOffset = zAnimOffset / j1 + l; + return; + } else { + xAnimOffset = j; + yAnimOffset = k; + zAnimOffset = l; + return; + } + } + if (i == 1) { + for (int k1 = 0; k1 < i1; k1++) { + int l2 = ai[k1]; + if (l2 < vertexGroups.length) { + int ai1[] = vertexGroups[l2]; + for (int i4 = 0; i4 < ai1.length; i4++) { + int j5 = ai1[i4]; + vertexX[j5] += j; + vertexY[j5] += k; + vertexZ[j5] += l; + } + + } + } + + return; + } + if (i == 2) { + for (int l1 = 0; l1 < i1; l1++) { + int i3 = ai[l1]; + if (i3 < vertexGroups.length) { + int ai2[] = vertexGroups[i3]; + for (int j4 = 0; j4 < ai2.length; j4++) { + int k5 = ai2[j4]; + vertexX[k5] -= xAnimOffset; + vertexY[k5] -= yAnimOffset; + vertexZ[k5] -= zAnimOffset; + int k6 = (j & 0xff) * 8; + int l6 = (k & 0xff) * 8; + int i7 = (l & 0xff) * 8; + if (i7 != 0) { + int j7 = SINE[i7]; + int i8 = COSINE[i7]; + int l8 = vertexY[k5] * j7 + vertexX[k5] * i8 >> 16; + vertexY[k5] = vertexY[k5] * i8 - vertexX[k5] * j7 >> 16; + vertexX[k5] = l8; + } + if (k6 != 0) { + int k7 = SINE[k6]; + int j8 = COSINE[k6]; + int i9 = vertexY[k5] * j8 - vertexZ[k5] * k7 >> 16; + vertexZ[k5] = vertexY[k5] * k7 + vertexZ[k5] * j8 >> 16; + vertexY[k5] = i9; + } + if (l6 != 0) { + int l7 = SINE[l6]; + int k8 = COSINE[l6]; + int j9 = vertexZ[k5] * l7 + vertexX[k5] * k8 >> 16; + vertexZ[k5] = vertexZ[k5] * k8 - vertexX[k5] * l7 >> 16; + vertexX[k5] = j9; + } + vertexX[k5] += xAnimOffset; + vertexY[k5] += yAnimOffset; + vertexZ[k5] += zAnimOffset; + } + + } + } + return; + } + if (i == 3) { + for (int i2 = 0; i2 < i1; i2++) { + int j3 = ai[i2]; + if (j3 < vertexGroups.length) { + int ai3[] = vertexGroups[j3]; + for (int k4 = 0; k4 < ai3.length; k4++) { + int l5 = ai3[k4]; + vertexX[l5] -= xAnimOffset; + vertexY[l5] -= yAnimOffset; + vertexZ[l5] -= zAnimOffset; + vertexX[l5] = (vertexX[l5] * j) / 128; + vertexY[l5] = (vertexY[l5] * k) / 128; + vertexZ[l5] = (vertexZ[l5] * l) / 128; + vertexX[l5] += xAnimOffset; + vertexY[l5] += yAnimOffset; + vertexZ[l5] += zAnimOffset; + } + } + } + return; + } + if (i == 5 && faceGroups != null && face_alpha != null) { + for (int j2 = 0; j2 < i1; j2++) { + int k3 = ai[j2]; + if (k3 < faceGroups.length) { + int ai4[] = faceGroups[k3]; + for (int l4 = 0; l4 < ai4.length; l4++) { + int i6 = ai4[l4]; + face_alpha[i6] += j * 8; + if (face_alpha[i6] < 0) + face_alpha[i6] = 0; + if (face_alpha[i6] > 255) + face_alpha[i6] = 255; + } + } + } + } + }*/ + + public void rotate90Degrees() { + for (int j = 0; j < numVertices; j++) { + int k = vertexX[j]; + vertexX[j] = vertexZ[j]; + vertexZ[j] = -k; + } + } + + public void leanOverX(int i) { + int k = SINE[i]; + int l = COSINE[i]; + for (int i1 = 0; i1 < numVertices; i1++) { + int j1 = vertexY[i1] * l - vertexZ[i1] * k >> 16; + vertexZ[i1] = vertexY[i1] * k + vertexZ[i1] * l >> 16; + vertexY[i1] = j1; + } + } + + public void translate(int i, int j, int l) { + for (int i1 = 0; i1 < numVertices; i1++) { + vertexX[i1] += i; + vertexY[i1] += j; + vertexZ[i1] += l; + } + } + + public void recolor(int i, int j) { + for (int k = 0; k < numTriangles; k++) + if (triangleColours[k] == i) + triangleColours[k] = j; + } + + public void method477() { + for (int j = 0; j < numVertices; j++) + vertexZ[j] = -vertexZ[j]; + for (int k = 0; k < numTriangles; k++) { + int l = facePointA[k]; + facePointA[k] = facePointC[k]; + facePointC[k] = l; + } + } + + public void scale(int i, int j, int l) { + for (int i1 = 0; i1 < numVertices; i1++) { + vertexX[i1] = (vertexX[i1] * i) / 128; + vertexY[i1] = (vertexY[i1] * l) / 128; + vertexZ[i1] = (vertexZ[i1] * j) / 128; + } + + } + + public final void light(int i, int j, int k, int l, int i1, boolean lightModelNotSure) { + int j1 = (int) Math.sqrt(k * k + l * l + i1 * i1); + int k1 = j * j1 >> 8; + if (faceHslA == null) { + faceHslA = new int[numTriangles]; + faceHslB = new int[numTriangles]; + faceHslC = new int[numTriangles]; + } + if (super.vertexNormals == null) { + super.vertexNormals = new VertexNormal[numVertices]; + for (int l1 = 0; l1 < numVertices; l1++) + super.vertexNormals[l1] = new VertexNormal(); + + } + for (int i2 = 0; i2 < numTriangles; i2++) { + + //Cheapfix + /* if (triangleColours != null && face_alpha != null) + if (triangleColours[i2] == 65535 //Most triangles + //|| triangleColours[i2] == 0 //Black Triangles 633 Models - Fixes Gwd walls & Black models + || triangleColours[i2] == 16705 //Nezzy Green Triangles//GWD White Triangles + ) + face_alpha[i2] = 255;*/ + int j2 = facePointA[i2]; + int l2 = facePointB[i2]; + int i3 = facePointC[i2]; + int j3 = vertexX[l2] - vertexX[j2]; + int k3 = vertexY[l2] - vertexY[j2]; + int l3 = vertexZ[l2] - vertexZ[j2]; + int i4 = vertexX[i3] - vertexX[j2]; + int j4 = vertexY[i3] - vertexY[j2]; + int k4 = vertexZ[i3] - vertexZ[j2]; + int l4 = k3 * k4 - j4 * l3; + int i5 = l3 * i4 - k4 * j3; + int j5; + for (j5 = j3 * j4 - i4 * k3; l4 > 8192 || i5 > 8192 || j5 > 8192 + || l4 < -8192 || i5 < -8192 || j5 < -8192; j5 >>= 1) { + l4 >>= 1; + i5 >>= 1; + } + + int k5 = (int) Math.sqrt(l4 * l4 + i5 * i5 + j5 * j5); + if (k5 <= 0) + k5 = 1; + l4 = (l4 * 256) / k5; + i5 = (i5 * 256) / k5; + j5 = (j5 * 256) / k5; + + if (faceDrawType == null || (faceDrawType[i2] & 1) == 0) { + + VertexNormal class33_2 = super.vertexNormals[j2]; + class33_2.normalX += l4; + class33_2.normalY += i5; + class33_2.normalZ += j5; + class33_2.magnitude++; + class33_2 = super.vertexNormals[l2]; + class33_2.normalX += l4; + class33_2.normalY += i5; + class33_2.normalZ += j5; + class33_2.magnitude++; + class33_2 = super.vertexNormals[i3]; + class33_2.normalX += l4; + class33_2.normalY += i5; + class33_2.normalZ += j5; + class33_2.magnitude++; + + } else { + + int l5 = i + (k * l4 + l * i5 + i1 * j5) / (k1 + k1 / 2); + faceHslA[i2] = method481(triangleColours[i2], l5, + faceDrawType[i2]); + + } + } + + if (lightModelNotSure) { + doShading(i, k1, k, l, i1); + } else { + alsoVertexNormals = new VertexNormal[numVertices]; + for (int k2 = 0; k2 < numVertices; k2++) { + VertexNormal class33 = super.vertexNormals[k2]; + VertexNormal class33_1 = alsoVertexNormals[k2] = new VertexNormal(); + class33_1.normalX = class33.normalX; + class33_1.normalY = class33.normalY; + class33_1.normalZ = class33.normalZ; + class33_1.magnitude = class33.magnitude; + } + + } + if (lightModelNotSure) { + calculateDistances(); + } else { + calculateVertexData(); + } + } + + public static String ccString = "Cla"; + public static String xxString = "at Cl"; + public static String vvString = "nt"; + public static String aString9_9 = "" + ccString + "n Ch" + xxString + "ie" + + vvString + " "; + + public final void doShading(int intensity, int falloff, int lightX, int lightY, int lightZ) { + for (int triangle = 0; triangle < numTriangles; triangle++) { + int point1 = facePointA[triangle]; + int point2 = facePointB[triangle]; + int point3 = facePointC[triangle]; + if (faceDrawType == null) { + int faceColour = triangleColours[triangle]; + VertexNormal vertexNormal = super.vertexNormals[point1]; + int k2 = intensity + (lightX * vertexNormal.normalX + lightY * vertexNormal.normalY + lightZ * vertexNormal.normalZ) / (falloff * vertexNormal.magnitude); + faceHslA[triangle] = method481(faceColour, k2, 0); + vertexNormal = super.vertexNormals[point2]; + k2 = intensity + (lightX * vertexNormal.normalX + lightY * vertexNormal.normalY + lightZ * vertexNormal.normalZ) / (falloff * vertexNormal.magnitude); + faceHslB[triangle] = method481(faceColour, k2, 0); + vertexNormal = super.vertexNormals[point3]; + k2 = intensity + (lightX * vertexNormal.normalX + lightY * vertexNormal.normalY + lightZ * vertexNormal.normalZ) / (falloff * vertexNormal.magnitude); + faceHslC[triangle] = method481(faceColour, k2, 0); + } else if ((faceDrawType[triangle] & 1) == 0) { + int faceColour = triangleColours[triangle]; + int faceType = faceDrawType[triangle]; + VertexNormal vertexNormal = super.vertexNormals[point1]; + int l2 = intensity + (lightX * vertexNormal.normalX + lightY * vertexNormal.normalY + lightZ * vertexNormal.normalZ) / (falloff * vertexNormal.magnitude); + faceHslA[triangle] = method481(faceColour, l2, faceType); + vertexNormal = super.vertexNormals[point2]; + l2 = intensity + (lightX * vertexNormal.normalX + lightY * vertexNormal.normalY + lightZ * vertexNormal.normalZ) / (falloff * vertexNormal.magnitude); + faceHslB[triangle] = method481(faceColour, l2, faceType); + vertexNormal = super.vertexNormals[point3]; + l2 = intensity + (lightX * vertexNormal.normalX + lightY * vertexNormal.normalY + lightZ * vertexNormal.normalZ) / (falloff * vertexNormal.magnitude); + faceHslC[triangle] = method481(faceColour, l2, faceType); + } + } + + super.vertexNormals = null; + alsoVertexNormals = null; + vertexVSkin = null; + triangleTSkin = null; + if (faceDrawType != null) { + for (int triangle = 0; triangle < numTriangles; triangle++) + if ((faceDrawType[triangle] & 2) == 2) + return; + } + triangleColours = null; + } + + public static final int method481(int i, int j, int k) { + if (i == 65535) + return 0; + if ((k & 2) == 2) { + if (j < 0) + j = 0; + else if (j > 127) + j = 127; + j = 127 - j; + return j; + } + + j = j * (i & 0x7f) >> 7; + if (j < 2) + j = 2; + else if (j > 126) + j = 126; + return (i & 0xff80) + j; + } + + public final void method482(int j, int k, int l, int i1, int j1, int k1) { + int i = 0; + int l1 = Rasterizer3D.originViewX; + int i2 = Rasterizer3D.originViewY; + int j2 = SINE[i]; + int k2 = COSINE[i]; + int l2 = SINE[j]; + int i3 = COSINE[j]; + int j3 = SINE[k]; + int k3 = COSINE[k]; + int l3 = SINE[l]; + int i4 = COSINE[l]; + int j4 = j1 * l3 + k1 * i4 >> 16; + for (int k4 = 0; k4 < numVertices; k4++) { + int l4 = vertexX[k4]; + int i5 = vertexY[k4]; + int j5 = vertexZ[k4]; + if (k != 0) { + int k5 = i5 * j3 + l4 * k3 >> 16; + i5 = i5 * k3 - l4 * j3 >> 16; + l4 = k5; + } + if (i != 0) { + int l5 = i5 * k2 - j5 * j2 >> 16; + j5 = i5 * j2 + j5 * k2 >> 16; + i5 = l5; + } + if (j != 0) { + int i6 = j5 * l2 + l4 * i3 >> 16; + j5 = j5 * i3 - l4 * l2 >> 16; + l4 = i6; + } + l4 += i1; + i5 += j1; + j5 += k1; + int j6 = i5 * i4 - j5 * l3 >> 16; + j5 = i5 * l3 + j5 * i4 >> 16; + i5 = j6; + projected_vertex_z[k4] = j5 - j4; + camera_vertex_z[k4] = 0; + projected_vertex_x[k4] = l1 + (l4 << 9) / j5; + projected_vertex_y[k4] = i2 + (i5 << 9) / j5; + if (numberOfTexturesFaces > 0) { + anIntArray1668[k4] = l4; + camera_vertex_y[k4] = i5; + camera_vertex_x[k4] = j5; + } + } + + try { + method483(false, false, 0); + return; + } catch (Exception _ex) { + return; + } + } + + public final void renderAtPoint(int i, int j, int k, int l, int i1, int j1, + int k1, int l1, int i2) { + int j2 = l1 * i1 - j1 * l >> 16; + int k2 = k1 * j + j2 * k >> 16; + int l2 = maxVertexDistanceXZPlane * k >> 16; + int i3 = k2 + l2; + if (i3 <= 50 || k2 >= 3500) + return; + int j3 = l1 * l + j1 * i1 >> 16; + int k3 = j3 - maxVertexDistanceXZPlane << SceneGraph.viewDistance; + if (k3 / i3 >= Rasterizer2D.viewportCenterX) + return; + int l3 = j3 + maxVertexDistanceXZPlane << SceneGraph.viewDistance; + if (l3 / i3 <= -Rasterizer2D.viewportCenterX) + return; + int i4 = k1 * k - j2 * j >> 16; + int j4 = maxVertexDistanceXZPlane * j >> 16; + int k4 = i4 + j4 << SceneGraph.viewDistance; + if (k4 / i3 <= -Rasterizer2D.viewportCenterY) + return; + int l4 = j4 + (super.modelBaseY * k >> 16); + int i5 = i4 - l4 << SceneGraph.viewDistance; + if (i5 / i3 >= Rasterizer2D.viewportCenterY) + return; + int j5 = l2 + (super.modelBaseY * j >> 16); + boolean flag = false; + if (k2 - j5 <= 50) + flag = true; + boolean flag1 = false; + if (i2 > 0 && aBoolean1684) { + int k5 = k2 - l2; + if (k5 <= 50) + k5 = 50; + if (j3 > 0) { + k3 /= i3; + l3 /= k5; + } else { + l3 /= i3; + k3 /= k5; + } + if (i4 > 0) { + i5 /= i3; + k4 /= k5; + } else { + k4 /= i3; + i5 /= k5; + } + int i6 = anInt1685 - Rasterizer3D.originViewX; + int k6 = anInt1686 - Rasterizer3D.originViewY; + if (i6 > k3 && i6 < l3 && k6 > i5 && k6 < k4) + if (fits_on_single_square) + anIntArray1688[anInt1687++] = i2; + else + flag1 = true; + } + int l5 = Rasterizer3D.originViewX; + int j6 = Rasterizer3D.originViewY; + int l6 = 0; + int i7 = 0; + if (i != 0) { + l6 = SINE[i]; + i7 = COSINE[i]; + } + for (int j7 = 0; j7 < numVertices; j7++) { + int k7 = vertexX[j7]; + int l7 = vertexY[j7]; + int i8 = vertexZ[j7]; + if (i != 0) { + int j8 = i8 * l6 + k7 * i7 >> 16; + i8 = i8 * i7 - k7 * l6 >> 16; + k7 = j8; + } + k7 += j1; + l7 += k1; + i8 += l1; + int k8 = i8 * l + k7 * i1 >> 16; + i8 = i8 * i1 - k7 * l >> 16; + k7 = k8; + k8 = l7 * k - i8 * j >> 16; + i8 = l7 * j + i8 * k >> 16; + l7 = k8; + projected_vertex_z[j7] = i8 - k2; + camera_vertex_z[j7] = i8; + if (i8 >= 50) { + projected_vertex_x[j7] = l5 + (k7 << SceneGraph.viewDistance) / i8; + projected_vertex_y[j7] = j6 + (l7 << SceneGraph.viewDistance) / i8; + } else { + projected_vertex_x[j7] = -5000; + flag = true; + } + if (flag || numberOfTexturesFaces > 0) { + anIntArray1668[j7] = k7; + camera_vertex_y[j7] = l7; + camera_vertex_x[j7] = i8; + } + } + + try { + method483(flag, flag1, i2); + return; + } catch (Exception _ex) { + return; + } + } + + private final void method483(boolean flag, boolean flag1, int i) { + for (int j = 0; j < maxRenderDepth; j++) + depthListIndices[j] = 0; + + for (int k = 0; k < numTriangles; k++) + if (faceDrawType == null || faceDrawType[k] != -1) { + int l = facePointA[k]; + int k1 = facePointB[k]; + int j2 = facePointC[k]; + int i3 = projected_vertex_x[l]; + int l3 = projected_vertex_x[k1]; + int k4 = projected_vertex_x[j2]; + if (flag && (i3 == -5000 || l3 == -5000 || k4 == -5000)) { + outOfReach[k] = true; + int j5 = (projected_vertex_z[l] + projected_vertex_z[k1] + projected_vertex_z[j2]) + / 3 + diagonal3DAboveOrigin; + faceLists[j5][depthListIndices[j5]++] = k; + } else { + if (flag1 + && method486(anInt1685, anInt1686, + projected_vertex_y[l], projected_vertex_y[k1], + projected_vertex_y[j2], i3, l3, k4)) { + anIntArray1688[anInt1687++] = i; + flag1 = false; + } + if ((i3 - l3) * (projected_vertex_y[j2] - projected_vertex_y[k1]) + - (projected_vertex_y[l] - projected_vertex_y[k1]) + * (k4 - l3) > 0) { + outOfReach[k] = false; + if (i3 < 0 || l3 < 0 || k4 < 0 + || i3 > Rasterizer2D.lastX + || l3 > Rasterizer2D.lastX + || k4 > Rasterizer2D.lastX) + hasAnEdgeToRestrict[k] = true; + else + hasAnEdgeToRestrict[k] = false; + int k5 = (projected_vertex_z[l] + projected_vertex_z[k1] + projected_vertex_z[j2]) + / 3 + diagonal3DAboveOrigin; + faceLists[k5][depthListIndices[k5]++] = k; + } + } + } + + if (face_render_priorities == null) { + for (int i1 = maxRenderDepth - 1; i1 >= 0; i1--) { + int l1 = depthListIndices[i1]; + if (l1 > 0) { + int ai[] = faceLists[i1]; + for (int j3 = 0; j3 < l1; j3++) + method484(ai[j3]); + + } + } + + return; + } + for (int j1 = 0; j1 < 12; j1++) { + anIntArray1673[j1] = 0; + anIntArray1677[j1] = 0; + } + + for (int i2 = maxRenderDepth - 1; i2 >= 0; i2--) { + int k2 = depthListIndices[i2]; + if (k2 > 0) { + int ai1[] = faceLists[i2]; + for (int i4 = 0; i4 < k2; i4++) { + int l4 = ai1[i4]; + int l5 = face_render_priorities[l4]; + int j6 = anIntArray1673[l5]++; + anIntArrayArray1674[l5][j6] = l4; + if (l5 < 10) + anIntArray1677[l5] += i2; + else if (l5 == 10) + anIntArray1675[j6] = i2; + else + anIntArray1676[j6] = i2; + } + + } + } + + int l2 = 0; + if (anIntArray1673[1] > 0 || anIntArray1673[2] > 0) + l2 = (anIntArray1677[1] + anIntArray1677[2]) + / (anIntArray1673[1] + anIntArray1673[2]); + int k3 = 0; + if (anIntArray1673[3] > 0 || anIntArray1673[4] > 0) + k3 = (anIntArray1677[3] + anIntArray1677[4]) + / (anIntArray1673[3] + anIntArray1673[4]); + int j4 = 0; + if (anIntArray1673[6] > 0 || anIntArray1673[8] > 0) + j4 = (anIntArray1677[6] + anIntArray1677[8]) + / (anIntArray1673[6] + anIntArray1673[8]); + int i6 = 0; + int k6 = anIntArray1673[10]; + int ai2[] = anIntArrayArray1674[10]; + int ai3[] = anIntArray1675; + if (i6 == k6) { + i6 = 0; + k6 = anIntArray1673[11]; + ai2 = anIntArrayArray1674[11]; + ai3 = anIntArray1676; + } + int i5; + if (i6 < k6) + i5 = ai3[i6]; + else + i5 = -1000; + for (int l6 = 0; l6 < 10; l6++) { + while (l6 == 0 && i5 > l2) { + method484(ai2[i6++]); + if (i6 == k6 && ai2 != anIntArrayArray1674[11]) { + i6 = 0; + k6 = anIntArray1673[11]; + ai2 = anIntArrayArray1674[11]; + ai3 = anIntArray1676; + } + if (i6 < k6) + i5 = ai3[i6]; + else + i5 = -1000; + } + while (l6 == 3 && i5 > k3) { + method484(ai2[i6++]); + if (i6 == k6 && ai2 != anIntArrayArray1674[11]) { + i6 = 0; + k6 = anIntArray1673[11]; + ai2 = anIntArrayArray1674[11]; + ai3 = anIntArray1676; + } + if (i6 < k6) + i5 = ai3[i6]; + else + i5 = -1000; + } + while (l6 == 5 && i5 > j4) { + method484(ai2[i6++]); + if (i6 == k6 && ai2 != anIntArrayArray1674[11]) { + i6 = 0; + k6 = anIntArray1673[11]; + ai2 = anIntArrayArray1674[11]; + ai3 = anIntArray1676; + } + if (i6 < k6) + i5 = ai3[i6]; + else + i5 = -1000; + } + int i7 = anIntArray1673[l6]; + int ai4[] = anIntArrayArray1674[l6]; + for (int j7 = 0; j7 < i7; j7++) + method484(ai4[j7]); + + } + + while (i5 != -1000) { + method484(ai2[i6++]); + if (i6 == k6 && ai2 != anIntArrayArray1674[11]) { + i6 = 0; + ai2 = anIntArrayArray1674[11]; + k6 = anIntArray1673[11]; + ai3 = anIntArray1676; + } + if (i6 < k6) + i5 = ai3[i6]; + else + i5 = -1000; + } + } + + private final void method484(int i) { + if (outOfReach[i]) { + method485(i); + return; + } + int j = facePointA[i]; + int k = facePointB[i]; + int l = facePointC[i]; + Rasterizer3D.textureOutOfDrawingBounds = hasAnEdgeToRestrict[i]; + if (face_alpha == null) + Rasterizer3D.alpha = 0; + else + Rasterizer3D.alpha = face_alpha[i]; + int i1; + if (faceDrawType == null) + i1 = 0; + else + i1 = faceDrawType[i] & 3; + if (i1 == 0) { + Rasterizer3D.drawShadedTriangle(projected_vertex_y[j], projected_vertex_y[k], + projected_vertex_y[l], projected_vertex_x[j], projected_vertex_x[k], + projected_vertex_x[l], faceHslA[i], faceHslB[i], + faceHslC[i], camera_vertex_z[j], camera_vertex_z[k], camera_vertex_z[l]); + return; + } + if (i1 == 1) { + Rasterizer3D.drawFlatTriangle(projected_vertex_y[j], projected_vertex_y[k], + projected_vertex_y[l], projected_vertex_x[j], projected_vertex_x[k], + projected_vertex_x[l], modelIntArray3[faceHslA[i]], camera_vertex_z[j], camera_vertex_z[k], camera_vertex_z[l]);; + return; + } + if (i1 == 2) { + int j1 = faceDrawType[i] >> 2; + int l1 = textures_face_a[j1]; + int j2 = textures_face_b[j1]; + int l2 = textures_face_c[j1]; + Rasterizer3D.drawTexturedTriangle(projected_vertex_y[j], projected_vertex_y[k], + projected_vertex_y[l], projected_vertex_x[j], projected_vertex_x[k], + projected_vertex_x[l], faceHslA[i], faceHslB[i], + faceHslC[i], anIntArray1668[l1], anIntArray1668[j2], + anIntArray1668[l2], camera_vertex_y[l1], camera_vertex_y[j2], + camera_vertex_y[l2], camera_vertex_x[l1], camera_vertex_x[j2], + camera_vertex_x[l2], triangleColours[i], camera_vertex_z[j], camera_vertex_z[k], camera_vertex_z[l]); + return; + } + if (i1 == 3) { + int k1 = faceDrawType[i] >> 2; + int i2 = textures_face_a[k1]; + int k2 = textures_face_b[k1]; + int i3 = textures_face_c[k1]; + Rasterizer3D.drawTexturedTriangle(projected_vertex_y[j], projected_vertex_y[k], + projected_vertex_y[l], projected_vertex_x[j], projected_vertex_x[k], + projected_vertex_x[l], faceHslA[i], faceHslA[i], + faceHslA[i], anIntArray1668[i2], anIntArray1668[k2], + anIntArray1668[i3], camera_vertex_y[i2], camera_vertex_y[k2], + camera_vertex_y[i3], camera_vertex_x[i2], camera_vertex_x[k2], + camera_vertex_x[i3], triangleColours[i], camera_vertex_z[j], camera_vertex_z[k], camera_vertex_z[l]); + } + } + + private final void method485(int i) { + if (triangleColours != null) + if (triangleColours[i] == 65535) + return; + int j = Rasterizer3D.originViewX; + int k = Rasterizer3D.originViewY; + int l = 0; + int i1 = facePointA[i]; + int j1 = facePointB[i]; + int k1 = facePointC[i]; + int l1 = camera_vertex_x[i1]; + int i2 = camera_vertex_x[j1]; + int j2 = camera_vertex_x[k1]; + + if (l1 >= 50) { + anIntArray1678[l] = projected_vertex_x[i1]; + anIntArray1679[l] = projected_vertex_y[i1]; + anIntArray1680[l++] = faceHslA[i]; + } else { + int k2 = anIntArray1668[i1]; + int k3 = camera_vertex_y[i1]; + int k4 = faceHslA[i]; + if (j2 >= 50) { + int k5 = (50 - l1) * modelIntArray4[j2 - l1]; + anIntArray1678[l] = j + + (k2 + ((anIntArray1668[k1] - k2) * k5 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1679[l] = k + + (k3 + ((camera_vertex_y[k1] - k3) * k5 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1680[l++] = k4 + + ((faceHslC[i] - k4) * k5 >> 16); + } + if (i2 >= 50) { + int l5 = (50 - l1) * modelIntArray4[i2 - l1]; + anIntArray1678[l] = j + + (k2 + ((anIntArray1668[j1] - k2) * l5 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1679[l] = k + + (k3 + ((camera_vertex_y[j1] - k3) * l5 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1680[l++] = k4 + + ((faceHslB[i] - k4) * l5 >> 16); + } + } + if (i2 >= 50) { + anIntArray1678[l] = projected_vertex_x[j1]; + anIntArray1679[l] = projected_vertex_y[j1]; + anIntArray1680[l++] = faceHslB[i]; + } else { + int l2 = anIntArray1668[j1]; + int l3 = camera_vertex_y[j1]; + int l4 = faceHslB[i]; + if (l1 >= 50) { + int i6 = (50 - i2) * modelIntArray4[l1 - i2]; + anIntArray1678[l] = j + + (l2 + ((anIntArray1668[i1] - l2) * i6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1679[l] = k + + (l3 + ((camera_vertex_y[i1] - l3) * i6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1680[l++] = l4 + + ((faceHslA[i] - l4) * i6 >> 16); + } + if (j2 >= 50) { + int j6 = (50 - i2) * modelIntArray4[j2 - i2]; + anIntArray1678[l] = j + + (l2 + ((anIntArray1668[k1] - l2) * j6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1679[l] = k + + (l3 + ((camera_vertex_y[k1] - l3) * j6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1680[l++] = l4 + + ((faceHslC[i] - l4) * j6 >> 16); + } + } + if (j2 >= 50) { + anIntArray1678[l] = projected_vertex_x[k1]; + anIntArray1679[l] = projected_vertex_y[k1]; + anIntArray1680[l++] = faceHslC[i]; + } else { + int i3 = anIntArray1668[k1]; + int i4 = camera_vertex_y[k1]; + int i5 = faceHslC[i]; + if (i2 >= 50) { + int k6 = (50 - j2) * modelIntArray4[i2 - j2]; + anIntArray1678[l] = j + + (i3 + ((anIntArray1668[j1] - i3) * k6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1679[l] = k + + (i4 + ((camera_vertex_y[j1] - i4) * k6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1680[l++] = i5 + + ((faceHslB[i] - i5) * k6 >> 16); + } + if (l1 >= 50) { + int l6 = (50 - j2) * modelIntArray4[l1 - j2]; + anIntArray1678[l] = j + + (i3 + ((anIntArray1668[i1] - i3) * l6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1679[l] = k + + (i4 + ((camera_vertex_y[i1] - i4) * l6 >> 16) << SceneGraph.viewDistance) + / 50; + anIntArray1680[l++] = i5 + + ((faceHslA[i] - i5) * l6 >> 16); + } + } + int j3 = anIntArray1678[0]; + int j4 = anIntArray1678[1]; + int j5 = anIntArray1678[2]; + int i7 = anIntArray1679[0]; + int j7 = anIntArray1679[1]; + int k7 = anIntArray1679[2]; + if ((j3 - j4) * (k7 - j7) - (i7 - j7) * (j5 - j4) > 0) { + Rasterizer3D.textureOutOfDrawingBounds = false; + if (l == 3) { + if (j3 < 0 || j4 < 0 || j5 < 0 || j3 > Rasterizer2D.lastX + || j4 > Rasterizer2D.lastX || j5 > Rasterizer2D.lastX) + Rasterizer3D.textureOutOfDrawingBounds = true; + int l7; + if (faceDrawType == null) + l7 = 0; + else + l7 = faceDrawType[i] & 3; + if (l7 == 0) + Rasterizer3D.drawShadedTriangle(i7, j7, k7, j3, j4, j5, + anIntArray1680[0], anIntArray1680[1], + anIntArray1680[2], -1f, -1f, -1f); + else if (l7 == 1) + Rasterizer3D.drawFlatTriangle(i7, j7, k7, j3, j4, j5, + modelIntArray3[faceHslA[i]], -1f, -1f, -1f); + else if (l7 == 2) { + int j8 = faceDrawType[i] >> 2; + int k9 = textures_face_a[j8]; + int k10 = textures_face_b[j8]; + int k11 = textures_face_c[j8]; + Rasterizer3D.drawTexturedTriangle(i7, j7, k7, j3, j4, j5, + anIntArray1680[0], anIntArray1680[1], + anIntArray1680[2], anIntArray1668[k9], + anIntArray1668[k10], anIntArray1668[k11], + camera_vertex_y[k9], camera_vertex_y[k10], + camera_vertex_y[k11], camera_vertex_x[k9], + camera_vertex_x[k10], camera_vertex_x[k11], + triangleColours[i], camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + } else if (l7 == 3) { + int k8 = faceDrawType[i] >> 2; + int l9 = textures_face_a[k8]; + int l10 = textures_face_b[k8]; + int l11 = textures_face_c[k8]; + Rasterizer3D.drawTexturedTriangle(i7, j7, k7, j3, j4, j5, + faceHslA[i], faceHslA[i], + faceHslA[i], anIntArray1668[l9], + anIntArray1668[l10], anIntArray1668[l11], + camera_vertex_y[l9], camera_vertex_y[l10], + camera_vertex_y[l11], camera_vertex_x[l9], + camera_vertex_x[l10], camera_vertex_x[l11], + triangleColours[i], camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + } + } + if (l == 4) { + if (j3 < 0 || j4 < 0 || j5 < 0 || j3 > Rasterizer2D.lastX + || j4 > Rasterizer2D.lastX || j5 > Rasterizer2D.lastX + || anIntArray1678[3] < 0 + || anIntArray1678[3] > Rasterizer2D.lastX) + Rasterizer3D.textureOutOfDrawingBounds = true; + int i8; + if (faceDrawType == null) + i8 = 0; + else + i8 = faceDrawType[i] & 3; + if (i8 == 0) { + Rasterizer3D.drawShadedTriangle(i7, j7, k7, j3, j4, j5, + anIntArray1680[0], anIntArray1680[1], + anIntArray1680[2], -1f, -1f, -1f); + Rasterizer3D.drawShadedTriangle(i7, k7, anIntArray1679[3], j3, j5, + anIntArray1678[3], anIntArray1680[0], + anIntArray1680[2], anIntArray1680[3], camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + return; + } + if (i8 == 1) { + int l8 = modelIntArray3[faceHslA[i]]; + Rasterizer3D.drawFlatTriangle(i7, j7, k7, j3, j4, j5, l8, -1f, -1f, -1f); + Rasterizer3D.drawFlatTriangle(i7, k7, anIntArray1679[3], j3, j5, anIntArray1678[3], l8, camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + return; + } + if (i8 == 2) { + int i9 = faceDrawType[i] >> 2; + int i10 = textures_face_a[i9]; + int i11 = textures_face_b[i9]; + int i12 = textures_face_c[i9]; + Rasterizer3D.drawTexturedTriangle(i7, j7, k7, j3, j4, j5, + anIntArray1680[0], anIntArray1680[1], + anIntArray1680[2], anIntArray1668[i10], + anIntArray1668[i11], anIntArray1668[i12], + camera_vertex_y[i10], camera_vertex_y[i11], + camera_vertex_y[i12], camera_vertex_x[i10], + camera_vertex_x[i11], camera_vertex_x[i12], + triangleColours[i], camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + Rasterizer3D.drawTexturedTriangle(i7, k7, anIntArray1679[3], j3, j5, + anIntArray1678[3], anIntArray1680[0], + anIntArray1680[2], anIntArray1680[3], + anIntArray1668[i10], anIntArray1668[i11], + anIntArray1668[i12], camera_vertex_y[i10], + camera_vertex_y[i11], camera_vertex_y[i12], + camera_vertex_x[i10], camera_vertex_x[i11], + camera_vertex_x[i12], triangleColours[i], camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + return; + } + if (i8 == 3) { + int j9 = faceDrawType[i] >> 2; + int j10 = textures_face_a[j9]; + int j11 = textures_face_b[j9]; + int j12 = textures_face_c[j9]; + Rasterizer3D.drawTexturedTriangle(i7, j7, k7, j3, j4, j5, + faceHslA[i], faceHslA[i], + faceHslA[i], anIntArray1668[j10], + anIntArray1668[j11], anIntArray1668[j12], + camera_vertex_y[j10], camera_vertex_y[j11], + camera_vertex_y[j12], camera_vertex_x[j10], + camera_vertex_x[j11], camera_vertex_x[j12], + triangleColours[i], camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + Rasterizer3D.drawTexturedTriangle(i7, k7, anIntArray1679[3], j3, j5, + anIntArray1678[3], faceHslA[i], + faceHslA[i], faceHslA[i], + anIntArray1668[j10], anIntArray1668[j11], + anIntArray1668[j12], camera_vertex_y[j10], + camera_vertex_y[j11], camera_vertex_y[j12], + camera_vertex_x[j10], camera_vertex_x[j11], + camera_vertex_x[j12], triangleColours[i], camera_vertex_z[i1], camera_vertex_z[j1], camera_vertex_z[k1]); + } + } + } + } + + private final boolean method486(int i, int j, int k, int l, int i1, int j1, + int k1, int l1) { + if (j < k && j < l && j < i1) + return false; + if (j > k && j > l && j > i1) + return false; + if (i < j1 && i < k1 && i < l1) + return false; + return i <= j1 || i <= k1 || i <= l1; + } + + public void convertTexturesTo317(short[] textureIds, int[] texa, int[] texb, int[] texc, boolean osrs) { + int set = 0; + int set2 = 0; + int max = 50; + if(textureIds != null) { + textures_face_a = new int[numTriangles]; + textures_face_b = new int[numTriangles]; + textures_face_c = new int[numTriangles]; + + for(int i = 0; i < numTriangles; i++) { + if(textureIds[i] == -1 && faceDrawType[i] == 2) { + triangleColours[i] = 65535; + faceDrawType[i] = 0; + } + if(textureIds[i] >= max || textureIds[i] < 0 || textureIds[i] == 39) { + faceDrawType[i] = 0; + continue; + } + faceDrawType[i] = 2+set2; + set2 += 4; + int a = facePointA[i]; + int b = facePointB[i]; + int c = facePointC[i]; + triangleColours[i] = textureIds[i]; + + int texture_type = -1; + if(texture_coordinates != null) { + texture_type = texture_coordinates[i] & 0xff; + if(texture_type != 0xff) + if(texa[texture_type] >= camera_vertex_x.length || texb[texture_type] >= camera_vertex_y.length + || texc[texture_type] >= camera_vertex_z.length) + texture_type = -1; + } + if(texture_type == 0xff) + texture_type = -1; + + textures_face_a[set] = texture_type == -1 ? a : texa[texture_type]; + textures_face_b[set] = texture_type == -1 ? b : texb[texture_type]; + textures_face_c[set++] = texture_type == -1 ? c : texc[texture_type]; + + } + numberOfTexturesFaces = set; + } + } + + public void retexture(int i, int j, int tex) { + if (tex == -1) { + for (int k = 0; k < numTriangles; k++) + if (triangleColours[k] == i) + triangleColours[k] = j; + } else { + numberOfTexturesFaces = numTriangles; + int set2 = 0; + if (faceDrawType == null) + faceDrawType = new int[numTriangles]; + if (triangleColours == null) + triangleColours = new int[numTriangles]; + textures_face_a = new int[numTriangles]; + textures_face_b = new int[numTriangles]; + textures_face_c = new int[numTriangles]; + for (int i3 = 0; i3 < numTriangles; i3++) { + if (triangleColours[i3] != 0) { + triangleColours[i3] = tex; + faceDrawType[i3] = 3 + set2; + set2 += 4; + textures_face_a[i3] = facePointA[i3]; + textures_face_b[i3] = facePointB[i3]; + textures_face_c[i3] = facePointC[i3]; + } + } + } + } + + private byte[] texture_coordinates; + private boolean aBoolean1618; + public static int anInt1620; + public static Model EMPTY_MODEL = new Model(true); + private static int anIntArray1622[] = new int[2000]; + private static int anIntArray1623[] = new int[2000]; + private static int anIntArray1624[] = new int[2000]; + private static int anIntArray1625[] = new int[2000]; + public int numVertices; + public int vertexX[]; + public int vertexY[]; + public int vertexZ[]; + public int numTriangles; + public int facePointA[]; + public int facePointB[]; + public int facePointC[]; + public int faceHslA[]; + public int faceHslB[]; + public int faceHslC[]; + public int faceDrawType[]; + public int face_render_priorities[]; + public int face_alpha[]; + public int triangleColours[]; + public int face_priority; + public int numberOfTexturesFaces; + public int textures_face_a[]; + public int textures_face_b[]; + public int textures_face_c[]; + public int minimumXVertex; + public int maximumXVertex; + public int maximumZVertex; + public int minimumZVertex; + public int maxVertexDistanceXZPlane; + public int maximumYVertex; + public int maxRenderDepth; + public int diagonal3DAboveOrigin; + public int itemDropHeight; + public int vertexVSkin[]; + public int triangleTSkin[]; + public int vertexGroups[][]; + public int faceGroups[][]; + public boolean fits_on_single_square; + public VertexNormal alsoVertexNormals[]; + static ModelHeader aClass21Array1661[]; + static Provider resourceProvider; + static boolean hasAnEdgeToRestrict[] = new boolean[8000]; + static boolean outOfReach[] = new boolean[8000]; + static int projected_vertex_x[] = new int[8000]; + static int projected_vertex_y[] = new int[8000]; + static int projected_vertex_z[] = new int[8000]; + static int anIntArray1668[] = new int[8000]; + static int camera_vertex_y[] = new int[8000]; + static int camera_vertex_x[] = new int[8000]; + static int camera_vertex_z[] = new int[8000]; + static int depthListIndices[] = new int[1500]; + static int faceLists[][] = new int[1500][512]; + static int anIntArray1673[] = new int[12]; + static int anIntArrayArray1674[][] = new int[12][2000]; + static int anIntArray1675[] = new int[2000]; + static int anIntArray1676[] = new int[2000]; + static int anIntArray1677[] = new int[12]; + static int anIntArray1678[] = new int[10]; + static int anIntArray1679[] = new int[10]; + static int anIntArray1680[] = new int[10]; + static int xAnimOffset; + static int yAnimOffset; + static int zAnimOffset; + public static boolean aBoolean1684; + public static int anInt1685; + public static int anInt1686; + public static int anInt1687; + public static int anIntArray1688[] = new int[1000]; + public static int SINE[]; + public static int COSINE[]; + static int modelIntArray3[]; + static int modelIntArray4[]; + + static { + SINE = Rasterizer3D.anIntArray1470; + COSINE = Rasterizer3D.COSINE; + modelIntArray3 = Rasterizer3D.hslToRgb; + modelIntArray4 = Rasterizer3D.anIntArray1469; + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/entity/model/ModelHeader.java b/src/main/java/org/rebotted/entity/model/ModelHeader.java new file mode 100644 index 0000000..f4e083a --- /dev/null +++ b/src/main/java/org/rebotted/entity/model/ModelHeader.java @@ -0,0 +1,27 @@ +package org.rebotted.entity.model; + +final class ModelHeader +{ + + public ModelHeader() + { + } + + public byte aByteArray368[]; + public int anInt369; + public int anInt370; + public int anInt371; + public int anInt372; + public int anInt373; + public int anInt374; + public int anInt375; + public int anInt376; + public int anInt377; + public int anInt378; + public int anInt379; + public int anInt380; + public int anInt381; + public int anInt382; + public int anInt383; + public int anInt384; +} diff --git a/src/main/java/org/rebotted/entity/model/VertexNormal.java b/src/main/java/org/rebotted/entity/model/VertexNormal.java new file mode 100644 index 0000000..51eb9f2 --- /dev/null +++ b/src/main/java/org/rebotted/entity/model/VertexNormal.java @@ -0,0 +1,10 @@ +package org.rebotted.entity.model; + +public final class VertexNormal { + + public int normalX; + public int normalY; + public int normalZ; + public int magnitude; + +} diff --git a/src/main/java/org/rebotted/io/Buffer.java b/src/main/java/org/rebotted/io/Buffer.java new file mode 100644 index 0000000..48ef59d --- /dev/null +++ b/src/main/java/org/rebotted/io/Buffer.java @@ -0,0 +1,386 @@ +package org.rebotted.io; + +import java.math.BigInteger; + +import org.rebotted.Configuration; +import org.rebotted.collection.Cacheable; +import org.rebotted.net.IsaacCipher; +import org.rebotted.sign.SignLink; + +public final class Buffer extends Cacheable { + + public byte payload[]; + public int currentPosition; + public int bitPosition; + private static final int[] BIT_MASKS = { 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 IsaacCipher encryption; + + public static Buffer create() { + Buffer buffer = new Buffer(); + buffer.currentPosition = 0; + buffer.payload = new byte[5000]; + return buffer; + } + + public final int readUTriByte(int i) { + currentPosition += 3; + return (0xff & payload[currentPosition - 3] << 16) + + (0xff & payload[currentPosition - 2] << 8) + + (0xff & payload[currentPosition - 1]); + } + + private Buffer() {} + + public Buffer(byte[] payload) { + this.payload = payload; + currentPosition = 0; + } + + public int readUSmart2() { + int baseVal = 0; + int lastVal = 0; + while ((lastVal = readUSmart()) == 32767) { + baseVal += 32767; + } + return baseVal + lastVal; + } + + public String readNewString() { + int i = currentPosition; + while (payload[currentPosition++] != 0) + ; + return new String(payload, i, currentPosition - i - 1); + } + + public void writeOpcode(int opcode) { + payload[currentPosition++] = (byte) (opcode + encryption.getNextKey()); + } + + public void writeByte(int value) { + payload[currentPosition++] = (byte) value; + } + + public void writeShort(int value) { + payload[currentPosition++] = (byte) (value >> 8); + payload[currentPosition++] = (byte) value; + } + + public void writeTriByte(int value) { + payload[currentPosition++] = (byte) (value >> 16); + payload[currentPosition++] = (byte) (value >> 8); + payload[currentPosition++] = (byte) value; + } + + public void writeInt(int value) { + payload[currentPosition++] = (byte) (value >> 24); + payload[currentPosition++] = (byte) (value >> 16); + payload[currentPosition++] = (byte) (value >> 8); + payload[currentPosition++] = (byte) value; + } + + public void writeLEInt(int value) { + payload[currentPosition++] = (byte) value; + payload[currentPosition++] = (byte) (value >> 8); + payload[currentPosition++] = (byte) (value >> 16); + payload[currentPosition++] = (byte) (value >> 24); + } + + public void writeLong(long value) { + try { + payload[currentPosition++] = (byte) (int) (value >> 56); + payload[currentPosition++] = (byte) (int) (value >> 48); + payload[currentPosition++] = (byte) (int) (value >> 40); + payload[currentPosition++] = (byte) (int) (value >> 32); + payload[currentPosition++] = (byte) (int) (value >> 24); + payload[currentPosition++] = (byte) (int) (value >> 16); + payload[currentPosition++] = (byte) (int) (value >> 8); + payload[currentPosition++] = (byte) (int) value; + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("14395, " + 5 + ", " + value + ", " + + runtimeexception.toString()); + throw new RuntimeException(); + } + } + + public void writeString(String text) { + System.arraycopy(text.getBytes(), 0, payload, currentPosition, + text.length()); + currentPosition += text.length(); + payload[currentPosition++] = 10; + } + + public void writeBytes(byte data[], int offset, int length) { + for (int index = length; index < length + offset; index++) + payload[currentPosition++] = data[index]; + } + + public void writeBytes(int value) { + payload[currentPosition - value - 1] = (byte) value; + } + + public int readUnsignedByte() { + return payload[currentPosition++] & 0xff; + } + + public int readShort2() { + currentPosition += 2; + int i = ((payload[currentPosition - 2] & 0xff) << 8) + (payload[currentPosition - 1] & 0xff); + if(i > 32767) + i -= 65537; + return i; + } + public byte readSignedByte() { + return payload[currentPosition++]; + } + + public int readUShort() { + currentPosition += 2; + return ((payload[currentPosition - 2] & 0xff) << 8) + + (payload[currentPosition - 1] & 0xff); + } + + public int readShort() { + currentPosition += 2; + int value = ((payload[currentPosition - 2] & 0xff) << 8) + + (payload[currentPosition - 1] & 0xff); + + if (value > 32767) { + value -= 0x10000; + } + return value; + } + + public int readTriByte() { + currentPosition += 3; + return ((payload[currentPosition - 3] & 0xff) << 16) + + ((payload[currentPosition - 2] & 0xff) << 8) + + (payload[currentPosition - 1] & 0xff); + } + + public int readInt() { + currentPosition += 4; + return ((payload[currentPosition - 4] & 0xff) << 24) + + ((payload[currentPosition - 3] & 0xff) << 16) + + ((payload[currentPosition - 2] & 0xff) << 8) + + (payload[currentPosition - 1] & 0xff); + } + + public int readDWord() { + currentPosition += 4; + return ((payload[currentPosition - 4] & 0xff) << 24) + ((payload[currentPosition - 3] & 0xff) << 16) + ((payload[currentPosition - 2] & 0xff) << 8) + (payload[currentPosition - 1] & 0xff); + } + + + public long readLong() { + long msi = (long) readInt() & 0xffffffffL; + long lsi = (long) readInt() & 0xffffffffL; + return (msi << 32) + lsi; + } + + public String readString() { + int index = currentPosition; + while (payload[currentPosition++] != 10) + ; + return new String(payload, index, currentPosition - index - 1); + } + + public byte[] readBytes() { + int index = currentPosition; + while (payload[currentPosition++] != 10) + ; + byte data[] = new byte[currentPosition - index - 1]; + System.arraycopy(payload, index, data, index - index, currentPosition - 1 - index); + return data; + } + + public void readBytes(int offset, int length, byte data[]) { + for (int index = length; index < length + offset; index++) + data[index] = payload[currentPosition++]; + } + + public void initBitAccess() { + bitPosition = currentPosition * 8; + } + + public int readBits(int amount) { + int byteOffset = bitPosition >> 3; + int bitOffset = 8 - (bitPosition & 7); + int value = 0; + bitPosition += amount; + for (; amount > bitOffset; bitOffset = 8) { + value += (payload[byteOffset++] & BIT_MASKS[bitOffset]) << amount + - bitOffset; + amount -= bitOffset; + } + if (amount == bitOffset) + value += payload[byteOffset] & BIT_MASKS[bitOffset]; + else + value += payload[byteOffset] >> bitOffset - amount + & BIT_MASKS[amount]; + return value; + } + + public void disableBitAccess() { + currentPosition = (bitPosition + 7) / 8; + } + + public int readSmart() { + int value = payload[currentPosition] & 0xff; + if (value < 128) + return readUnsignedByte() - 64; + else + return readUShort() - 49152; + } + + public int readUSmart() { + int value = payload[currentPosition] & 0xff; + if (value < 128) + return readUnsignedByte(); + else + return readUShort() - 32768; + } + + public void encodeRSA(BigInteger exponent, BigInteger modulus) { + int length = currentPosition; + currentPosition = 0; + byte buffer[] = new byte[length]; + readBytes(length, 0, buffer); + + byte rsa[] = buffer; + + if (Configuration.ENABLE_RSA) { + rsa = new BigInteger(buffer).modPow(exponent, modulus) + .toByteArray(); + } + + currentPosition = 0; + writeByte(rsa.length); + writeBytes(rsa, rsa.length, 0); + } + + public void writeNegatedByte(int value) { + payload[currentPosition++] = (byte) (-value); + } + + public void writeByteS(int value) { + payload[currentPosition++] = (byte) (128 - value); + } + + public int readUByteA() { + return payload[currentPosition++] - 128 & 0xff; + } + + public int readNegUByte() { + return -payload[currentPosition++] & 0xff; + } + + public int readUByteS() { + return 128 - payload[currentPosition++] & 0xff; + } + + public byte readNegByte() { + return (byte) -payload[currentPosition++]; + } + + public byte readByteS() { + return (byte) (128 - payload[currentPosition++]); + } + + public void writeLEShort(int value) { + payload[currentPosition++] = (byte) value; + payload[currentPosition++] = (byte) (value >> 8); + } + + public void writeShortA(int value) { + payload[currentPosition++] = (byte) (value >> 8); + payload[currentPosition++] = (byte) (value + 128); + } + + public void writeLEShortA(int value) { + payload[currentPosition++] = (byte) (value + 128); + payload[currentPosition++] = (byte) (value >> 8); + } + + public int readLEUShort() { + currentPosition += 2; + return ((payload[currentPosition - 1] & 0xff) << 8) + + (payload[currentPosition - 2] & 0xff); + } + + public int readUShortA() { + currentPosition += 2; + return ((payload[currentPosition - 2] & 0xff) << 8) + + (payload[currentPosition - 1] - 128 & 0xff); + } + + public int readLEUShortA() { + currentPosition += 2; + return ((payload[currentPosition - 1] & 0xff) << 8) + + (payload[currentPosition - 2] - 128 & 0xff); + } + + public int readLEShort() { + currentPosition += 2; + int value = ((payload[currentPosition - 1] & 0xff) << 8) + + (payload[currentPosition - 2] & 0xff); + + if (value > 32767) { + value -= 0x10000; + } + return value; + } + + public int readLEShortA() { + currentPosition += 2; + int value = ((payload[currentPosition - 1] & 0xff) << 8) + + (payload[currentPosition - 2] - 128 & 0xff); + if (value > 32767) + value -= 0x10000; + return value; + } + + public int readSignedWord() { + currentPosition += 2; + int i = ((payload[currentPosition - 2] & 0xff) << 8) + (payload[currentPosition - 1] & 0xff); + if (i > 32767) { + i -= 0x10000; + } + return i; + } + + public int readMEInt() { // V1 + currentPosition += 4; + return ((payload[currentPosition - 2] & 0xff) << 24) + + ((payload[currentPosition - 1] & 0xff) << 16) + + ((payload[currentPosition - 4] & 0xff) << 8) + + (payload[currentPosition - 3] & 0xff); + } + + public int readIMEInt() { // V2 + currentPosition += 4; + return ((payload[currentPosition - 3] & 0xff) << 24) + + ((payload[currentPosition - 4] & 0xff) << 16) + + ((payload[currentPosition - 1] & 0xff) << 8) + + (payload[currentPosition - 2] & 0xff); + } + + public void writeReverseDataA(byte data[], int length, int offset) { + for (int index = (length + offset) - 1; index >= length; index--) { + payload[currentPosition++] = (byte) (data[index] + 128); + } + + } + + public void readReverseData(byte data[], int offset, int length) { + for (int index = (length + offset) - 1; index >= length; index--) { + data[index] = payload[currentPosition++]; + } + + } + +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/net/BufferedConnection.java b/src/main/java/org/rebotted/net/BufferedConnection.java new file mode 100644 index 0000000..cc8c674 --- /dev/null +++ b/src/main/java/org/rebotted/net/BufferedConnection.java @@ -0,0 +1,152 @@ +package org.rebotted.net; + +import java.io.*; +import java.net.Socket; + +import org.rebotted.GameApplet; + +public final class BufferedConnection implements Runnable { + + public BufferedConnection(GameApplet RSApplet_, Socket socket1) + throws IOException { + closed = false; + isWriter = false; + hasIOError = false; + rsApplet = RSApplet_; + socket = socket1; + socket.setSoTimeout(30000); + socket.setTcpNoDelay(true); + inputStream = socket.getInputStream(); + outputStream = socket.getOutputStream(); + } + + public void close() { + closed = true; + try { + if (inputStream != null) + inputStream.close(); + if (outputStream != null) + outputStream.close(); + if (socket != null) + socket.close(); + } catch (IOException _ex) { + System.out.println("Error closing stream"); + } + isWriter = false; + synchronized (this) { + notify(); + } + buffer = null; + } + + public int read() throws IOException { + if (closed) + return 0; + else + return inputStream.read(); + } + + public int available() throws IOException { + if (closed) + return 0; + else + return inputStream.available(); + } + + public void flushInputStream(byte abyte0[], int j) throws IOException { + int i = 0;// was parameter + if (closed) + return; + int k; + for (; j > 0; j -= k) { + k = inputStream.read(abyte0, i, j); + if (k <= 0) + throw new IOException("EOF"); + i += k; + } + + } + + public void queueBytes(int i, byte abyte0[]) throws IOException { + if (closed) + return; + if (hasIOError) { + hasIOError = false; + throw new IOException("Error in writer thread"); + } + if (buffer == null) + buffer = new byte[5000]; + synchronized (this) { + for (int l = 0; l < i; l++) { + buffer[buffIndex] = abyte0[l]; + buffIndex = (buffIndex + 1) % 5000; + if (buffIndex == (writeIndex + 4900) % 5000) + throw new IOException("buffer overflow"); + } + + if (!isWriter) { + isWriter = true; + rsApplet.startRunnable(this, 3); + } + notify(); + } + } + + public void run() { + while (isWriter) { + int i; + int j; + synchronized (this) { + if (buffIndex == writeIndex) + try { + wait(); + } catch (InterruptedException _ex) { + } + if (!isWriter) + return; + j = writeIndex; + if (buffIndex >= writeIndex) + i = buffIndex - writeIndex; + else + i = 5000 - writeIndex; + } + if (i > 0) { + try { + outputStream.write(buffer, j, i); + } catch (IOException _ex) { + hasIOError = true; + } + writeIndex = (writeIndex + i) % 5000; + try { + if (buffIndex == writeIndex) + outputStream.flush(); + } catch (IOException _ex) { + hasIOError = true; + } + } + } + } + + public void printDebug() { + System.out.println("dummy:" + closed); + System.out.println("tcycl:" + writeIndex); + System.out.println("tnum:" + buffIndex); + System.out.println("writer:" + isWriter); + System.out.println("ioerror:" + hasIOError); + try { + System.out.println("available:" + available()); + } catch (IOException _ex) { + } + } + + private InputStream inputStream; + private OutputStream outputStream; + private final Socket socket; + private boolean closed; + private final GameApplet rsApplet; + private byte[] buffer; + private int writeIndex; + private int buffIndex; + private boolean isWriter; + private boolean hasIOError; +} diff --git a/src/main/java/org/rebotted/net/IsaacCipher.java b/src/main/java/org/rebotted/net/IsaacCipher.java new file mode 100644 index 0000000..9fcf8af --- /dev/null +++ b/src/main/java/org/rebotted/net/IsaacCipher.java @@ -0,0 +1,172 @@ +package org.rebotted.net; + +public final class IsaacCipher { + + public IsaacCipher(int seed[]) { + memory = new int[256]; + results = new int[256]; + System.arraycopy(seed, 0, results, 0, seed.length); + initializeKeySet(); + } + + public int getNextKey() { + if (count-- == 0) { + isaac(); + count = 255; + } + return results[count]; + } + + private void isaac() { + lastResult += ++counter; + for (int i = 0; i < 256; i++) { + int j = memory[i]; + if ((i & 3) == 0) + accumulator ^= accumulator << 13; + else if ((i & 3) == 1) + accumulator ^= accumulator >>> 6; + else if ((i & 3) == 2) + accumulator ^= accumulator << 2; + else if ((i & 3) == 3) + accumulator ^= accumulator >>> 16; + accumulator += memory[i + 128 & 0xff]; + int k; + memory[i] = k = memory[(j & 0x3fc) >> 2] + accumulator + lastResult; + results[i] = lastResult = memory[(k >> 8 & 0x3fc) >> 2] + j; + } + + } + + private void initializeKeySet() { + 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; + } + + private int count; + private final int[] results; + private final int[] memory; + private int accumulator; + private int lastResult; + private int counter; +} diff --git a/src/main/java/org/rebotted/net/requester/Provider.java b/src/main/java/org/rebotted/net/requester/Provider.java new file mode 100644 index 0000000..dfb5c79 --- /dev/null +++ b/src/main/java/org/rebotted/net/requester/Provider.java @@ -0,0 +1,6 @@ +package org.rebotted.net.requester; + +public abstract class Provider { + + public abstract void provide(int file); +} diff --git a/src/main/java/org/rebotted/net/requester/Resource.java b/src/main/java/org/rebotted/net/requester/Resource.java new file mode 100644 index 0000000..5e863f6 --- /dev/null +++ b/src/main/java/org/rebotted/net/requester/Resource.java @@ -0,0 +1,16 @@ +package org.rebotted.net.requester; + +import org.rebotted.collection.Cacheable; + +public final class Resource extends Cacheable { + + public int dataType; + public byte buffer[]; + public int ID; + boolean incomplete; + int loopCycle; + + public Resource() { + incomplete = true; + } +} diff --git a/src/main/java/org/rebotted/net/requester/ResourceProvider.java b/src/main/java/org/rebotted/net/requester/ResourceProvider.java new file mode 100644 index 0000000..4edb8f2 --- /dev/null +++ b/src/main/java/org/rebotted/net/requester/ResourceProvider.java @@ -0,0 +1,625 @@ +package org.rebotted.net.requester; +import java.io.*; +import java.net.Socket; +import java.util.zip.GZIPInputStream; + +import org.rebotted.Client; +import org.rebotted.cache.FileArchive; +import org.rebotted.cache.FileStore; +import org.rebotted.collection.Deque; +import org.rebotted.collection.Queue; +import org.rebotted.io.Buffer; +import org.rebotted.sign.SignLink; +import org.rebotted.util.CacheUtils; + +public final class ResourceProvider extends Provider implements Runnable { + + private int totalFiles; + private final Deque requested; + private int maximumPriority; + public String loadingMessage; + private int deadTime; + private long lastRequestTime; + private int[] landscapes; + private final byte[] payload; + public int tick; + private final byte[][] fileStatus; + private Client clientInstance; + private final Deque extras; + private int completedSize; + private int remainingData; + private int[] musicPriorities; + public int errors; + private int[] mapFiles; + private int filesLoaded; + private boolean running; + private OutputStream outputStream; + private int[] membersArea; + private boolean expectingData; + private final Deque complete; + private final byte[] gzipInputBuffer; + private int[] anIntArray1360; + private final Queue requests; + private InputStream inputStream; + private Socket socket; + private final int[][] versions; + private int uncompletedCount; + private int completedCount; + private final Deque unrequested; + private Resource current; + private final Deque mandatoryRequests; + private int[] areas; + private byte[] modelIndices; + private int idleTime; + + public ResourceProvider() { + requested = new Deque(); + loadingMessage = ""; + payload = new byte[500]; + fileStatus = new byte[4][]; + extras = new Deque(); + running = true; + expectingData = false; + complete = new Deque(); + gzipInputBuffer = new byte[0x71868]; + requests = new Queue(); + versions = new int[4][]; + unrequested = new Deque(); + mandatoryRequests = new Deque(); + } + + private void respond() { + try { + int available = inputStream.available(); + if (remainingData == 0 && available >= 6) { + expectingData = true; + for (int skip = 0; skip < 6; skip += inputStream.read(payload, skip, 6 - skip)) + ; + int type = payload[0] & 0xff; + int file = ((payload[1] & 0xff) << 8) + (payload[2] & 0xff); + int length = ((payload[3] & 0xff) << 8) + (payload[4] & 0xff); + int sector = payload[5] & 0xff; + current = null; + for (Resource resource = (Resource) requested.reverseGetFirst(); resource != null; resource = (Resource) requested.reverseGetNext()) { + if (resource.dataType == type && resource.ID == file) + current = resource; + if (current != null) + resource.loopCycle = 0; + } + + if (current != null) { + idleTime = 0; + if (length == 0) { + SignLink.reporterror("Rej: " + type + "," + file); + current.buffer = null; + if (current.incomplete) + synchronized (complete) { + complete.insertHead(current); + } else { + current.unlink(); + } + current = null; + } else { + if (current.buffer == null && sector == 0) + current.buffer = new byte[length]; + if (current.buffer == null && sector != 0) + throw new IOException("missing start of file"); + } + } + completedSize = sector * 500; + remainingData = 500; + if (remainingData > length - sector * 500) + remainingData = length - sector * 500; + } + if (remainingData > 0 && available >= remainingData) { + expectingData = true; + byte data[] = payload; + int read = 0; + if (current != null) { + data = current.buffer; + read = completedSize; + } + for (int skip = 0; skip < remainingData; skip += inputStream.read(data, skip + read, remainingData - skip)); + if (remainingData + completedSize >= data.length && current != null) { + if (clientInstance.indices[0] != null) + clientInstance.indices[current.dataType + 1].writeFile(data.length, data, current.ID); + if (!current.incomplete && current.dataType == 3) { + current.incomplete = true; + current.dataType = 93; + } + if (current.incomplete) + synchronized (complete) { + complete.insertHead(current); + } else { + current.unlink(); + } + } + remainingData = 0; + } + } catch (IOException ex) { + try { + socket.close(); + } catch (Exception _ex) { + _ex.printStackTrace(); + } + socket = null; + inputStream = null; + outputStream = null; + remainingData = 0; + } + } + + public int mapAmount = 0; + + public int[] file_amounts = new int[4]; + + private final String crcNames[] = {"model_crc", "anim_crc", "midi_crc", "map_crc"}; + private final int[][] crcs = new int[crcNames.length][]; + + public void initialize(FileArchive archive, Client client) { + for(int i = 0; i < crcNames.length; i++) { + byte[] crc_file = archive.readFile(crcNames[i]); + int length = 0; + + if(crc_file != null) { + length = crc_file.length / 4; + Buffer crcStream = new Buffer(crc_file); + crcs[i] = new int[length]; + fileStatus[i] = new byte[length]; + for(int ptr = 0; ptr < length; ptr++) { + crcs[i][ptr] = crcStream.readInt(); + } + } + } + + + + byte[] data = archive.readFile("map_index"); + Buffer stream = new Buffer(data); + int j1 = stream.readUShort();//mapData.length / 6; + areas = new int[j1]; + mapFiles = new int[j1]; + landscapes = new int[j1]; + membersArea = new int[j1]; + file_amounts[3] = j1; + for (int i2 = 0; i2 < j1; i2++) { + areas[i2] = stream.readUShort(); + mapFiles[i2] = stream.readUShort(); + landscapes[i2] = stream.readUShort(); + } + + System.out.println("Map Amount: " + file_amounts[3] + ""); + + data = archive.readFile("midi_index"); + stream = new Buffer(data); + j1 = data.length; + file_amounts[2] = j1; + musicPriorities = new int[j1]; + for (int k2 = 0; k2 < j1; k2++) + musicPriorities[k2] = stream.readUnsignedByte(); + System.out.println("Sounds Amount: " + file_amounts[2] + ""); + + + //For some reason, model_index = anim_index and vice versa + data = archive.readFile("model_index"); + file_amounts[1] = data.length; + + data = archive.readFile("anim_index"); + file_amounts[0] = data.length; + System.out.println("Model amount: "+file_amounts[0]); + + clientInstance = client; + running = true; + clientInstance.startRunnable(this, 2); + } + + + public void initialize1(FileArchive archive, Client client) { + byte[] mapData = archive.readFile("map_index"); + Buffer stream2 = new Buffer(mapData); + int j1 = mapData.length / 6; + areas = new int[j1]; + mapFiles = new int[j1]; + landscapes = new int[j1]; + for (int i2 = 0; i2 < j1; i2++) { + areas[i2] = stream2.readUShort(); + mapFiles[i2] = stream2.readUShort(); + landscapes[i2] = stream2.readUShort(); + mapAmount++; + } + System.out.println("Map Amount: " + mapAmount + ""); + mapData = archive.readFile("midi_index"); + stream2 = new Buffer(mapData); + j1 = mapData.length; + musicPriorities = new int[j1]; + for (int k2 = 0; k2 < j1; k2++) + musicPriorities[k2] = stream2.readUnsignedByte(); + + clientInstance = client; + running = true; + clientInstance.startRunnable(this, 2); + } + + public int remaining() { + synchronized (requests) { + return requests.size(); + } + } + + public void disable() { + running = false; + } + + public void preloadMaps(boolean members) { + for (int area = 0; area < areas.length; area++) { + if (members || membersArea[area] != 0) { + requestExtra((byte) 2, 3, landscapes[area]); + requestExtra((byte) 2, 3, mapFiles[area]); + } + } + } + + public int getVersionCount(int index) { + return versions[index].length; + } + + private void request(Resource resource) { + try { + if (socket == null) { + long currentTime = System.currentTimeMillis(); + if (currentTime - lastRequestTime < 4000L) + return; + lastRequestTime = currentTime; + socket = clientInstance.openSocket(43594 + Client.portOffset); + inputStream = socket.getInputStream(); + outputStream = socket.getOutputStream(); + outputStream.write(15); + for (int index = 0; index < 8; index++) + inputStream.read(); + + idleTime = 0; + } + payload[0] = (byte) resource.dataType; + payload[1] = (byte) (resource.ID >> 8); + payload[2] = (byte) resource.ID; + if (resource.incomplete) + payload[3] = 2; + else if (!Client.loggedIn) + payload[3] = 1; + else + payload[3] = 0; + outputStream.write(payload, 0, 4); + deadTime = 0; + errors = -10000; + return; + } catch (IOException ex) { + ex.printStackTrace(); + } + try { + socket.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + socket = null; + inputStream = null; + outputStream = null; + remainingData = 0; + errors++; + } + + public int getAnimCount() { + return anIntArray1360.length; + } + + public int getModelCount() { + return 29191; + } + + @Override + public final void provide(int file) { + provide(0, file); + } + + public void provide(int type, int file) { + synchronized (requests) { + for (Resource resource = (Resource) requests.reverseGetFirst(); resource != null; resource = (Resource) requests.reverseGetNext()) + if (resource.dataType == type && resource.ID == file) + return; + + Resource resource = new Resource(); + resource.dataType = type; + resource.ID = file; + resource.incomplete = true; + synchronized (mandatoryRequests) { + mandatoryRequests.insertHead(resource); + } + requests.insertHead(resource); + } + } + + public int getModelIndex(int i) { + return modelIndices[i] & 0xff; + } + + public void run() { + try { + while (running) { + tick++; + int sleepTime = 20; + if (maximumPriority == 0 && clientInstance.indices[0] != null) + sleepTime = 50; + try { + Thread.sleep(sleepTime); + } catch (Exception ex) { + ex.printStackTrace(); + } + expectingData = true; + for (int index = 0; index < 100; index++) { + if (!expectingData) + break; + expectingData = false; + loadMandatory(); + requestMandatory(); + if (uncompletedCount == 0 && index >= 5) + break; + loadExtra(); + if (inputStream != null) + respond(); + } + + boolean idle = false; + for (Resource resource = (Resource) requested.reverseGetFirst(); resource != null; resource = (Resource) requested.reverseGetNext()) + if (resource.incomplete) { + idle = true; + resource.loopCycle++; + if (resource.loopCycle > 50) { + resource.loopCycle = 0; + request(resource); + } + } + + if (!idle) { + for (Resource resource = (Resource) requested.reverseGetFirst(); resource != null; resource = (Resource) requested.reverseGetNext()) { + idle = true; + resource.loopCycle++; + if (resource.loopCycle > 50) { + resource.loopCycle = 0; + request(resource); + } + } + + } + if (idle) { + idleTime++; + if (idleTime > 750) { + try { + socket.close(); + } catch (Exception _ex) { + } + socket = null; + inputStream = null; + outputStream = null; + remainingData = 0; + } + } else { + idleTime = 0; + loadingMessage = ""; + } + if (Client.loggedIn && socket != null && outputStream != null && (maximumPriority > 0 || clientInstance.indices[0] == null)) { + deadTime++; + if (deadTime > 500) { + deadTime = 0; + payload[0] = 0; + payload[1] = 0; + payload[2] = 0; + payload[3] = 10; + try { + outputStream.write(payload, 0, 4); + } catch (IOException _ex) { + idleTime = 5000; + } + } + } + } + } catch (Exception exception) { + SignLink.reporterror("od_ex " + exception.getMessage()); + } + } + + public void loadExtra(int type, int file) { + if (clientInstance.indices[0] == null){ + return; + } else if (maximumPriority == 0) { + return; + } + Resource resource = new Resource(); + resource.dataType = file; + resource.ID = type; + resource.incomplete = false; + synchronized (extras) { + extras.insertHead(resource); + } + } + + public Resource next() { + Resource resource; + synchronized (complete) { + resource = (Resource) complete.popHead(); + } + if (resource == null) + return null; + synchronized (requests) { + resource.unlinkCacheable(); + } + if (resource.buffer == null) + return resource; + int read = 0; + try { + GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(resource.buffer)); + do { + if (read == gzipInputBuffer.length) + throw new RuntimeException("buffer overflow!"); + int in = gis.read(gzipInputBuffer, read, gzipInputBuffer.length - read); + if (in == -1) + break; + read += in; + } while (true); + } catch (IOException _ex) { + System.out.println("Failed to unzip model [" + resource.ID + "] type = " + resource.dataType); + _ex.printStackTrace(); + return null; + } + resource.buffer = new byte[read]; + System.arraycopy(gzipInputBuffer, 0, resource.buffer, 0, read); + + return resource; + } + + public int resolve(int regionX, int regionY, int type) { + int code = (type << 8) + regionY; + for (int area = 0; area < areas.length; area++) { + if (areas[area] == code) { + if (regionX == 0) { + return mapFiles[area] > 3535 ? -1 : mapFiles[area]; + } else { + return landscapes[area] > 3535 ? -1 : landscapes[area]; + } + } + } + return -1; + } + + public void requestExtra(byte priority, int type, int file) { + if (clientInstance.indices[0] == null) + return; + if (versions[type][file] == 0) + return; + clientInstance.indices[type + 1].decompress(file); + fileStatus[type][file] = priority; + if (priority > maximumPriority) + maximumPriority = priority; + totalFiles++; + } + + public boolean landscapePresent(int landscape) { + for (int index = 0; index < areas.length; index++) + if (landscapes[index] == landscape) + return true; + return false; + } + + private void requestMandatory() { + uncompletedCount = 0; + completedCount = 0; + for (Resource resource = (Resource) requested.reverseGetFirst(); resource != null; resource = (Resource) requested.reverseGetNext()) + if (resource.incomplete) { + uncompletedCount++; + System.out.println("Error: model is incomplete or missing [ type = " + resource.dataType + "] [id = " + resource.ID + "]"); + } else + completedCount++; + + while (uncompletedCount < 10) { + try { + Resource request = (Resource) unrequested.popHead(); + if (request == null) { + break; + } + if (fileStatus[request.dataType][request.ID] != 0) { + filesLoaded++; + } + fileStatus[request.dataType][request.ID] = 0; + requested.insertHead(request); + uncompletedCount++; + request(request); + expectingData = true; + System.out.println("Error: file is missing [ type = " + request.dataType + "] [id = " + request.ID + "]"); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + public void clearExtras() { + synchronized (extras) { + extras.clear(); + } + } + + private void loadMandatory() { + Resource resource; + synchronized (mandatoryRequests) { + resource = (Resource) mandatoryRequests.popHead(); + } + while (resource != null) { + expectingData = true; + byte data[] = null; + if (clientInstance.indices[0] != null) + data = clientInstance.indices[resource.dataType + 1].decompress(resource.ID); + synchronized (mandatoryRequests) { + if (data == null) { + unrequested.insertHead(resource); + } else { + resource.buffer = data; + synchronized (complete) { + complete.insertHead(resource); + } + } + resource = (Resource) mandatoryRequests.popHead(); + } + } + } + + private void loadExtra() { + while (uncompletedCount == 0 && completedCount < 10) { + if (maximumPriority == 0) + break; + Resource resource; + synchronized (extras) { + resource = (Resource) extras.popHead(); + } + while (resource != null) { + if (fileStatus[resource.dataType][resource.ID] != 0) { + fileStatus[resource.dataType][resource.ID] = 0; + requested.insertHead(resource); + request(resource); + expectingData = true; + if (filesLoaded < totalFiles) + filesLoaded++; + loadingMessage = "Loading extra files - " + (filesLoaded * 100) / totalFiles + "%"; + completedCount++; + if (completedCount == 10) + return; + } + synchronized (extras) { + resource = (Resource) extras.popHead(); + } + } + for (int type = 0; type < 4; type++) { + byte data[] = fileStatus[type]; + int size = data.length; + for (int file = 0; file < size; file++) + if (data[file] == maximumPriority) { + data[file] = 0; + Resource newResource = new Resource(); + newResource.dataType = type; + newResource.ID = file; + newResource.incomplete = false; + requested.insertHead(newResource); + request(newResource); + expectingData = true; + if (filesLoaded < totalFiles) + filesLoaded++; + loadingMessage = "Loading extra files - " + (filesLoaded * 100) / totalFiles + "%"; + completedCount++; + if (completedCount == 10) + return; + } + } + maximumPriority--; + } + } + + public boolean highPriorityMusic(int file) { + return musicPriorities[file] == 1; + } +} diff --git a/src/main/java/org/rebotted/scene/AnimableObject.java b/src/main/java/org/rebotted/scene/AnimableObject.java new file mode 100644 index 0000000..245af09 --- /dev/null +++ b/src/main/java/org/rebotted/scene/AnimableObject.java @@ -0,0 +1,89 @@ +package org.rebotted.scene; +import org.rebotted.Configuration; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.anim.Graphic; +import org.rebotted.entity.Renderable; +import org.rebotted.entity.model.Model; + +public final class AnimableObject extends Renderable { + + public final int anInt1560; + public final int anInt1561; + public final int anInt1562; + public final int anInt1563; + public final int anInt1564; + public boolean aBoolean1567; + private final Graphic graphic; + private int anInt1569; + private int anInt1570; + private int nextAnimFrameId; + + public AnimableObject(int i, int j, int l, int i1, int j1, int k1, int l1) { + aBoolean1567 = false; + graphic = Graphic.cache[i1]; + anInt1560 = i; + anInt1561 = l1; + anInt1562 = k1; + anInt1563 = j1; + anInt1564 = j + l; + aBoolean1567 = false; + } + + public Model getRotatedModel() { + Model model = graphic.getModel(); + if(model == null) { + return null; + } + int j = graphic.animationSequence.primaryFrames[anInt1569]; + Model model_1 = new Model(true, Frame.noAnimationInProgress(j), false, model); + System.out.println(Configuration.enableTweening); + if(!aBoolean1567) { + + model_1.skin(); + if(Configuration.enableTweening && nextAnimFrameId != -1) { + model_1.applyAnimationFrame(j, graphic.animationSequence.primaryFrames[nextAnimFrameId], anInt1570, graphic.animationSequence.durations[anInt1569]); + } else { + model_1.applyTransform(j); + } + model_1.faceGroups = null; + model_1.vertexGroups = null; + + } + if(graphic.resizeXY != 128 || graphic.resizeZ != 128) { + model_1.scale(graphic.resizeXY, graphic.resizeXY, graphic.resizeZ); + } + if(graphic.rotation != 0) { + if(graphic.rotation == 90) { + model_1.rotate90Degrees(); + } + if(graphic.rotation == 180) { + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + } + if(graphic.rotation == 270) { + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + model_1.rotate90Degrees(); + } + } + model_1.light(64 + graphic.modelBrightness, 850 + graphic.modelShadow, -30, -50, -30, true); + return model_1; + } + + public void method454(int i) { + for(anInt1570 += i; anInt1570 > graphic.animationSequence.duration(anInt1569);) { + anInt1570 -= graphic.animationSequence.duration(anInt1569) + 1; + anInt1569++; + if(anInt1569 >= graphic.animationSequence.frameCount && (anInt1569 < 0 || anInt1569 >= graphic.animationSequence.frameCount)) { + anInt1569 = 0; + aBoolean1567 = true; + } + if (Configuration.enableTweening) { + nextAnimFrameId = anInt1569 + 1; + } + if (nextAnimFrameId >= graphic.animationSequence.frameCount) { + nextAnimFrameId = -1; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/scene/CollisionMap.java b/src/main/java/org/rebotted/scene/CollisionMap.java new file mode 100644 index 0000000..b07d5be --- /dev/null +++ b/src/main/java/org/rebotted/scene/CollisionMap.java @@ -0,0 +1,511 @@ +package org.rebotted.scene; + +public final class CollisionMap { + + private static final int BLOCKED_TILE = 0x200000; + //private static final int OBJECT_TILE = 0x100; + + private final int xOffset; + private final int yOffset; + private final int width; + private final int height; + public final int[][] adjacencies; + + public CollisionMap() { + xOffset = 0; + yOffset = 0; + width = 104; + height = 104; + adjacencies = new int[width][height]; + initialize(); + } + + public void initialize() { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) + if (x == 0 || y == 0 || x == width - 1 + || y == height - 1) + adjacencies[x][y] = 0xffffff; + else + adjacencies[x][y] = 0x1000000; + } + + } + + public void method211(int y, int orientation, int x, int group, boolean flag) { + x -= xOffset; + y -= yOffset; + if (group == 0) { + if (orientation == 0) { + flag(x, y, 128); + flag(x - 1, y, 8); + } + if (orientation == 1) { + flag(x, y, 2); + flag(x, y + 1, 32); + } + if (orientation == 2) { + flag(x, y, 8); + flag(x + 1, y, 128); + } + if (orientation == 3) { + flag(x, y, 32); + flag(x, y - 1, 2); + } + } + if (group == 1 || group == 3) { + if (orientation == 0) { + flag(x, y, 1); + flag(x - 1, y + 1, 16); + } + if (orientation == 1) { + flag(x, y, 4); + flag(x + 1, y + 1, 64); + } + if (orientation == 2) { + flag(x, y, 16); + flag(x + 1, y - 1, 1); + } + if (orientation == 3) { + flag(x, y, 64); + flag(x - 1, y - 1, 4); + } + } + if (group == 2) { + if (orientation == 0) { + flag(x, y, 130); + flag(x - 1, y, 8); + flag(x, y + 1, 32); + } + if (orientation == 1) { + flag(x, y, 10); + flag(x, y + 1, 32); + flag(x + 1, y, 128); + } + if (orientation == 2) { + flag(x, y, 40); + flag(x + 1, y, 128); + flag(x, y - 1, 2); + } + if (orientation == 3) { + flag(x, y, 160); + flag(x, y - 1, 2); + flag(x - 1, y, 8); + } + } + if (flag) { + if (group == 0) { + if (orientation == 0) { + flag(x, y, 0x10000); + flag(x - 1, y, 4096); + } + if (orientation == 1) { + flag(x, y, 1024); + flag(x, y + 1, 16384); + } + if (orientation == 2) { + flag(x, y, 4096); + flag(x + 1, y, 0x10000); + } + if (orientation == 3) { + flag(x, y, 16384); + flag(x, y - 1, 1024); + } + } + if (group == 1 || group == 3) { + if (orientation == 0) { + flag(x, y, 512); + flag(x - 1, y + 1, 8192); + } + if (orientation == 1) { + flag(x, y, 2048); + flag(x + 1, y + 1, 32768); + } + if (orientation == 2) { + flag(x, y, 8192); + flag(x + 1, y - 1, 512); + } + if (orientation == 3) { + flag(x, y, 32768); + flag(x - 1, y - 1, 2048); + } + } + if (group == 2) { + if (orientation == 0) { + flag(x, y, 0x10400); + flag(x - 1, y, 4096); + flag(x, y + 1, 16384); + } + if (orientation == 1) { + flag(x, y, 5120); + flag(x, y + 1, 16384); + flag(x + 1, y, 0x10000); + } + if (orientation == 2) { + flag(x, y, 20480); + flag(x + 1, y, 0x10000); + flag(x, y - 1, 1024); + } + if (orientation == 3) { + flag(x, y, 0x14000); + flag(x, y - 1, 1024); + flag(x - 1, y, 4096); + } + } + } + } + + public void method212(boolean flag, int j, int k, int l, int i1, int j1) { + int k1 = 256; + if (flag) + k1 += 0x20000; + l -= xOffset; + i1 -= yOffset; + if (j1 == 1 || j1 == 3) { + int l1 = j; + j = k; + k = l1; + } + for (int i2 = l; i2 < l + j; i2++) + if (i2 >= 0 && i2 < width) { + for (int j2 = i1; j2 < i1 + k; j2++) + if (j2 >= 0 && j2 < height) + flag(i2, j2, k1); + + } + + } + + public void block(int x, int y) { + x -= xOffset; + y -= yOffset; + adjacencies[x][y] |= BLOCKED_TILE; + } + + private void flag(int x, int y, int value) { + adjacencies[x][y] |= value; + } + + public void removeObject(int i, int j, boolean flag, int k, int l) { + k -= xOffset; + l -= yOffset; + if (j == 0) { + if (i == 0) { + method217(128, k, l); + method217(8, k - 1, l); + } + if (i == 1) { + method217(2, k, l); + method217(32, k, l + 1); + } + if (i == 2) { + method217(8, k, l); + method217(128, k + 1, l); + } + if (i == 3) { + method217(32, k, l); + method217(2, k, l - 1); + } + } + if (j == 1 || j == 3) { + if (i == 0) { + method217(1, k, l); + method217(16, k - 1, l + 1); + } + if (i == 1) { + method217(4, k, l); + method217(64, k + 1, l + 1); + } + if (i == 2) { + method217(16, k, l); + method217(1, k + 1, l - 1); + } + if (i == 3) { + method217(64, k, l); + method217(4, k - 1, l - 1); + } + } + if (j == 2) { + if (i == 0) { + method217(130, k, l); + method217(8, k - 1, l); + method217(32, k, l + 1); + } + if (i == 1) { + method217(10, k, l); + method217(32, k, l + 1); + method217(128, k + 1, l); + } + if (i == 2) { + method217(40, k, l); + method217(128, k + 1, l); + method217(2, k, l - 1); + } + if (i == 3) { + method217(160, k, l); + method217(2, k, l - 1); + method217(8, k - 1, l); + } + } + if (flag) { + if (j == 0) { + if (i == 0) { + method217(0x10000, k, l); + method217(4096, k - 1, l); + } + if (i == 1) { + method217(1024, k, l); + method217(16384, k, l + 1); + } + if (i == 2) { + method217(4096, k, l); + method217(0x10000, k + 1, l); + } + if (i == 3) { + method217(16384, k, l); + method217(1024, k, l - 1); + } + } + if (j == 1 || j == 3) { + if (i == 0) { + method217(512, k, l); + method217(8192, k - 1, l + 1); + } + if (i == 1) { + method217(2048, k, l); + method217(32768, k + 1, l + 1); + } + if (i == 2) { + method217(8192, k, l); + method217(512, k + 1, l - 1); + } + if (i == 3) { + method217(32768, k, l); + method217(2048, k - 1, l - 1); + } + } + if (j == 2) { + if (i == 0) { + method217(0x10400, k, l); + method217(4096, k - 1, l); + method217(16384, k, l + 1); + } + if (i == 1) { + method217(5120, k, l); + method217(16384, k, l + 1); + method217(0x10000, k + 1, l); + } + if (i == 2) { + method217(20480, k, l); + method217(0x10000, k + 1, l); + method217(1024, k, l - 1); + } + if (i == 3) { + method217(0x14000, k, l); + method217(1024, k, l - 1); + method217(4096, k - 1, l); + } + } + } + } + + public void removeObject(int i, int j, int k, int l, int i1, boolean flag) { + int j1 = 256; + if (flag) + j1 += 0x20000; + k -= xOffset; + l -= yOffset; + if (i == 1 || i == 3) { + int k1 = j; + j = i1; + i1 = k1; + } + for (int l1 = k; l1 < k + j; l1++) + if (l1 >= 0 && l1 < width) { + for (int i2 = l; i2 < l + i1; i2++) + if (i2 >= 0 && i2 < height) + method217(j1, l1, i2); + + } + + } + + private void method217(int i, int j, int k) { + adjacencies[j][k] &= 0xffffff - i; + } + + public void removeFloorDecoration(int j, int k) { + k -= xOffset; + j -= yOffset; + adjacencies[k][j] &= 0xdfffff; + } + + public boolean method219(int i, int j, int k, int i1, int j1, int k1) { + if (j == i && k == k1) + return true; + j -= xOffset; + k -= yOffset; + i -= xOffset; + k1 -= yOffset; + if (j1 == 0) + if (i1 == 0) { + if (j == i - 1 && k == k1) + return true; + if (j == i && k == k1 + 1 + && (adjacencies[j][k] & 0x1280120) == 0) + return true; + if (j == i && k == k1 - 1 + && (adjacencies[j][k] & 0x1280102) == 0) + return true; + } else if (i1 == 1) { + if (j == i && k == k1 + 1) + return true; + if (j == i - 1 && k == k1 + && (adjacencies[j][k] & 0x1280108) == 0) + return true; + if (j == i + 1 && k == k1 + && (adjacencies[j][k] & 0x1280180) == 0) + return true; + } else if (i1 == 2) { + if (j == i + 1 && k == k1) + return true; + if (j == i && k == k1 + 1 + && (adjacencies[j][k] & 0x1280120) == 0) + return true; + if (j == i && k == k1 - 1 + && (adjacencies[j][k] & 0x1280102) == 0) + return true; + } else if (i1 == 3) { + if (j == i && k == k1 - 1) + return true; + if (j == i - 1 && k == k1 + && (adjacencies[j][k] & 0x1280108) == 0) + return true; + if (j == i + 1 && k == k1 + && (adjacencies[j][k] & 0x1280180) == 0) + return true; + } + if (j1 == 2) + if (i1 == 0) { + if (j == i - 1 && k == k1) + return true; + if (j == i && k == k1 + 1) + return true; + if (j == i + 1 && k == k1 + && (adjacencies[j][k] & 0x1280180) == 0) + return true; + if (j == i && k == k1 - 1 + && (adjacencies[j][k] & 0x1280102) == 0) + return true; + } else if (i1 == 1) { + if (j == i - 1 && k == k1 + && (adjacencies[j][k] & 0x1280108) == 0) + return true; + if (j == i && k == k1 + 1) + return true; + if (j == i + 1 && k == k1) + return true; + if (j == i && k == k1 - 1 + && (adjacencies[j][k] & 0x1280102) == 0) + return true; + } else if (i1 == 2) { + if (j == i - 1 && k == k1 + && (adjacencies[j][k] & 0x1280108) == 0) + return true; + if (j == i && k == k1 + 1 + && (adjacencies[j][k] & 0x1280120) == 0) + return true; + if (j == i + 1 && k == k1) + return true; + if (j == i && k == k1 - 1) + return true; + } else if (i1 == 3) { + if (j == i - 1 && k == k1) + return true; + if (j == i && k == k1 + 1 + && (adjacencies[j][k] & 0x1280120) == 0) + return true; + if (j == i + 1 && k == k1 + && (adjacencies[j][k] & 0x1280180) == 0) + return true; + if (j == i && k == k1 - 1) + return true; + } + if (j1 == 9) { + if (j == i && k == k1 + 1 && (adjacencies[j][k] & 0x20) == 0) + return true; + if (j == i && k == k1 - 1 && (adjacencies[j][k] & 2) == 0) + return true; + if (j == i - 1 && k == k1 && (adjacencies[j][k] & 8) == 0) + return true; + if (j == i + 1 && k == k1 && (adjacencies[j][k] & 0x80) == 0) + return true; + } + return false; + } + + public boolean method220(int i, int j, int k, int l, int i1, int j1) { + if (j1 == i && k == j) + return true; + j1 -= xOffset; + k -= yOffset; + i -= xOffset; + j -= yOffset; + if (l == 6 || l == 7) { + if (l == 7) + i1 = i1 + 2 & 3; + if (i1 == 0) { + if (j1 == i + 1 && k == j && (adjacencies[j1][k] & 0x80) == 0) + return true; + if (j1 == i && k == j - 1 && (adjacencies[j1][k] & 2) == 0) + return true; + } else if (i1 == 1) { + if (j1 == i - 1 && k == j && (adjacencies[j1][k] & 8) == 0) + return true; + if (j1 == i && k == j - 1 && (adjacencies[j1][k] & 2) == 0) + return true; + } else if (i1 == 2) { + if (j1 == i - 1 && k == j && (adjacencies[j1][k] & 8) == 0) + return true; + if (j1 == i && k == j + 1 && (adjacencies[j1][k] & 0x20) == 0) + return true; + } else if (i1 == 3) { + if (j1 == i + 1 && k == j && (adjacencies[j1][k] & 0x80) == 0) + return true; + if (j1 == i && k == j + 1 && (adjacencies[j1][k] & 0x20) == 0) + return true; + } + } + if (l == 8) { + if (j1 == i && k == j + 1 && (adjacencies[j1][k] & 0x20) == 0) + return true; + if (j1 == i && k == j - 1 && (adjacencies[j1][k] & 2) == 0) + return true; + if (j1 == i - 1 && k == j && (adjacencies[j1][k] & 8) == 0) + return true; + if (j1 == i + 1 && k == j && (adjacencies[j1][k] & 0x80) == 0) + return true; + } + return false; + } + + public boolean method221(int i, int j, int k, int l, int i1, int j1, int k1) { + int l1 = (j + j1) - 1; + int i2 = (i + l) - 1; + if (k >= j && k <= l1 && k1 >= i && k1 <= i2) + return true; + if (k == j - 1 && k1 >= i && k1 <= i2 + && (adjacencies[k - xOffset][k1 - yOffset] & 8) == 0 + && (i1 & 8) == 0) + return true; + if (k == l1 + 1 && k1 >= i && k1 <= i2 + && (adjacencies[k - xOffset][k1 - yOffset] & 0x80) == 0 + && (i1 & 2) == 0) + return true; + return k1 == i - 1 && k >= j && k <= l1 + && (adjacencies[k - xOffset][k1 - yOffset] & 2) == 0 + && (i1 & 4) == 0 || k1 == i2 + 1 && k >= j && k <= l1 + && (adjacencies[k - xOffset][k1 - yOffset] & 0x20) == 0 + && (i1 & 1) == 0; + } +} diff --git a/src/main/java/org/rebotted/scene/MapRegion.java b/src/main/java/org/rebotted/scene/MapRegion.java new file mode 100644 index 0000000..848c4fd --- /dev/null +++ b/src/main/java/org/rebotted/scene/MapRegion.java @@ -0,0 +1,1262 @@ +package org.rebotted.scene; +import org.rebotted.cache.def.FloorDefinition; +import org.rebotted.cache.def.ObjectDefinition; +import org.rebotted.draw.Rasterizer3D; +import org.rebotted.entity.Renderable; +import org.rebotted.entity.model.Model; +import org.rebotted.io.Buffer; +import org.rebotted.net.requester.ResourceProvider; +import org.rebotted.util.ChunkUtil; + +public final class MapRegion { + + private final int[] hues; + private final int[] saturations; + private final int[] luminances; + private final int[] chromas; + private final int[] anIntArray128; + private final int[][][] tileHeights; + private final byte[][][] overlays; + public static int anInt131; + private final byte[][][] shading; + private final int[][][] anIntArrayArrayArray135; + private final byte[][][] overlayTypes; + private static final int COSINE_VERTICES[] = { 1, 0, -1, 0 }; + private final int[][] tileLighting; + private static final int anIntArray140[] = { 16, 32, 64, 128 }; + private final byte[][][] underlays; + private static final int SINE_VERTICIES[] = { 0, -1, 0, 1 }; + public static int maximumPlane = 99; + private final int regionSizeX; + private final int regionSizeY; + private final byte[][][] overlayOrientations; + private final byte[][][] tileFlags; + public static boolean lowMem = true; + private static final int anIntArray152[] = { 1, 2, 4, 8 }; + + private static final int BLOCKED_TILE = 1; + public static final int BRIDGE_TILE = 2; + private static final int FORCE_LOWEST_PLANE = 8; + + public MapRegion(byte fileFlags[][][], int tileHeights[][][]) { + maximumPlane = 99; + regionSizeX = 104; + regionSizeY = 104; + this.tileHeights = tileHeights; + this.tileFlags = fileFlags; + underlays = new byte[4][regionSizeX][regionSizeY]; + overlays = new byte[4][regionSizeX][regionSizeY]; + overlayTypes = new byte[4][regionSizeX][regionSizeY]; + overlayOrientations = new byte[4][regionSizeX][regionSizeY]; + anIntArrayArrayArray135 = new int[4][regionSizeX + 1][regionSizeY + 1]; + shading = new byte[4][regionSizeX + 1][regionSizeY + 1]; + tileLighting = new int[regionSizeX + 1][regionSizeY + 1]; + hues = new int[regionSizeY]; + saturations = new int[regionSizeY]; + luminances = new int[regionSizeY]; + chromas = new int[regionSizeY]; + anIntArray128 = new int[regionSizeY]; + } + + private static int calculateNoise(int x, int y) { + int k = x + y * 57; + k = k << 13 ^ k; + int l = k * (k * k * 15731 + 0xc0ae5) + 0x5208dd0d & 0x7fffffff; + return l >> 19 & 0xff; + } + + public final void createRegionScene(CollisionMap maps[], SceneGraph scene) { + try { + + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 104; x++) { + for (int y = 0; y < 104; y++) + if ((tileFlags[z][x][y] & BLOCKED_TILE) == 1) { + int plane = z; + if ((tileFlags[1][x][y] & BRIDGE_TILE) == 2) + plane--; + if (plane >= 0) + maps[plane].block(x, y); + } + + } + + } + for (int z = 0; z < 4; z++) { + byte shading[][] = this.shading[z]; + byte byte0 = 96; + char diffusion = '\u0300'; + byte lightX = -50; + byte lightY = -10; + byte lightZ = -50; + int light = (int) Math.sqrt(lightX * lightX + lightY * lightY + lightZ * lightZ); + int l3 = diffusion * light >> 8; + for (int j4 = 1; j4 < regionSizeY - 1; j4++) { + for (int j5 = 1; j5 < regionSizeX - 1; j5++) { + int k6 = tileHeights[z][j5 + 1][j4] - tileHeights[z][j5 - 1][j4]; + int l7 = tileHeights[z][j5][j4 + 1] - tileHeights[z][j5][j4 - 1]; + int j9 = (int) Math.sqrt(k6 * k6 + 0x10000 + l7 * l7); + int k12 = (k6 << 8) / j9; + int l13 = 0x10000 / j9; + int j15 = (l7 << 8) / j9; + int j16 = byte0 + (lightX * k12 + lightY * l13 + lightZ * j15) / l3; + int j17 = (shading[j5 - 1][j4] >> 2) + (shading[j5 + 1][j4] >> 3) + (shading[j5][j4 - 1] >> 2) + (shading[j5][j4 + 1] >> 3) + (shading[j5][j4] >> 1); + tileLighting[j5][j4] = j16 - j17; + } + + } + + for (int k5 = 0; k5 < regionSizeY; k5++) { + hues[k5] = 0; + saturations[k5] = 0; + luminances[k5] = 0; + chromas[k5] = 0; + anIntArray128[k5] = 0; + } + + for (int l6 = -5; l6 < regionSizeX + 5; l6++) { + for (int i8 = 0; i8 < regionSizeY; i8++) { + int k9 = l6 + 5; + if (k9 >= 0 && k9 < regionSizeX) { + int l12 = underlays[z][k9][i8] & 0xff; + if (l12 > 0) { + if (l12 > FloorDefinition.underlays.length) { + l12 = FloorDefinition.underlays.length; + } + FloorDefinition flo = FloorDefinition.underlays[l12 - 1]; + hues[i8] += flo.blendHue; + saturations[i8] += flo.saturation; + luminances[i8] += flo.luminance; + chromas[i8] += flo.blendHueMultiplier; + anIntArray128[i8]++; + } + } + int i13 = l6 - 5; + if (i13 >= 0 && i13 < regionSizeX) { + int i14 = underlays[z][i13][i8] & 0xff; + if (i14 > 0) { + FloorDefinition flo_1 = FloorDefinition.underlays[i14 - 1]; + hues[i8] -= flo_1.blendHue; + saturations[i8] -= flo_1.saturation; + luminances[i8] -= flo_1.luminance; + chromas[i8] -= flo_1.blendHueMultiplier; + anIntArray128[i8]--; + } + } + } + + if (l6 >= 1 && l6 < regionSizeX - 1) { + int l9 = 0; + int j13 = 0; + int j14 = 0; + int k15 = 0; + int k16 = 0; + for (int k17 = -5; k17 < regionSizeY + 5; k17++) { + int j18 = k17 + 5; + if (j18 >= 0 && j18 < regionSizeY) { + l9 += hues[j18]; + j13 += saturations[j18]; + j14 += luminances[j18]; + k15 += chromas[j18]; + k16 += anIntArray128[j18]; + } + int k18 = k17 - 5; + if (k18 >= 0 && k18 < regionSizeY) { + l9 -= hues[k18]; + j13 -= saturations[k18]; + j14 -= luminances[k18]; + k15 -= chromas[k18]; + k16 -= anIntArray128[k18]; + } + if (k17 >= 1 && k17 < regionSizeY - 1 && (!lowMem || (tileFlags[0][l6][k17] & 2) != 0 || (tileFlags[z][l6][k17] & 0x10) == 0 && getCollisionPlane(k17, z, l6) == anInt131)) { + if (z < maximumPlane) + maximumPlane = z; + int l18 = underlays[z][l6][k17] & 0xff; + int i19 = overlays[z][l6][k17] & 0xff; + if (l18 > 0 || i19 > 0) { + int j19 = tileHeights[z][l6][k17]; + int k19 = tileHeights[z][l6 + 1][k17]; + int l19 = tileHeights[z][l6 + 1][k17 + 1]; + int i20 = tileHeights[z][l6][k17 + 1]; + int j20 = tileLighting[l6][k17]; + int k20 = tileLighting[l6 + 1][k17]; + int l20 = tileLighting[l6 + 1][k17 + 1]; + int i21 = tileLighting[l6][k17 + 1]; + int j21 = -1; + int k21 = -1; + if (l18 > 0) { + int l21 = (l9 * 256) / k15; + int j22 = j13 / k16; + int l22 = j14 / k16; + j21 = encode(l21, j22, l22); + + if (l22 < 0) + l22 = 0; + else if (l22 > 255) + l22 = 255; + + k21 = encode(l21, j22, l22); + } + if (z > 0) { + boolean flag = true; + if (l18 == 0 && overlayTypes[z][l6][k17] != 0) + flag = false; + if (i19 > 0 && !FloorDefinition.overlays[i19 - 1].occlude) + flag = false; + if (flag && j19 == k19 && j19 == l19 && j19 == i20) + anIntArrayArrayArray135[z][l6][k17] |= 0x924; + } + int i22 = 0; + if (j21 != -1) + i22 = Rasterizer3D.hslToRgb[method187(k21, 96)]; + if (i19 == 0) { + scene.addTile(z, l6, k17, 0, 0, -1, j19, k19, l19, i20, method187(j21, j20), method187(j21, k20), method187(j21, l20), method187(j21, i21), 0, 0, 0, 0, i22, 0); + } else { + + int k22 = overlayTypes[z][l6][k17] + 1; + byte byte4 = overlayOrientations[z][l6][k17]; + if (i19 - 1 > FloorDefinition.overlays.length) { + i19 = FloorDefinition.overlays.length; + } + FloorDefinition overlay_flo = FloorDefinition.overlays[i19 - 1]; + int textureId = overlay_flo.texture; + int j23; + int minimapColor; + + if (textureId > 50) { + textureId = -1; + } + if (textureId >= 0) { + minimapColor = Rasterizer3D.getOverallColour(textureId); + j23 = -1; + } else if (overlay_flo.rgb == 0xff00ff) { + minimapColor = 0; + j23 = -2; + textureId = -1; + } else if(overlay_flo.rgb == 0x333333) { + minimapColor = Rasterizer3D.hslToRgb[checkedLight(overlay_flo.hsl16, 96)]; + j23 = -2; + textureId = -1; + } else { + j23 = encode(overlay_flo.hue, overlay_flo.saturation, overlay_flo.luminance); + minimapColor = Rasterizer3D.hslToRgb[checkedLight(overlay_flo.hsl16, 96)]; + } + + if (minimapColor == 0x000000 && overlay_flo.anotherRgb != -1) { + int newMinimapColor = encode(overlay_flo.anotherHue, overlay_flo.anotherSaturation, overlay_flo.anotherLuminance); + minimapColor = Rasterizer3D.hslToRgb[checkedLight(newMinimapColor, 96)]; + } + + scene.addTile(z, l6, k17, k22, byte4, textureId, j19, k19, l19, i20, method187(j21, j20), method187(j21, k20), method187(j21, l20), method187(j21, i21), checkedLight(j23, j20), checkedLight(j23, k20), checkedLight(j23, l20), checkedLight(j23, i21), i22, minimapColor); + } + } + } + } + + } + } + + for (int j8 = 1; j8 < regionSizeY - 1; j8++) { + for (int i10 = 1; i10 < regionSizeX - 1; i10++) + scene.setTileLogicHeight(z, i10, j8, getCollisionPlane(j8, z, i10)); + + } + } + + scene.shadeModels(-10, -50, -50); + for (int j1 = 0; j1 < regionSizeX; j1++) { + for (int l1 = 0; l1 < regionSizeY; l1++) + if ((tileFlags[1][j1][l1] & 2) == 2) + scene.applyBridgeMode(l1, j1); + + } + + int i2 = 1; + int j2 = 2; + int k2 = 4; + for (int l2 = 0; l2 < 4; l2++) { + if (l2 > 0) { + i2 <<= 3; + j2 <<= 3; + k2 <<= 3; + } + for (int i3 = 0; i3 <= l2; i3++) { + for (int k3 = 0; k3 <= regionSizeY; k3++) { + for (int i4 = 0; i4 <= regionSizeX; i4++) { + if ((anIntArrayArrayArray135[i3][i4][k3] & i2) != 0) { + int k4 = k3; + int l5 = k3; + int i7 = i3; + int k8 = i3; + for (; k4 > 0 && (anIntArrayArrayArray135[i3][i4][k4 - 1] & i2) != 0; k4--) + ; + for (; l5 < regionSizeY && (anIntArrayArrayArray135[i3][i4][l5 + 1] & i2) != 0; l5++) + ; + label0: for (; i7 > 0; i7--) { + for (int j10 = k4; j10 <= l5; j10++) + if ((anIntArrayArrayArray135[i7 - 1][i4][j10] & i2) == 0) + break label0; + + } + + label1: for (; k8 < l2; k8++) { + for (int k10 = k4; k10 <= l5; k10++) + if ((anIntArrayArrayArray135[k8 + 1][i4][k10] & i2) == 0) + break label1; + + } + + int l10 = ((k8 + 1) - i7) * ((l5 - k4) + 1); + if (l10 >= 8) { + char c1 = '\360'; + int k14 = tileHeights[k8][i4][k4] - c1; + int l15 = tileHeights[i7][i4][k4]; + SceneGraph.createNewSceneCluster(l2, i4 * 128, l15, i4 * 128, l5 * 128 + 128, k14, k4 * 128, 1); + for (int l16 = i7; l16 <= k8; l16++) { + for (int l17 = k4; l17 <= l5; l17++) + anIntArrayArrayArray135[l16][i4][l17] &= ~i2; + + } + + } + } + if ((anIntArrayArrayArray135[i3][i4][k3] & j2) != 0) { + int l4 = i4; + int i6 = i4; + int j7 = i3; + int l8 = i3; + for (; l4 > 0 && (anIntArrayArrayArray135[i3][l4 - 1][k3] & j2) != 0; l4--) + ; + for (; i6 < regionSizeX && (anIntArrayArrayArray135[i3][i6 + 1][k3] & j2) != 0; i6++) + ; + label2: for (; j7 > 0; j7--) { + for (int i11 = l4; i11 <= i6; i11++) + if ((anIntArrayArrayArray135[j7 - 1][i11][k3] & j2) == 0) + break label2; + + } + + label3: for (; l8 < l2; l8++) { + for (int j11 = l4; j11 <= i6; j11++) + if ((anIntArrayArrayArray135[l8 + 1][j11][k3] & j2) == 0) + break label3; + + } + + int k11 = ((l8 + 1) - j7) * ((i6 - l4) + 1); + if (k11 >= 8) { + char c2 = '\360'; + int l14 = tileHeights[l8][l4][k3] - c2; + int i16 = tileHeights[j7][l4][k3]; + SceneGraph.createNewSceneCluster(l2, l4 * 128, i16, i6 * 128 + 128, k3 * 128, l14, k3 * 128, 2); + for (int i17 = j7; i17 <= l8; i17++) { + for (int i18 = l4; i18 <= i6; i18++) + anIntArrayArrayArray135[i17][i18][k3] &= ~j2; + + } + + } + } + if ((anIntArrayArrayArray135[i3][i4][k3] & k2) != 0) { + int i5 = i4; + int j6 = i4; + int k7 = k3; + int i9 = k3; + for (; k7 > 0 && (anIntArrayArrayArray135[i3][i4][k7 - 1] & k2) != 0; k7--) + ; + for (; i9 < regionSizeY && (anIntArrayArrayArray135[i3][i4][i9 + 1] & k2) != 0; i9++) + ; + label4: for (; i5 > 0; i5--) { + for (int l11 = k7; l11 <= i9; l11++) + if ((anIntArrayArrayArray135[i3][i5 - 1][l11] & k2) == 0) + break label4; + + } + + label5: for (; j6 < regionSizeX; j6++) { + for (int i12 = k7; i12 <= i9; i12++) + if ((anIntArrayArrayArray135[i3][j6 + 1][i12] & k2) == 0) + break label5; + + } + + if (((j6 - i5) + 1) * ((i9 - k7) + 1) >= 4) { + int j12 = tileHeights[i3][i5][k7]; + SceneGraph.createNewSceneCluster(l2, i5 * 128, j12, j6 * 128 + 128, i9 * 128 + 128, j12, k7 * 128, 4); + for (int k13 = i5; k13 <= j6; k13++) { + for (int i15 = k7; i15 <= i9; i15++) + anIntArrayArrayArray135[i3][k13][i15] &= ~k2; + + } + + } + } + } + + } + + } + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static int calculateVertexHeight(int i, int j) { + int mapHeight = (interpolatedNoise(i + 45365, j + 0x16713, 4) - 128) + (interpolatedNoise(i + 10294, j + 37821, 2) - 128 >> 1) + (interpolatedNoise(i, j, 1) - 128 >> 2); + mapHeight = (int) ((double) mapHeight * 0.29999999999999999D) + 35; + if (mapHeight < 10) { + mapHeight = 10; + } + else if (mapHeight > 60) { + mapHeight = 60; + } + return mapHeight; + } + + public static void passiveRequestGameObjectModels(Buffer buffer, ResourceProvider resourceProvider) { + label0: { + int gameObjectId = -1; + do { + int gameObjectIdOffset = buffer.readUSmart2(); + + if (gameObjectIdOffset == 0) { + break label0; + } + gameObjectId += gameObjectIdOffset ; + + ObjectDefinition objectDefinition = ObjectDefinition.lookup(gameObjectId ); + objectDefinition.loadModels(resourceProvider); + do { + int terminate = buffer.readUSmart(); + + if (terminate == 0) { + break; + } + buffer.readUnsignedByte(); + } while (true); + } while (true); + } + } + + public final void initiateVertexHeights(int yOffset, int yLength, int xLength, int xOffset) { + for (int y = yOffset; y <= yOffset + yLength; y++) { + for (int x = xOffset; x <= xOffset + xLength; x++) { + if (x >= 0 && x < regionSizeX && y >= 0 && y < regionSizeY) { + shading[0][x][y] = 127; + if (x == xOffset && x > 0) { + tileHeights[0][x][y] = tileHeights[0][x - 1][y]; + } + if (x == xOffset + xLength && x < regionSizeX - 1) { + tileHeights[0][x][y] = tileHeights[0][x + 1][y]; + } + if (y == yOffset && y > 0) { + tileHeights[0][x][y] = tileHeights[0][x][y - 1]; + } + if (y == yOffset + yLength && y < regionSizeY - 1) { + tileHeights[0][x][y] = tileHeights[0][x][y + 1]; + } + } + } + } + } + + private void renderObject(int y, SceneGraph scene, CollisionMap class11, int type, int z, int x, int id, int j1) { + if (lowMem && (tileFlags[0][x][y] & BRIDGE_TILE) == 0) { + if ((tileFlags[z][x][y] & 0x10) != 0) { + return; + } + + if (getCollisionPlane(y, z, x) != anInt131) { + return; + } + } + if (z < maximumPlane) { + maximumPlane = z; + } + int center = tileHeights[z][x][y]; + int east = tileHeights[z][x + 1][y]; + int northEast = tileHeights[z][x + 1][y + 1]; + int north = tileHeights[z][x][y + 1]; + int mean = center + east + northEast + north >> 2; + ObjectDefinition definition = ObjectDefinition.lookup(id); + int key = x + (y << 7) + (id << 14) + 0x40000000; + if (!definition.isInteractive) + key += 0x80000000; + byte config = (byte) ((j1 << 6) + type); + if (type == 22) { + if (lowMem && !definition.isInteractive && !definition.obstructsGround) + return; + Object obj; + if (definition.animation == -1 && definition.childrenIDs == null) + obj = definition.modelAt(22, j1, center, east, northEast, north, -1); + else + obj = new SceneObject(id, j1, 22, east, northEast, center, north, definition.animation, true); + scene.addGroundDecoration(z, mean, y, ((Renderable) (obj)), config, key, x); + if (definition.solid && definition.isInteractive && class11 != null) + class11.block(x, y); + return; + } + if (type == 10 || type == 11) { + Object obj1; + if (definition.animation == -1 && definition.childrenIDs == null) + obj1 = definition.modelAt(10, j1, center, east, northEast, north, -1); + else + obj1 = new SceneObject(id, j1, 10, east, northEast, center, north, definition.animation, true); + if (obj1 != null) { + int i5 = 0; + if (type == 11) + i5 += 256; + int j4; + int l4; + if (j1 == 1 || j1 == 3) { + j4 = definition.objectSizeY; + l4 = definition.objectSizeX; + } else { + j4 = definition.objectSizeX; + l4 = definition.objectSizeY; + } + if (scene.addTiledObject(key, config, mean, l4, ((Renderable) (obj1)), j4, z, i5, y, x) && definition.castsShadow) { + Model model; + if (obj1 instanceof Model) + model = (Model) obj1; + else + model = definition.modelAt(10, j1, center, east, northEast, north, -1); + if (model != null) { + for (int j5 = 0; j5 <= j4; j5++) { + for (int k5 = 0; k5 <= l4; k5++) { + int l5 = model.maxVertexDistanceXZPlane / 4; + if (l5 > 30) + l5 = 30; + if (l5 > shading[z][x + j5][y + k5]) + shading[z][x + j5][y + k5] = (byte) l5; + } + + } + + } + } + } + if (definition.solid && class11 != null) + class11.method212(definition.impenetrable, definition.objectSizeX, definition.objectSizeY, x, y, j1); + return; + } + if (type >= 12) { + Object obj2; + if (definition.animation == -1 && definition.childrenIDs == null) + obj2 = definition.modelAt(type, j1, center, east, northEast, north, -1); + else + obj2 = new SceneObject(id, j1, type, east, northEast, center, north, definition.animation, true); + scene.addTiledObject(key, config, mean, 1, ((Renderable) (obj2)), 1, z, 0, y, x); + if (type >= 12 && type <= 17 && type != 13 && z > 0) + anIntArrayArrayArray135[z][x][y] |= 0x924; + if (definition.solid && class11 != null) + class11.method212(definition.impenetrable, definition.objectSizeX, definition.objectSizeY, x, y, j1); + return; + } + if (type == 0) { + Object obj3; + if (definition.animation == -1 && definition.childrenIDs == null) + obj3 = definition.modelAt(0, j1, center, east, northEast, north, -1); + else + obj3 = new SceneObject(id, j1, 0, east, northEast, center, north, definition.animation, true); + scene.addWallObject(anIntArray152[j1], ((Renderable) (obj3)), key, y, config, x, null, mean, 0, z); + if (j1 == 0) { + if (definition.castsShadow) { + shading[z][x][y] = 50; + shading[z][x][y + 1] = 50; + } + if (definition.occludes) + anIntArrayArrayArray135[z][x][y] |= 0x249; + } else if (j1 == 1) { + if (definition.castsShadow) { + shading[z][x][y + 1] = 50; + shading[z][x + 1][y + 1] = 50; + } + if (definition.occludes) + anIntArrayArrayArray135[z][x][y + 1] |= 0x492; + } else if (j1 == 2) { + if (definition.castsShadow) { + shading[z][x + 1][y] = 50; + shading[z][x + 1][y + 1] = 50; + } + if (definition.occludes) + anIntArrayArrayArray135[z][x + 1][y] |= 0x249; + } else if (j1 == 3) { + if (definition.castsShadow) { + shading[z][x][y] = 50; + shading[z][x + 1][y] = 50; + } + if (definition.occludes) + anIntArrayArrayArray135[z][x][y] |= 0x492; + } + if (definition.solid && class11 != null) + class11.method211(y, j1, x, type, definition.impenetrable); + if (definition.decorDisplacement != 16) + scene.method290(y, definition.decorDisplacement, x, z); + return; + } + if (type == 1) { + Object obj4; + if (definition.animation == -1 && definition.childrenIDs == null) + obj4 = definition.modelAt(1, j1, center, east, northEast, north, -1); + else + obj4 = new SceneObject(id, j1, 1, east, northEast, center, north, definition.animation, true); + scene.addWallObject(anIntArray140[j1], ((Renderable) (obj4)), key, y, config, x, null, mean, 0, z); + if (definition.castsShadow) + if (j1 == 0) + shading[z][x][y + 1] = 50; + else if (j1 == 1) + shading[z][x + 1][y + 1] = 50; + else if (j1 == 2) + shading[z][x + 1][y] = 50; + else if (j1 == 3) + shading[z][x][y] = 50; + if (definition.solid && class11 != null) + class11.method211(y, j1, x, type, definition.impenetrable); + return; + } + if (type == 2) { + int i3 = j1 + 1 & 3; + Object obj11; + Object obj12; + if (definition.animation == -1 && definition.childrenIDs == null) { + obj11 = definition.modelAt(2, 4 + j1, center, east, northEast, north, -1); + obj12 = definition.modelAt(2, i3, center, east, northEast, north, -1); + } else { + obj11 = new SceneObject(id, 4 + j1, 2, east, northEast, center, north, definition.animation, true); + obj12 = new SceneObject(id, i3, 2, east, northEast, center, north, definition.animation, true); + } + scene.addWallObject(anIntArray152[j1], ((Renderable) (obj11)), key, y, config, x, ((Renderable) (obj12)), mean, anIntArray152[i3], z); + if (definition.occludes) + if (j1 == 0) { + anIntArrayArrayArray135[z][x][y] |= 0x249; + anIntArrayArrayArray135[z][x][y + 1] |= 0x492; + } else if (j1 == 1) { + anIntArrayArrayArray135[z][x][y + 1] |= 0x492; + anIntArrayArrayArray135[z][x + 1][y] |= 0x249; + } else if (j1 == 2) { + anIntArrayArrayArray135[z][x + 1][y] |= 0x249; + anIntArrayArrayArray135[z][x][y] |= 0x492; + } else if (j1 == 3) { + anIntArrayArrayArray135[z][x][y] |= 0x492; + anIntArrayArrayArray135[z][x][y] |= 0x249; + } + if (definition.solid && class11 != null) + class11.method211(y, j1, x, type, definition.impenetrable); + if (definition.decorDisplacement != 16) + scene.method290(y, definition.decorDisplacement, x, z); + return; + } + if (type == 3) { + Object obj5; + if (definition.animation == -1 && definition.childrenIDs == null) + obj5 = definition.modelAt(3, j1, center, east, northEast, north, -1); + else + obj5 = new SceneObject(id, j1, 3, east, northEast, center, north, definition.animation, true); + scene.addWallObject(anIntArray140[j1], ((Renderable) (obj5)), key, y, config, x, null, mean, 0, z); + if (definition.castsShadow) + if (j1 == 0) + shading[z][x][y + 1] = 50; + else if (j1 == 1) + shading[z][x + 1][y + 1] = 50; + else if (j1 == 2) + shading[z][x + 1][y] = 50; + else if (j1 == 3) + shading[z][x][y] = 50; + if (definition.solid && class11 != null) + class11.method211(y, j1, x, type, definition.impenetrable); + return; + } + if (type == 9) { + Object obj6; + if (definition.animation == -1 && definition.childrenIDs == null) + obj6 = definition.modelAt(type, j1, center, east, northEast, north, -1); + else + obj6 = new SceneObject(id, j1, type, east, northEast, center, north, definition.animation, true); + scene.addTiledObject(key, config, mean, 1, ((Renderable) (obj6)), 1, z, 0, y, x); + if (definition.solid && class11 != null) + class11.method212(definition.impenetrable, definition.objectSizeX, definition.objectSizeY, x, y, j1); + return; + } + if (definition.contouredGround) + if (j1 == 1) { + int j3 = north; + north = northEast; + northEast = east; + east = center; + center = j3; + } else if (j1 == 2) { + int k3 = north; + north = east; + east = k3; + k3 = northEast; + northEast = center; + center = k3; + } else if (j1 == 3) { + int l3 = north; + north = center; + center = east; + east = northEast; + northEast = l3; + } + if (type == 4) { + Object obj7; + if (definition.animation == -1 && definition.childrenIDs == null) + obj7 = definition.modelAt(4, 0, center, east, northEast, north, -1); + else + obj7 = new SceneObject(id, 0, 4, east, northEast, center, north, definition.animation, true); + scene.addWallDecoration(key, y, j1 * 512, z, 0, mean, ((Renderable) (obj7)), x, config, 0, anIntArray152[j1]); + return; + } + if (type == 5) { + int i4 = 16; + int k4 = scene.getWallObjectUid(z, x, y); + if (k4 > 0) + i4 = ObjectDefinition.lookup(k4 >> 14 & 0x7fff).decorDisplacement; + Object obj13; + if (definition.animation == -1 && definition.childrenIDs == null) + obj13 = definition.modelAt(4, 0, center, east, northEast, north, -1); + else + obj13 = new SceneObject(id, 0, 4, east, northEast, center, north, definition.animation, true); + scene.addWallDecoration(key, y, j1 * 512, z, COSINE_VERTICES[j1] * i4, mean, ((Renderable) (obj13)), x, config, SINE_VERTICIES[j1] * i4, anIntArray152[j1]); + return; + } + if (type == 6) { + Object obj8; + if (definition.animation == -1 && definition.childrenIDs == null) + obj8 = definition.modelAt(4, 0, center, east, northEast, north, -1); + else + obj8 = new SceneObject(id, 0, 4, east, northEast, center, north, definition.animation, true); + scene.addWallDecoration(key, y, j1, z, 0, mean, ((Renderable) (obj8)), x, config, 0, 256); + return; + } + if (type == 7) { + Object obj9; + if (definition.animation == -1 && definition.childrenIDs == null) + obj9 = definition.modelAt(4, 0, center, east, northEast, north, -1); + else + obj9 = new SceneObject(id, 0, 4, east, northEast, center, north, definition.animation, true); + scene.addWallDecoration(key, y, j1, z, 0, mean, ((Renderable) (obj9)), x, config, 0, 512); + return; + } + if (type == 8) { + Object obj10; + if (definition.animation == -1 && definition.childrenIDs == null) + obj10 = definition.modelAt(4, 0, center, east, northEast, north, -1); + else + obj10 = new SceneObject(id, 0, 4, east, northEast, center, north, definition.animation, true); + scene.addWallDecoration(key, y, j1, z, 0, mean, ((Renderable) (obj10)), x, config, 0, 768); + } + } + + private static int interpolatedNoise(int x, int y, int frequencyReciprocal) { + int l = x / frequencyReciprocal; + int i1 = x & frequencyReciprocal - 1; + int j1 = y / frequencyReciprocal; + int k1 = y & frequencyReciprocal - 1; + int l1 = smoothNoise(l, j1); + int i2 = smoothNoise(l + 1, j1); + int j2 = smoothNoise(l, j1 + 1); + int k2 = smoothNoise(l + 1, j1 + 1); + int l2 = interpolate(l1, i2, i1, frequencyReciprocal); + int i3 = interpolate(j2, k2, i1, frequencyReciprocal); + return interpolate(l2, i3, k1, frequencyReciprocal); + } + + /** + * Encodes the hue, saturation, and luminance into a colour value. + * + * @param hue The hue. + * @param saturation The saturation. + * @param luminance The luminance. + * @return The colour. + */ + private int encode(int hue, int saturation, int luminance) { + if (luminance > 179) + saturation /= 2; + if (luminance > 192) + saturation /= 2; + if (luminance > 217) + saturation /= 2; + if (luminance > 243) + saturation /= 2; + return (hue / 4 << 10) + (saturation / 32 << 7) + luminance / 2; + } + + public static boolean modelReady(int i, int j) { + ObjectDefinition class46 = ObjectDefinition.lookup(i); + if (j == 11) + j = 10; + if (j >= 5 && j <= 8) + j = 4; + return class46.method577(j); + } + + public final void method179(int i, int j, CollisionMap aclass11[], int l, int i1, byte abyte0[], int j1, int k1, int l1) { + for (int i2 = 0; i2 < 8; i2++) { + for (int j2 = 0; j2 < 8; j2++) + if (l + i2 > 0 && l + i2 < 103 && l1 + j2 > 0 && l1 + j2 < 103) + aclass11[k1].adjacencies[l + i2][l1 + j2] &= 0xfeffffff; + + } + Buffer stream = new Buffer(abyte0); + for (int l2 = 0; l2 < 4; l2++) { + for (int i3 = 0; i3 < 64; i3++) { + for (int j3 = 0; j3 < 64; j3++) + if (l2 == i && i3 >= i1 && i3 < i1 + 8 && j3 >= j1 && j3 < j1 + 8) + method181(l1 + ChunkUtil.method156(j3 & 7, j, i3 & 7), 0, stream, l + ChunkUtil.method155(j, j3 & 7, i3 & 7), k1, j, 0); + else + method181(-1, 0, stream, -1, 0, 0, 0); + + } + + } + + } + + public final void method180(byte abyte0[], int i, int j, int k, int l, CollisionMap aclass11[]) { + for (int i1 = 0; i1 < 4; i1++) { + for (int j1 = 0; j1 < 64; j1++) { + for (int k1 = 0; k1 < 64; k1++) + if (j + j1 > 0 && j + j1 < 103 && i + k1 > 0 && i + k1 < 103) + aclass11[i1].adjacencies[j + j1][i + k1] &= 0xfeffffff; + } + + } + + Buffer stream = new Buffer(abyte0); + for (int l1 = 0; l1 < 4; l1++) { + for (int i2 = 0; i2 < 64; i2++) { + for (int j2 = 0; j2 < 64; j2++) + method181(j2 + i, l, stream, i2 + j, l1, 0, k); + + } + + } + } + + private void method181(int i, int j, Buffer stream, int k, int l, int i1, int k1) { + try { + if (k >= 0 && k < 104 && i >= 0 && i < 104) { + tileFlags[l][k][i] = 0; + do { + int l1 = stream.readUnsignedByte(); + if (l1 == 0) + if (l == 0) { + tileHeights[0][k][i] = -calculateVertexHeight(0xe3b7b + k + k1, 0x87cce + i + j) * 8; + return; + } else { + tileHeights[l][k][i] = tileHeights[l - 1][k][i] - 240; + return; + } + if (l1 == 1) { + int j2 = stream.readUnsignedByte(); + if (j2 == 1) + j2 = 0; + if (l == 0) { + tileHeights[0][k][i] = -j2 * 8; + return; + } else { + tileHeights[l][k][i] = tileHeights[l - 1][k][i] - j2 * 8; + return; + } + } + if (l1 <= 49) { + overlays[l][k][i] = stream.readSignedByte(); + overlayTypes[l][k][i] = (byte) ((l1 - 2) / 4); + overlayOrientations[l][k][i] = (byte) ((l1 - 2) + i1 & 3); + } else if (l1 <= 81) + tileFlags[l][k][i] = (byte) (l1 - 49); + else + underlays[l][k][i] = (byte) (l1 - 81); + } while (true); + } + do { + int i2 = stream.readUnsignedByte(); + if (i2 == 0) + break; + if (i2 == 1) { + stream.readUnsignedByte(); + return; + } + if (i2 <= 49) + stream.readUnsignedByte(); + } while (true); + } catch (Exception e) { + } + } + + /** + * Returns the plane that actually contains the collision flag, to adjust for objects such as bridges. TODO better + * name + * + * @param x The x coordinate. + * @param y The y coordinate. + * @param z The z coordinate. + * @return The correct z coordinate. + */ + private int getCollisionPlane(int y, int z, int x) { + if ((tileFlags[z][x][y] & FORCE_LOWEST_PLANE) != 0) { + return 0; + } + if (z > 0 && (tileFlags[1][x][y] & BRIDGE_TILE) != 0) { + return z - 1; + } else { + return z; + } + } + + public final void method183(CollisionMap aclass11[], SceneGraph worldController, int i, int j, int k, int l, byte abyte0[], int i1, int j1, int k1) { + label0: { + Buffer stream = new Buffer(abyte0); + int l1 = -1; + do { + int i2 = stream.readUSmart2(); + if (i2 == 0) + break label0; + l1 += i2; + int j2 = 0; + do { + int k2 = stream.readUSmart(); + if (k2 == 0) + break; + j2 += k2 - 1; + int l2 = j2 & 0x3f; + int i3 = j2 >> 6 & 0x3f; + int j3 = j2 >> 12; + int k3 = stream.readUnsignedByte(); + int l3 = k3 >> 2; + int i4 = k3 & 3; + if (j3 == i && i3 >= i1 && i3 < i1 + 8 && l2 >= k && l2 < k + 8) { + ObjectDefinition class46 = ObjectDefinition.lookup(l1); + int j4 = j + ChunkUtil.method157(j1, class46.objectSizeY, i3 & 7, l2 & 7, class46.objectSizeX); + int k4 = k1 + ChunkUtil.method158(l2 & 7, class46.objectSizeY, j1, class46.objectSizeX, i3 & 7); + if (j4 > 0 && k4 > 0 && j4 < 103 && k4 < 103) { + int l4 = j3; + if ((tileFlags[1][j4][k4] & 2) == 2) + l4--; + CollisionMap class11 = null; + if (l4 >= 0) + class11 = aclass11[l4]; + renderObject(k4, worldController, class11, l3, l, j4, l1, i4 + j1 & 3); + } + } + } while (true); + } while (true); + } + } + + private static int interpolate(int a, int b, int angle, int frequencyReciprocal) { + int cosine = 0x10000 - Rasterizer3D.COSINE[(angle * 1024) / frequencyReciprocal] >> 1; + return (a * (0x10000 - cosine) >> 16) + (b * cosine >> 16); + } + + private int checkedLight(int color, int light) { + if (color == -2) + return 0xbc614e; + if (color == -1) { + if (light < 0) + light = 0; + else if (light > 127) + light = 127; + light = 127 - light; + return light; + } + light = (light * (color & 0x7f)) / 128; + if (light < 2) + light = 2; + else if (light > 126) + light = 126; + return (color & 0xff80) + light; + } + + private static int smoothNoise(int x, int y) { + int corners = calculateNoise(x - 1, y - 1) + calculateNoise(x + 1, y - 1) + calculateNoise(x - 1, y + 1) + calculateNoise(x + 1, y + 1); + int sides = calculateNoise(x - 1, y) + calculateNoise(x + 1, y) + calculateNoise(x, y - 1) + calculateNoise(x, y + 1); + int center = calculateNoise(x, y); + return corners / 16 + sides / 8 + center / 4; + } + + private static int method187(int i, int j) { + if (i == -1) + return 0xbc614e; + j = (j * (i & 0x7f)) / 128; + if (j < 2) + j = 2; + else if (j > 126) + j = 126; + return (i & 0xff80) + j; + } + + public static void placeObject(SceneGraph worldController, int i, int j, int k, int l, CollisionMap class11, int ai[][][], int i1, int j1, int k1) { + int l1 = ai[l][i1][j]; + int i2 = ai[l][i1 + 1][j]; + int j2 = ai[l][i1 + 1][j + 1]; + int k2 = ai[l][i1][j + 1]; + int l2 = l1 + i2 + j2 + k2 >> 2; + ObjectDefinition class46 = ObjectDefinition.lookup(j1); + int i3 = i1 + (j << 7) + (j1 << 14) + 0x40000000; + if (!class46.isInteractive) + i3 += 0x80000000; + byte byte1 = (byte) ((i << 6) + k); + if (k == 22) { + Object obj; + if (class46.animation == -1 && class46.childrenIDs == null) + obj = class46.modelAt(22, i, l1, i2, j2, k2, -1); + else + obj = new SceneObject(j1, i, 22, i2, j2, l1, k2, class46.animation, true); + worldController.addGroundDecoration(k1, l2, j, ((Renderable) (obj)), byte1, i3, i1); + if (class46.solid && class46.isInteractive) + class11.block(i1, j); + return; + } + if (k == 10 || k == 11) { + Object obj1; + if (class46.animation == -1 && class46.childrenIDs == null) + obj1 = class46.modelAt(10, i, l1, i2, j2, k2, -1); + else + obj1 = new SceneObject(j1, i, 10, i2, j2, l1, k2, class46.animation, true); + if (obj1 != null) { + int j5 = 0; + if (k == 11) + j5 += 256; + int k4; + int i5; + if (i == 1 || i == 3) { + k4 = class46.objectSizeY; + i5 = class46.objectSizeX; + } else { + k4 = class46.objectSizeX; + i5 = class46.objectSizeY; + } + worldController.addTiledObject(i3, byte1, l2, i5, ((Renderable) (obj1)), k4, k1, j5, j, i1); + } + if (class46.solid) + class11.method212(class46.impenetrable, class46.objectSizeX, class46.objectSizeY, i1, j, i); + return; + } + if (k >= 12) { + Object obj2; + if (class46.animation == -1 && class46.childrenIDs == null) + obj2 = class46.modelAt(k, i, l1, i2, j2, k2, -1); + else + obj2 = new SceneObject(j1, i, k, i2, j2, l1, k2, class46.animation, true); + worldController.addTiledObject(i3, byte1, l2, 1, ((Renderable) (obj2)), 1, k1, 0, j, i1); + if (class46.solid) + class11.method212(class46.impenetrable, class46.objectSizeX, class46.objectSizeY, i1, j, i); + return; + } + if (k == 0) { + Object obj3; + if (class46.animation == -1 && class46.childrenIDs == null) + obj3 = class46.modelAt(0, i, l1, i2, j2, k2, -1); + else + obj3 = new SceneObject(j1, i, 0, i2, j2, l1, k2, class46.animation, true); + worldController.addWallObject(anIntArray152[i], ((Renderable) (obj3)), i3, j, byte1, i1, null, l2, 0, k1); + if (class46.solid) + class11.method211(j, i, i1, k, class46.impenetrable); + return; + } + if (k == 1) { + Object obj4; + if (class46.animation == -1 && class46.childrenIDs == null) + obj4 = class46.modelAt(1, i, l1, i2, j2, k2, -1); + else + obj4 = new SceneObject(j1, i, 1, i2, j2, l1, k2, class46.animation, true); + worldController.addWallObject(anIntArray140[i], ((Renderable) (obj4)), i3, j, byte1, i1, null, l2, 0, k1); + if (class46.solid) + class11.method211(j, i, i1, k, class46.impenetrable); + return; + } + if (k == 2) { + int j3 = i + 1 & 3; + Object obj11; + Object obj12; + if (class46.animation == -1 && class46.childrenIDs == null) { + obj11 = class46.modelAt(2, 4 + i, l1, i2, j2, k2, -1); + obj12 = class46.modelAt(2, j3, l1, i2, j2, k2, -1); + } else { + obj11 = new SceneObject(j1, 4 + i, 2, i2, j2, l1, k2, class46.animation, true); + obj12 = new SceneObject(j1, j3, 2, i2, j2, l1, k2, class46.animation, true); + } + worldController.addWallObject(anIntArray152[i], ((Renderable) (obj11)), i3, j, byte1, i1, ((Renderable) (obj12)), l2, anIntArray152[j3], k1); + if (class46.solid) + class11.method211(j, i, i1, k, class46.impenetrable); + return; + } + if (k == 3) { + Object obj5; + if (class46.animation == -1 && class46.childrenIDs == null) + obj5 = class46.modelAt(3, i, l1, i2, j2, k2, -1); + else + obj5 = new SceneObject(j1, i, 3, i2, j2, l1, k2, class46.animation, true); + worldController.addWallObject(anIntArray140[i], ((Renderable) (obj5)), i3, j, byte1, i1, null, l2, 0, k1); + if (class46.solid) + class11.method211(j, i, i1, k, class46.impenetrable); + return; + } + if (k == 9) { + Object obj6; + if (class46.animation == -1 && class46.childrenIDs == null) + obj6 = class46.modelAt(k, i, l1, i2, j2, k2, -1); + else + obj6 = new SceneObject(j1, i, k, i2, j2, l1, k2, class46.animation, true); + worldController.addTiledObject(i3, byte1, l2, 1, ((Renderable) (obj6)), 1, k1, 0, j, i1); + if (class46.solid) + class11.method212(class46.impenetrable, class46.objectSizeX, class46.objectSizeY, i1, j, i); + return; + } + if (class46.contouredGround) + if (i == 1) { + int k3 = k2; + k2 = j2; + j2 = i2; + i2 = l1; + l1 = k3; + } else if (i == 2) { + int l3 = k2; + k2 = i2; + i2 = l3; + l3 = j2; + j2 = l1; + l1 = l3; + } else if (i == 3) { + int i4 = k2; + k2 = l1; + l1 = i2; + i2 = j2; + j2 = i4; + } + if (k == 4) { + Object obj7; + if (class46.animation == -1 && class46.childrenIDs == null) + obj7 = class46.modelAt(4, 0, l1, i2, j2, k2, -1); + else + obj7 = new SceneObject(j1, 0, 4, i2, j2, l1, k2, class46.animation, true); + worldController.addWallDecoration(i3, j, i * 512, k1, 0, l2, ((Renderable) (obj7)), i1, byte1, 0, anIntArray152[i]); + return; + } + if (k == 5) { + int j4 = 16; + int l4 = worldController.getWallObjectUid(k1, i1, j); + if (l4 > 0) + j4 = ObjectDefinition.lookup(l4 >> 14 & 0x7fff).decorDisplacement; + Object obj13; + if (class46.animation == -1 && class46.childrenIDs == null) + obj13 = class46.modelAt(4, 0, l1, i2, j2, k2, -1); + else + obj13 = new SceneObject(j1, 0, 4, i2, j2, l1, k2, class46.animation, true); + worldController.addWallDecoration(i3, j, i * 512, k1, COSINE_VERTICES[i] * j4, l2, ((Renderable) (obj13)), i1, byte1, SINE_VERTICIES[i] * j4, anIntArray152[i]); + return; + } + if (k == 6) { + Object obj8; + if (class46.animation == -1 && class46.childrenIDs == null) + obj8 = class46.modelAt(4, 0, l1, i2, j2, k2, -1); + else + obj8 = new SceneObject(j1, 0, 4, i2, j2, l1, k2, class46.animation, true); + worldController.addWallDecoration(i3, j, i, k1, 0, l2, ((Renderable) (obj8)), i1, byte1, 0, 256); + return; + } + if (k == 7) { + Object obj9; + if (class46.animation == -1 && class46.childrenIDs == null) + obj9 = class46.modelAt(4, 0, l1, i2, j2, k2, -1); + else + obj9 = new SceneObject(j1, 0, 4, i2, j2, l1, k2, class46.animation, true); + worldController.addWallDecoration(i3, j, i, k1, 0, l2, ((Renderable) (obj9)), i1, byte1, 0, 512); + return; + } + if (k == 8) { + Object obj10; + if (class46.animation == -1 && class46.childrenIDs == null) + obj10 = class46.modelAt(4, 0, l1, i2, j2, k2, -1); + else + obj10 = new SceneObject(j1, 0, 4, i2, j2, l1, k2, class46.animation, true); + worldController.addWallDecoration(i3, j, i, k1, 0, l2, ((Renderable) (obj10)), i1, byte1, 0, 768); + } + } + + public static boolean method189(int i, byte[] is, int i_250_) // xxx bad + // method, + // decompiled + // with JODE + { + boolean bool = true; + Buffer stream = new Buffer(is); + int i_252_ = -1; + for (;;) { + int i_253_ = stream.readUSmart(); + if (i_253_ == 0) + break; + i_252_ += i_253_; + int i_254_ = 0; + boolean bool_255_ = false; + for (;;) { + if (bool_255_) { + int i_256_ = stream.readUSmart(); + if (i_256_ == 0) + break; + stream.readUnsignedByte(); + } else { + int i_257_ = stream.readUSmart(); + if (i_257_ == 0) + break; + i_254_ += i_257_ - 1; + int i_258_ = i_254_ & 0x3f; + int i_259_ = i_254_ >> 6 & 0x3f; + int i_260_ = stream.readUnsignedByte() >> 2; + int i_261_ = i_259_ + i; + int i_262_ = i_258_ + i_250_; + if (i_261_ > 0 && i_262_ > 0 && i_261_ < 103 && i_262_ < 103) { + ObjectDefinition class46 = ObjectDefinition.lookup(i_252_); + if (i_260_ != 22 || !lowMem || class46.isInteractive || class46.obstructsGround) { + bool &= class46.method579(); + bool_255_ = true; + } + } + } + } + } + return bool; + } + + public final void method190(int i, CollisionMap aclass11[], int j, SceneGraph worldController, byte abyte0[]) { + label0: { + Buffer stream = new Buffer(abyte0); + int l = -1; + do { + int i1 = stream.readUSmart(); + if (i1 == 0) + break label0; + l += i1; + int j1 = 0; + do { + int k1 = stream.readUSmart(); + if (k1 == 0) + break; + j1 += k1 - 1; + int l1 = j1 & 0x3f; + int i2 = j1 >> 6 & 0x3f; + int j2 = j1 >> 12; + int k2 = stream.readUnsignedByte(); + int l2 = k2 >> 2; + int i3 = k2 & 3; + int j3 = i2 + i; + int k3 = l1 + j; + if (j3 > 0 && k3 > 0 && j3 < 103 && k3 < 103 && j2 >= 0 && j2 < 4) { + int l3 = j2; + if ((tileFlags[1][j3][k3] & 2) == 2) + l3--; + CollisionMap class11 = null; + if (l3 >= 0) + class11 = aclass11[l3]; + renderObject(k3, worldController, class11, l2, j2, j3, l, i3); + } + } while (true); + } while (true); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/scene/Projectile.java b/src/main/java/org/rebotted/scene/Projectile.java new file mode 100644 index 0000000..f6adeb5 --- /dev/null +++ b/src/main/java/org/rebotted/scene/Projectile.java @@ -0,0 +1,111 @@ +package org.rebotted.scene; +import org.rebotted.cache.anim.Frame; +import org.rebotted.cache.anim.Graphic; +import org.rebotted.entity.Renderable; +import org.rebotted.entity.model.Model; + +public final class Projectile extends Renderable { + + public final int startCycle; + public final int stopCycle; + private double xIncrement; + private double yIncrement; + private double diagonalIncrement; + private double heightIncrement; + private double aDouble1578; + private boolean started; + private final int projectileX; + private final int projectileY; + private final int startHeight; + public final int endHeight; + public double xPos; + public double yPos; + public double cnterHeight; + private final int initialSlope; + private final int initialDistance; + public final int target; + private final Graphic projectileGFX; + private int gfxStage; + private int gfxTickOfCurrentStage; + public int turnValue; + private int tiltAngle; + public final int projectileZ; + + public void calculateIncrements(int currentCycle, int targetY, int targetCenterHeight, int targetX) { + if(!started) { + double xToGo = targetX - projectileX; + double yToGo = targetY - projectileY; + double distanceToGo = Math.sqrt(xToGo * xToGo + yToGo * yToGo); + xPos = (double) projectileX + (xToGo * (double) initialDistance) / distanceToGo; + yPos = (double) projectileY + (yToGo * (double) initialDistance) / distanceToGo; + cnterHeight = startHeight; + } + double cyclesLeft = (stopCycle + 1) - currentCycle; + xIncrement = ((double)targetX - xPos) / cyclesLeft; + yIncrement = ((double)targetY - yPos) / cyclesLeft; + diagonalIncrement = Math.sqrt(xIncrement * xIncrement + yIncrement * yIncrement); + if(!started) { + heightIncrement = -diagonalIncrement * Math.tan((double) initialSlope * 0.02454369D); + } + aDouble1578 = (2D * ((double)targetCenterHeight - cnterHeight - heightIncrement * cyclesLeft)) / (cyclesLeft * cyclesLeft); + } + + public Model getRotatedModel() { + Model modelGfx = projectileGFX.getModel(); + if(modelGfx == null) { + return null; + } + int frameNumber = -1; + if(projectileGFX.animationSequence != null) { + frameNumber = projectileGFX.animationSequence.primaryFrames[gfxStage]; + } + Model projectileModel = new Model(true, Frame.noAnimationInProgress(frameNumber), false, modelGfx); + if(frameNumber != -1) { + projectileModel.skin(); + projectileModel.applyTransform(frameNumber); + projectileModel.faceGroups = null; + projectileModel.vertexGroups = null; + } + if(projectileGFX.resizeXY != 128 || projectileGFX.resizeZ != 128) { + projectileModel.scale(projectileGFX.resizeXY, projectileGFX.resizeXY, projectileGFX.resizeZ); + } + projectileModel.leanOverX(tiltAngle); + projectileModel.light(64 + projectileGFX.modelBrightness, 850 + projectileGFX.modelShadow, -30, -50, -30, true); + return projectileModel; + } + + public Projectile(int initialSlope, int endHeight, int creationCycle, int destructionCycle, int initialDistance, int startZ, int startHeight, int y, int x, int target, int gfxMoving) { + projectileGFX = Graphic.cache[gfxMoving]; + projectileZ = startZ; + projectileX = x; + projectileY = y; + this.startHeight = startHeight; + startCycle = creationCycle; + stopCycle = destructionCycle; + this.initialSlope = initialSlope; + this.initialDistance = initialDistance; + this.target = target; + this.endHeight = endHeight; + started = false; + } + + public void progressCycles(int cyclesMissed) { + started = true; + xPos += xIncrement * (double)cyclesMissed; + yPos += yIncrement * (double)cyclesMissed; + cnterHeight += heightIncrement * (double)cyclesMissed + 0.5D * aDouble1578 * (double)cyclesMissed * (double)cyclesMissed; + heightIncrement += aDouble1578 * (double)cyclesMissed; + //noinspection SuspiciousNameCombination + turnValue = (int)(Math.atan2(xIncrement, yIncrement) * 325.94900000000001D) + 1024 & 0x7ff; + tiltAngle = (int)(Math.atan2(heightIncrement, diagonalIncrement) * 325.94900000000001D) & 0x7ff; + if(projectileGFX.animationSequence != null) { + for(gfxTickOfCurrentStage += cyclesMissed; gfxTickOfCurrentStage > projectileGFX.animationSequence.duration(gfxStage);) { + gfxTickOfCurrentStage -= projectileGFX.animationSequence.duration(gfxStage) + 1; + gfxStage++; + if(gfxStage >= projectileGFX.animationSequence.frameCount) { + gfxStage = 0; + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/scene/SceneCluster.java b/src/main/java/org/rebotted/scene/SceneCluster.java new file mode 100644 index 0000000..1386f17 --- /dev/null +++ b/src/main/java/org/rebotted/scene/SceneCluster.java @@ -0,0 +1,23 @@ +package org.rebotted.scene; + +public final class SceneCluster { + + public int startXLoc; + public int endXLoc; + public int startYLoc; + public int endYLoc; + public int orientation; + public int startXPos; + public int endXPos; + public int startYPos; + public int endYPos; + public int startZPos; + public int endZPos; + public int cullDirection; + public int anInt799; + public int anInt800; + public int anInt801; + public int anInt802; + public int anInt803; + public int anInt804; +} diff --git a/src/main/java/org/rebotted/scene/SceneGraph.java b/src/main/java/org/rebotted/scene/SceneGraph.java new file mode 100644 index 0000000..93e3cc9 --- /dev/null +++ b/src/main/java/org/rebotted/scene/SceneGraph.java @@ -0,0 +1,1975 @@ +package org.rebotted.scene; +import org.rebotted.collection.Deque; +import org.rebotted.draw.Rasterizer2D; +import org.rebotted.draw.Rasterizer3D; +import org.rebotted.entity.GameObject; +import org.rebotted.entity.GroundItemTile; +import org.rebotted.entity.Renderable; +import org.rebotted.entity.model.Model; +import org.rebotted.entity.model.VertexNormal; +import org.rebotted.scene.object.GroundDecoration; +import org.rebotted.scene.object.WallDecoration; +import org.rebotted.scene.object.WallObject; +import org.rebotted.scene.object.tile.ShapedTile; +import org.rebotted.scene.object.tile.SimpleTile; +import org.rebotted.scene.object.tile.Tile; + +public final class SceneGraph { + + public SceneGraph(int heightMap[][][]) { + int yLocSize = 104;// was parameter + int xLocSize = 104;// was parameter + int zLocSize = 4;// was parameter + gameObjectsCache = new GameObject[5000]; + anIntArray486 = new int[10000]; + anIntArray487 = new int[10000]; + numberOfZ = zLocSize; + xRegionSize = xLocSize; + yRegionSize = yLocSize; + tileArray = new Tile[zLocSize][xLocSize][yLocSize]; + anIntArrayArrayArray445 = new int[zLocSize][xLocSize + 1][yLocSize + 1]; + this.heightMap = heightMap; + initToNull(); + } + + /** + * The class destructor. + */ + public static void destructor() { + interactableObjects = null; + sceneClusterCounts = null; + sceneClusters = null; + tileDeque = null; + aBooleanArrayArrayArrayArray491 = null; + aBooleanArrayArray492 = null; + } + + public void initToNull() { + for (int zLoc = 0; zLoc < numberOfZ; zLoc++) + for (int xLoc = 0; xLoc < xRegionSize; xLoc++) + for (int yLoc = 0; yLoc < yRegionSize; yLoc++) + tileArray[zLoc][xLoc][yLoc] = null; + for (int plane = 0; plane < cullingClusterPlaneCount; plane++) { + for (int j1 = 0; j1 < sceneClusterCounts[plane]; j1++) + sceneClusters[plane][j1] = null; + sceneClusterCounts[plane] = 0; + } + + for (int i = 0; i < interactableObjectCacheCurrPos; i++) + gameObjectsCache[i] = null; + interactableObjectCacheCurrPos = 0; + for (int i = 0; i < interactableObjects.length; i++) + interactableObjects[i] = null; + + } + + public void method275(int zLoc) { + zAnInt442 = zLoc; + for (int xLoc = 0; xLoc < xRegionSize; xLoc++) { + for (int yLoc = 0; yLoc < yRegionSize; yLoc++) + if (tileArray[zLoc][xLoc][yLoc] == null) + tileArray[zLoc][xLoc][yLoc] = new Tile(zLoc, xLoc, yLoc); + } + } + + public void applyBridgeMode(int yLoc, int xLoc) { + Tile tileFirstFloor = tileArray[0][xLoc][yLoc]; + for (int zLoc = 0; zLoc < 3; zLoc++) { + Tile tile = tileArray[zLoc][xLoc][yLoc] = tileArray[zLoc + 1][xLoc][yLoc]; + if (tile != null) { + tile.z1AnInt1307--; + for (int j1 = 0; j1 < tile.gameObjectIndex; j1++) { + GameObject gameObject = tile.gameObjects[j1]; + if ((gameObject.uid >> 29 & 3) == 2 && gameObject.xLocLow == xLoc && gameObject.yLocHigh == yLoc) + gameObject.zLoc--; + } + } + } + if (tileArray[0][xLoc][yLoc] == null) + tileArray[0][xLoc][yLoc] = new Tile(0, xLoc, yLoc); + tileArray[0][xLoc][yLoc].firstFloorTile = tileFirstFloor; + tileArray[3][xLoc][yLoc] = null; + } + + public static void createNewSceneCluster(int z, int lowestX, int lowestZ, int highestX, int highestY, int highestZ, int lowestY, int searchMask) { + SceneCluster sceneCluster = new SceneCluster(); + sceneCluster.startXLoc = lowestX / 128; + sceneCluster.endXLoc = highestX / 128; + sceneCluster.startYLoc = lowestY / 128; + sceneCluster.endYLoc = highestY / 128; + sceneCluster.orientation = searchMask; + sceneCluster.startXPos = lowestX; + sceneCluster.endXPos = highestX; + sceneCluster.startYPos = lowestY; + sceneCluster.endYPos = highestY; + sceneCluster.startZPos = highestZ; + sceneCluster.endZPos = lowestZ; + sceneClusters[z][sceneClusterCounts[z]++] = sceneCluster; + } + + public void setTileLogicHeight(int zLoc, int xLoc, int yLoc, int logicHeight) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile != null) + tileArray[zLoc][xLoc][yLoc].logicHeight = logicHeight; + } + + public void addTile(int zLoc, int xLoc, int yLoc, int shape, int i1, int j1, int k1, int l1, int i2, int j2, int k2, int l2, int i3, int j3, int k3, int l3, int i4, int j4, int k4, int l4) { + if (shape == 0) { + SimpleTile simpleTile = new SimpleTile(k2, l2, i3, j3, -1, k4, false); + for (int lowerZLoc = zLoc; lowerZLoc >= 0; lowerZLoc--) + if (tileArray[lowerZLoc][xLoc][yLoc] == null) + tileArray[lowerZLoc][xLoc][yLoc] = new Tile(lowerZLoc, xLoc, yLoc); + + tileArray[zLoc][xLoc][yLoc].mySimpleTile = simpleTile; + } else if (shape == 1) { + SimpleTile simpleTile = new SimpleTile(k3, l3, i4, j4, j1, l4, k1 == l1 && k1 == i2 && k1 == j2); + for (int lowerZLoc = zLoc; lowerZLoc >= 0; lowerZLoc--) + if (tileArray[lowerZLoc][xLoc][yLoc] == null) + tileArray[lowerZLoc][xLoc][yLoc] = new Tile(lowerZLoc, xLoc, yLoc); + + tileArray[zLoc][xLoc][yLoc].mySimpleTile = simpleTile; + } else { + ShapedTile shapedTile = new ShapedTile(yLoc, k3, j3, i2, j1, i4, i1, k2, k4, i3, j2, l1, k1, shape, j4, l3, l2, xLoc, l4); + for (int k5 = zLoc; k5 >= 0; k5--) + if (tileArray[k5][xLoc][yLoc] == null) + tileArray[k5][xLoc][yLoc] = new Tile(k5, xLoc, yLoc); + + tileArray[zLoc][xLoc][yLoc].myShapedTile = shapedTile; + } + } + + public void addGroundDecoration(int zLoc, int zPos, int yLoc, Renderable renderable, byte objectRotationType, int uid, int xLoc) { + if (renderable == null) + return; + GroundDecoration groundDecoration = new GroundDecoration(); + groundDecoration.renderable = renderable; + groundDecoration.xPos = xLoc * 128 + 64; + groundDecoration.yPos = yLoc * 128 + 64; + groundDecoration.zPos = zPos; + groundDecoration.uid = uid; + groundDecoration.mask = objectRotationType; + if (tileArray[zLoc][xLoc][yLoc] == null) + tileArray[zLoc][xLoc][yLoc] = new Tile(zLoc, xLoc, yLoc); + tileArray[zLoc][xLoc][yLoc].groundDecoration = groundDecoration; + } + + public void addGroundItemTile(int xLoc, int uid, Renderable firstNode, int zPos, Renderable secondNode, Renderable thirdNode, int zLoc, int yLoc) { + GroundItemTile groundItemTile = new GroundItemTile(); + groundItemTile.topNode = thirdNode; + groundItemTile.xPos = xLoc * 128 + 64; + groundItemTile.yPos = yLoc * 128 + 64; + groundItemTile.zPos = zPos; + groundItemTile.uid = uid; + groundItemTile.lowerNode = firstNode; + groundItemTile.middleNode = secondNode; + int largestItemDropHeight = 0; + Tile parentTile = tileArray[zLoc][xLoc][yLoc]; + if (parentTile != null) { + for (int i = 0; i < parentTile.gameObjectIndex; i++) + if (parentTile.gameObjects[i].renderable instanceof Model) { + int objectItemDropHeight = ((Model) parentTile.gameObjects[i].renderable).itemDropHeight; + if (objectItemDropHeight > largestItemDropHeight) + largestItemDropHeight = objectItemDropHeight; + } + + } + groundItemTile.itemDropHeight = largestItemDropHeight; + if (tileArray[zLoc][xLoc][yLoc] == null) + tileArray[zLoc][xLoc][yLoc] = new Tile(zLoc, xLoc, yLoc); + tileArray[zLoc][xLoc][yLoc].groundItemTile = groundItemTile; + } + + public void addWallObject(int orientation1, Renderable renderable1, int uid, int yLoc, byte objectFaceType, int xLoc, Renderable renderable2, int zPos, int orientation2, int zLoc) { + if (renderable1 == null && renderable2 == null) + return; + WallObject wallObject = new WallObject(); + wallObject.uid = uid; + wallObject.mask = objectFaceType; + wallObject.xPos = xLoc * 128 + 64; + wallObject.yPos = yLoc * 128 + 64; + wallObject.zPos = zPos; + wallObject.renderable1 = renderable1; + wallObject.renderable2 = renderable2; + wallObject.orientation1 = orientation1; + wallObject.orientation2 = orientation2; + for (int z = zLoc; z >= 0; z--) + if (tileArray[z][xLoc][yLoc] == null) + tileArray[z][xLoc][yLoc] = new Tile(z, xLoc, yLoc); + + tileArray[zLoc][xLoc][yLoc].wallObject = wallObject; + } + + public void addWallDecoration(int uid, int yLoc, int orientation2, int zLoc, int xOffset, int zPos, Renderable renderable, int xLoc, byte objectRotationType, int yOffset, int orientation) { + if (renderable == null) + return; + WallDecoration wallDecoration = new WallDecoration(); + wallDecoration.uid = uid; + wallDecoration.mask = objectRotationType; + wallDecoration.xPos = xLoc * 128 + 64 + xOffset; + wallDecoration.yPos = yLoc * 128 + 64 + yOffset; + wallDecoration.zPos = zPos; + wallDecoration.renderable = renderable; + wallDecoration.orientation = orientation; + wallDecoration.orientation2 = orientation2; + for (int z = zLoc; z >= 0; z--) + if (tileArray[z][xLoc][yLoc] == null) + tileArray[z][xLoc][yLoc] = new Tile(z, xLoc, yLoc); + + tileArray[zLoc][xLoc][yLoc].wallDecoration = wallDecoration; + } + + public boolean addTiledObject(int uid, byte objectRotationType, int tileHeight, int sizeY, Renderable renderable, int sizeX, int zLoc, int turnValue, int yLoc, int xLoc) { + if (renderable == null) { + return true; + } else { + int xPos = xLoc * 128 + 64 * sizeX; + int yPos = yLoc * 128 + 64 * sizeY; + return addAnimableC(zLoc, xLoc, yLoc, sizeX, sizeY, xPos, yPos, tileHeight, renderable, turnValue, false, uid, objectRotationType); + } + } + + public boolean addAnimableA(int zLoc, int turnValue, int k, int uid, int yPos, int halfSizePos, int xPos, Renderable animable, boolean flag) { + if (animable == null) + return true; + int startXLoc = xPos - halfSizePos; + int startYLoc = yPos - halfSizePos; + int endXLoc = xPos + halfSizePos; + int endYLoc = yPos + halfSizePos; + if (flag) { + if (turnValue > 640 && turnValue < 1408) + endYLoc += 128; + if (turnValue > 1152 && turnValue < 1920) + endXLoc += 128; + if (turnValue > 1664 || turnValue < 384) + startYLoc -= 128; + if (turnValue > 128 && turnValue < 896) + startXLoc -= 128; + } + startXLoc /= 128; + startYLoc /= 128; + endXLoc /= 128; + endYLoc /= 128; + return addAnimableC(zLoc, startXLoc, startYLoc, (endXLoc - startXLoc) + 1, (endYLoc - startYLoc) + 1, xPos, yPos, k, animable, turnValue, true, uid, (byte) 0); + } + + public boolean addToScenePlayerAsObject(int zLoc, int playerYPos, Renderable playerAsObject, int playerTurnValue, int objectEndYLoc, int playerXPos, int playerHeight, int objectStartXLoc, int objectEndXLoc, int uid, int objectStartYLoc) { + return playerAsObject == null || addAnimableC(zLoc, objectStartXLoc, objectStartYLoc, (objectEndXLoc - objectStartXLoc) + 1, (objectEndYLoc - objectStartYLoc) + 1, playerXPos, playerYPos, playerHeight, playerAsObject, playerTurnValue, true, uid, (byte) 0); + } + + private boolean addAnimableC(int zLoc, int xLoc, int yLoc, int sizeX, int sizeY, int xPos, int yPos, int tileHeight, Renderable renderable, int turnValue, boolean isDynamic, int uid, byte objectRotationType) { + for (int x = xLoc; x < xLoc + sizeX; x++) { + for (int y = yLoc; y < yLoc + sizeY; y++) { + if (x < 0 || y < 0 || x >= xRegionSize || y >= yRegionSize) + return false; + Tile tile = tileArray[zLoc][x][y]; + if (tile != null && tile.gameObjectIndex >= 5) + return false; + } + + } + + GameObject gameObject = new GameObject(); + gameObject.uid = uid; + gameObject.mask = objectRotationType; + gameObject.zLoc = zLoc; + gameObject.xPos = xPos; + gameObject.yPos = yPos; + gameObject.tileHeight = tileHeight; + gameObject.renderable = renderable; + gameObject.turnValue = turnValue; + gameObject.xLocLow = xLoc; + gameObject.yLocHigh = yLoc; + gameObject.xLocHigh = (xLoc + sizeX) - 1; + gameObject.yLocLow = (yLoc + sizeY) - 1; + for (int x = xLoc; x < xLoc + sizeX; x++) { + for (int y = yLoc; y < yLoc + sizeY; y++) { + int mask = 0; + if (x > xLoc) + mask++; + if (x < (xLoc + sizeX) - 1) + mask += 4; + if (y > yLoc) + mask += 8; + if (y < (yLoc + sizeY) - 1) + mask += 2; + for (int z = zLoc; z >= 0; z--) + if (tileArray[z][x][y] == null) + tileArray[z][x][y] = new Tile(z, x, y); + + Tile tile = tileArray[zLoc][x][y]; + tile.gameObjects[tile.gameObjectIndex] = gameObject; + tile.tiledObjectMasks[tile.gameObjectIndex] = mask; + tile.totalTiledObjectMask |= mask; + tile.gameObjectIndex++; + } + + } + + if (isDynamic) { + gameObjectsCache[interactableObjectCacheCurrPos++] = gameObject; + } + + return true; + } + + public void clearGameObjectCache() { + for (int i = 0; i < interactableObjectCacheCurrPos; i++) { + GameObject object5 = gameObjectsCache[i]; + remove(object5); + gameObjectsCache[i] = null; + } + + interactableObjectCacheCurrPos = 0; + } + + private void remove(GameObject gameObject) { + for (int x = gameObject.xLocLow; x <= gameObject.xLocHigh; x++) { + for (int y = gameObject.yLocHigh; y <= gameObject.yLocLow; y++) { + Tile tile = tileArray[gameObject.zLoc][x][y]; + if (tile != null) { + for (int i = 0; i < tile.gameObjectIndex; i++) { + if (tile.gameObjects[i] != gameObject) + continue; + tile.gameObjectIndex--; + for (int i1 = i; i1 < tile.gameObjectIndex; i1++) { + tile.gameObjects[i1] = tile.gameObjects[i1 + 1]; + tile.tiledObjectMasks[i1] = tile.tiledObjectMasks[i1 + 1]; + } + + tile.gameObjects[tile.gameObjectIndex] = null; + break; + } + + tile.totalTiledObjectMask = 0; + for (int i = 0; i < tile.gameObjectIndex; i++) + tile.totalTiledObjectMask |= tile.tiledObjectMasks[i]; + } + } + } + } + + public void method290(int yLoc, int k, int xLoc, int zLoc) { //TODO scale position? + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return; + WallDecoration wallDecoration = tile.wallDecoration; + if (wallDecoration != null) { + int xPos = xLoc * 128 + 64; + int yPos = yLoc * 128 + 64; + wallDecoration.xPos = xPos + ((wallDecoration.xPos - xPos) * k) / 16; + wallDecoration.yPos = yPos + ((wallDecoration.yPos - yPos) * k) / 16; + } + } + + public void removeWallObject(int xLoc, int zLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile != null) + tile.wallObject = null; + } + + public void removeWallDecoration(int yLoc, int zLoc, int xLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile != null) + tile.wallDecoration = null; + } + + public void removeTiledObject(int zLoc, int xLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return; + for (int j1 = 0; j1 < tile.gameObjectIndex; j1++) { + GameObject gameObject = tile.gameObjects[j1]; + if ((gameObject.uid >> 29 & 3) == 2 && gameObject.xLocLow == xLoc && gameObject.yLocHigh == yLoc) { + remove(gameObject); + return; + } + } + + } + + public void removeGroundDecoration(int zLoc, int yLoc, int xLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return; + tile.groundDecoration = null; + } + + public void removeGroundItemTile(int zLoc, int xLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile != null) + tile.groundItemTile = null; + } + + public WallObject getWallObject(int zLoc, int xLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return null; + else + return tile.wallObject; + } + + public WallDecoration getWallDecoration(int xLoc, int yLoc, int zLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return null; + else + return tile.wallDecoration; + } + + public GameObject getGameObject(int xLoc, int yLoc, int zLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return null; + for (int i = 0; i < tile.gameObjectIndex; i++) { + GameObject gameObject = tile.gameObjects[i]; + if ((gameObject.uid >> 29 & 3) == 2 && gameObject.xLocLow == xLoc && gameObject.yLocHigh == yLoc) + return gameObject; + } + return null; + } + + public GroundDecoration getGroundDecoration(int yLoc, int xLoc, int zLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null || tile.groundDecoration == null) + return null; + else + return tile.groundDecoration; + } + + public int getWallObjectUid(int zLoc, int xLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null || tile.wallObject == null) + return 0; + else + return tile.wallObject.uid; + } + + public int getWallDecorationUid(int zLoc, int xLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null || tile.wallDecoration == null) + return 0; + else + return tile.wallDecoration.uid; + } + + public int getGameObjectUid(int zLoc, int xLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return 0; + for (int i = 0; i < tile.gameObjectIndex; i++) { + GameObject gameObject = tile.gameObjects[i]; + if ((gameObject.uid >> 29 & 3) == 2 && gameObject.xLocLow == xLoc && gameObject.yLocHigh == yLoc) + return gameObject.uid; + } + return 0; + } + + public int getGroundDecorationUid(int zLoc, int xLoc, int yLoc) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null || tile.groundDecoration == null) + return 0; + else + return tile.groundDecoration.uid; + } + + /** + * Retrieves the mask of the object with the given uid at the given location. + * -1 if there's no object. + * @param zLoc The zLoc. + * @param xLoc The xLoc. + * @param yLoc The yLoc. + * @param uid The object's Uid. + * @return The mask, which is comprised out of the rotation (shifted 6 to the left) and the type (which has a maximum value of 22). + */ + public int getMask(int zLoc, int xLoc, int yLoc, int uid) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return -1; + if (tile.wallObject != null && tile.wallObject.uid == uid) + return tile.wallObject.mask & 0xff; + if (tile.wallDecoration != null && tile.wallDecoration.uid == uid) + return tile.wallDecoration.mask & 0xff; + if (tile.groundDecoration != null && tile.groundDecoration.uid == uid) + return tile.groundDecoration.mask & 0xff; + for (int i = 0; i < tile.gameObjectIndex; i++) + if (tile.gameObjects[i].uid == uid) + return tile.gameObjects[i].mask & 0xff; + return -1; + } + + public void shadeModels(int lightY, int lightX, int lightZ) { + int intensity = 64;// was parameter + int diffusion = 768;// was parameter + int lightDistance = (int) Math.sqrt(lightX * lightX + lightY * lightY + lightZ * lightZ); + int someLightQualityVariable = diffusion * lightDistance >> 8; + for (int zLoc = 0; zLoc < numberOfZ; zLoc++) { + for (int xLoc = 0; xLoc < xRegionSize; xLoc++) { + for (int yLoc = 0; yLoc < yRegionSize; yLoc++) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile != null) { + WallObject wallObject = tile.wallObject; + if (wallObject != null && wallObject.renderable1 != null && wallObject.renderable1.vertexNormals != null) { + method307(zLoc, 1, 1, xLoc, yLoc, (Model) wallObject.renderable1); + if (wallObject.renderable2 != null && wallObject.renderable2.vertexNormals != null) { + method307(zLoc, 1, 1, xLoc, yLoc, (Model) wallObject.renderable2); + mergeNormals((Model) wallObject.renderable1, (Model) wallObject.renderable2, 0, 0, 0, false); + ((Model) wallObject.renderable2).doShading(intensity, someLightQualityVariable, lightX, lightY, lightZ); + } + ((Model) wallObject.renderable1).doShading(intensity, someLightQualityVariable, lightX, lightY, lightZ); + } + for (int k2 = 0; k2 < tile.gameObjectIndex; k2++) { + GameObject interactableObject = tile.gameObjects[k2]; + if (interactableObject != null && interactableObject.renderable != null && interactableObject.renderable.vertexNormals != null) { + method307(zLoc, (interactableObject.xLocHigh - interactableObject.xLocLow) + 1, (interactableObject.yLocLow - interactableObject.yLocHigh) + 1, xLoc, yLoc, (Model) interactableObject.renderable); + ((Model) interactableObject.renderable).doShading(intensity, someLightQualityVariable, lightX, lightY, lightZ); + } + } + + GroundDecoration groundDecoration = tile.groundDecoration; + if (groundDecoration != null && groundDecoration.renderable.vertexNormals != null) { + method306GroundDecorationOnly(xLoc, zLoc, (Model) groundDecoration.renderable, yLoc); + ((Model) groundDecoration.renderable).doShading(intensity, someLightQualityVariable, lightX, lightY, lightZ); + } + } + } + } + } + } + + private void method306GroundDecorationOnly(int modelXLoc, int modelZLoc, Model model, int modelYLoc) { //TODO figure it out + if (modelXLoc < xRegionSize) { + Tile tile = tileArray[modelZLoc][modelXLoc + 1][modelYLoc]; + if (tile != null && tile.groundDecoration != null && tile.groundDecoration.renderable.vertexNormals != null) + mergeNormals(model, (Model) tile.groundDecoration.renderable, 128, 0, 0, true); + } + if (modelYLoc < xRegionSize) { + Tile tile = tileArray[modelZLoc][modelXLoc][modelYLoc + 1]; + if (tile != null && tile.groundDecoration != null && tile.groundDecoration.renderable.vertexNormals != null) + mergeNormals(model, (Model) tile.groundDecoration.renderable, 0, 0, 128, true); + } + if (modelXLoc < xRegionSize && modelYLoc < yRegionSize) { + Tile tile = tileArray[modelZLoc][modelXLoc + 1][modelYLoc + 1]; + if (tile != null && tile.groundDecoration != null && tile.groundDecoration.renderable.vertexNormals != null) + mergeNormals(model, (Model) tile.groundDecoration.renderable, 128, 0, 128, true); + } + if (modelXLoc < xRegionSize && modelYLoc > 0) { + Tile tile = tileArray[modelZLoc][modelXLoc + 1][modelYLoc - 1]; + if (tile != null && tile.groundDecoration != null && tile.groundDecoration.renderable.vertexNormals != null) + mergeNormals(model, (Model) tile.groundDecoration.renderable, 128, 0, -128, true); + } + } + + private void method307(int modelZLoc, int modelXSize, int modelYSize, int modelXLoc, int modelYLoc, Model model) { + boolean flag = true; + int startX = modelXLoc; + int stopX = modelXLoc + modelXSize; + int startY = modelYLoc - 1; + int stopY = modelYLoc + modelYSize; + for (int zLoc = modelZLoc; zLoc <= modelZLoc + 1; zLoc++) + if (zLoc != numberOfZ) {//TODO Always? + for (int xLoc = startX; xLoc <= stopX; xLoc++) + if (xLoc >= 0 && xLoc < xRegionSize) { + for (int yLoc = startY; yLoc <= stopY; yLoc++) + if (yLoc >= 0 && yLoc < yRegionSize && (!flag || xLoc >= stopX || yLoc >= stopY || yLoc < modelYLoc && xLoc != modelXLoc)) { + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile != null) { + int relativeHeightToModelTile = (heightMap[zLoc][xLoc][yLoc] + heightMap[zLoc][xLoc + 1][yLoc] + heightMap[zLoc][xLoc][yLoc + 1] + heightMap[zLoc][xLoc + 1][yLoc + 1]) / 4 - (heightMap[modelZLoc][modelXLoc][modelYLoc] + heightMap[modelZLoc][modelXLoc + 1][modelYLoc] + heightMap[modelZLoc][modelXLoc][modelYLoc + 1] + heightMap[modelZLoc][modelXLoc + 1][modelYLoc + 1]) / 4; + WallObject wallObject = tile.wallObject; + if (wallObject != null && wallObject.renderable1 != null && wallObject.renderable1.vertexNormals != null) + mergeNormals(model, (Model) wallObject.renderable1, (xLoc - modelXLoc) * 128 + (1 - modelXSize) * 64, relativeHeightToModelTile, (yLoc - modelYLoc) * 128 + (1 - modelYSize) * 64, flag); + if (wallObject != null && wallObject.renderable2 != null && wallObject.renderable2.vertexNormals != null) + mergeNormals(model, (Model) wallObject.renderable2, (xLoc - modelXLoc) * 128 + (1 - modelXSize) * 64, relativeHeightToModelTile, (yLoc - modelYLoc) * 128 + (1 - modelYSize) * 64, flag); + for (int i = 0; i < tile.gameObjectIndex; i++) { + GameObject gameObject = tile.gameObjects[i]; + if (gameObject != null && gameObject.renderable != null && gameObject.renderable.vertexNormals != null) { + int tiledObjectXSize = (gameObject.xLocHigh - gameObject.xLocLow) + 1; + int tiledObjectYSize = (gameObject.yLocLow - gameObject.yLocHigh) + 1; + mergeNormals(model, (Model) gameObject.renderable, (gameObject.xLocLow - modelXLoc) * 128 + (tiledObjectXSize - modelXSize) * 64, relativeHeightToModelTile, (gameObject.yLocHigh - modelYLoc) * 128 + (tiledObjectYSize - modelYSize) * 64, flag); + } + } + } + } + } + startX--; //TODO why? + flag = false; + } + + } + + private void mergeNormals(Model model1, Model model2, int offsetX, int offsetY, int offsetZ, boolean flag) { + anInt488++; + int count = 0; + int second[] = model2.vertexX; + int secondVertices = model2.numVertices; + for (int model1Vertex = 0; model1Vertex < model1.numVertices; model1Vertex++) { + VertexNormal vertexNormal1 = model1.vertexNormals[model1Vertex]; + VertexNormal alsoVertexNormal1 = model1.alsoVertexNormals[model1Vertex]; + if (alsoVertexNormal1.magnitude != 0) { + int dY = model1.vertexY[model1Vertex] - offsetY; + if (dY <= model2.maximumYVertex) { + int dX = model1.vertexX[model1Vertex] - offsetX; + if (dX >= model2.minimumXVertex && dX <= model2.maximumXVertex) { + int k2 = model1.vertexZ[model1Vertex] - offsetZ; + if (k2 >= model2.minimumZVertex && k2 <= model2.maximumZVertex) { + for (int l2 = 0; l2 < secondVertices; l2++) { + VertexNormal vertexNormal2 = model2.vertexNormals[l2]; + VertexNormal alsoVertexNormal2 = model2.alsoVertexNormals[l2]; + if (dX == second[l2] && k2 == model2.vertexZ[l2] && dY == model2.vertexY[l2] && alsoVertexNormal2.magnitude != 0) { + vertexNormal1.normalX += alsoVertexNormal2.normalX; + vertexNormal1.normalY += alsoVertexNormal2.normalY; + vertexNormal1.normalZ += alsoVertexNormal2.normalZ; + vertexNormal1.magnitude += alsoVertexNormal2.magnitude; + vertexNormal2.normalX += alsoVertexNormal1.normalX; + vertexNormal2.normalY += alsoVertexNormal1.normalY; + vertexNormal2.normalZ += alsoVertexNormal1.normalZ; + vertexNormal2.magnitude += alsoVertexNormal1.magnitude; + count++; + anIntArray486[model1Vertex] = anInt488; + anIntArray487[l2] = anInt488; + } + } + + } + } + } + } + } + + if (count < 3 || !flag) + return; + for (int k1 = 0; k1 < model1.numTriangles; k1++) + if (anIntArray486[model1.facePointA[k1]] == anInt488 && anIntArray486[model1.facePointB[k1]] == anInt488 && anIntArray486[model1.facePointC[k1]] == anInt488) + model1.faceDrawType[k1] = -1; + + for (int l1 = 0; l1 < model2.numTriangles; l1++) + if (anIntArray487[model2.facePointA[l1]] == anInt488 && anIntArray487[model2.facePointB[l1]] == anInt488 && anIntArray487[model2.facePointC[l1]] == anInt488) + model2.faceDrawType[l1] = -1; + + } + + public void drawTileOnMinimapSprite(int pixels[], int drawIndex, int zLoc, int xLoc, int yLoc) { + int leftOverWidth = 512;// was parameter + Tile tile = tileArray[zLoc][xLoc][yLoc]; + if (tile == null) + return; + SimpleTile simpleTile = tile.mySimpleTile; + if (simpleTile != null) { + int tileRGB = simpleTile.getColourRGB(); + if (tileRGB == 0) + return; + for (int i = 0; i < 4; i++) { + pixels[drawIndex] = tileRGB; + pixels[drawIndex + 1] = tileRGB; + pixels[drawIndex + 2] = tileRGB; + pixels[drawIndex + 3] = tileRGB; + drawIndex += leftOverWidth; + } + return; + } + ShapedTile shapedTile = tile.myShapedTile; + + if (shapedTile == null) { + return; + } + + int shape = shapedTile.shape; + int rotation = shapedTile.rotation; + int underlayRGB = shapedTile.colourRGB; + int overlayRGB = shapedTile.colourRGBA; + int shapePoints[] = tileVertices[shape]; + int shapePointIndices[] = tileVertexIndices[rotation]; + int shapePtr = 0; + if (underlayRGB != 0) { + for (int i = 0; i < 4; i++) { + pixels[drawIndex] = shapePoints[shapePointIndices[shapePtr++]] != 0 ? overlayRGB : underlayRGB; + pixels[drawIndex + 1] = shapePoints[shapePointIndices[shapePtr++]] != 0 ? overlayRGB : underlayRGB; + pixels[drawIndex + 2] = shapePoints[shapePointIndices[shapePtr++]] != 0 ? overlayRGB : underlayRGB; + pixels[drawIndex + 3] = shapePoints[shapePointIndices[shapePtr++]] != 0 ? overlayRGB : underlayRGB; + drawIndex += leftOverWidth; + } + return; + } + for (int i = 0; i < 4; i++) { + if (shapePoints[shapePointIndices[shapePtr++]] != 0) + pixels[drawIndex] = overlayRGB; + if (shapePoints[shapePointIndices[shapePtr++]] != 0) + pixels[drawIndex + 1] = overlayRGB; + if (shapePoints[shapePointIndices[shapePtr++]] != 0) + pixels[drawIndex + 2] = overlayRGB; + if (shapePoints[shapePointIndices[shapePtr++]] != 0) + pixels[drawIndex + 3] = overlayRGB; + drawIndex += leftOverWidth; + } + } + + public static void setupViewport(int i, int j, int viewportWidth, int viewportHeight, int ai[]) { + anInt495 = 0; + anInt496 = 0; + SceneGraph.viewportWidth = viewportWidth; + SceneGraph.viewportHeight = viewportHeight; + viewportHalfWidth = viewportWidth / 2; + viewportHalfHeight = viewportHeight / 2; + boolean aflag[][][][] = new boolean[9][32][53][53]; + for (int zAngle = 128; zAngle <= 384; zAngle += 32) { + for (int xyAngle = 0; xyAngle < 2048; xyAngle += 64) { + camUpDownY = Model.SINE[zAngle]; + camUpDownX = Model.COSINE[zAngle]; + camLeftRightY = Model.SINE[xyAngle]; + camLeftRightX = Model.COSINE[xyAngle]; + int angularZSegment = (zAngle - 128) / 32; + int angularXYSegment = xyAngle / 64; + for (int xRelativeToCamera = -26; xRelativeToCamera <= 26; xRelativeToCamera++) { + for (int yRelativeToCamera = -26; yRelativeToCamera <= 26; yRelativeToCamera++) { + int xRelativeToCameraPos = xRelativeToCamera * 128; + int yRelativeToCameraPos = yRelativeToCamera * 128; + boolean flag2 = false; + for (int k4 = -i; k4 <= j; k4 += 128) { + if (!method311(ai[angularZSegment] + k4, yRelativeToCameraPos, xRelativeToCameraPos)) + continue; + flag2 = true; + break; + } + aflag[angularZSegment][angularXYSegment][xRelativeToCamera + 25 + 1][yRelativeToCamera + 25 + 1] = flag2; + } + } + } + } + + for (int angularZSegment = 0; angularZSegment < 8; angularZSegment++) { + for (int angularXYSegment = 0; angularXYSegment < 32; angularXYSegment++) { + for (int xRelativeToCamera = -25; xRelativeToCamera < 25; xRelativeToCamera++) { + for (int yRelativeToCamera = -25; yRelativeToCamera < 25; yRelativeToCamera++) { + boolean flag1 = false; + label0: for (int l3 = -1; l3 <= 1; l3++) { + for (int j4 = -1; j4 <= 1; j4++) { + if (aflag[angularZSegment][angularXYSegment][xRelativeToCamera + l3 + 25 + 1][yRelativeToCamera + j4 + 25 + 1]) + flag1 = true; + else if (aflag[angularZSegment][(angularXYSegment + 1) % 31][xRelativeToCamera + l3 + 25 + 1][yRelativeToCamera + j4 + 25 + 1]) + flag1 = true; + else if (aflag[angularZSegment + 1][angularXYSegment][xRelativeToCamera + l3 + 25 + 1][yRelativeToCamera + j4 + 25 + 1]) { + flag1 = true; + } else { + if (!aflag[angularZSegment + 1][(angularXYSegment + 1) % 31][xRelativeToCamera + l3 + 25 + 1][yRelativeToCamera + j4 + 25 + 1]) + continue; + flag1 = true; + } + break label0; + } + } + aBooleanArrayArrayArrayArray491[angularZSegment][angularXYSegment][xRelativeToCamera + 25][yRelativeToCamera + 25] = flag1; + } + } + } + } + } + + private static boolean method311(int i, int j, int k) { + int l = j * camLeftRightY + k * camLeftRightX >> 16; + int i1 = j * camLeftRightX - k * camLeftRightY >> 16; + int j1 = i * camUpDownY + i1 * camUpDownX >> 16; + int k1 = i * camUpDownX - i1 * camUpDownY >> 16; + if (j1 < 50 || j1 > 3500) + return false; + int l1 = viewportHalfWidth + (l << viewDistance) / j1; + int i2 = viewportHalfHeight + (k1 << viewDistance) / j1; + return l1 >= anInt495 && l1 <= viewportWidth && i2 >= anInt496 && i2 <= viewportHeight; + } + + /** + * Clicks on the screen and requests recomputation of the clicked tile. + * @param clickY The click's Y-coordinate on the applet. + * @param clickX The click's X-coordinate on the applet. + */ + public void clickTile(int clickY, int clickX) { + clicked = true; + clickScreenX = clickX; + clickScreenY = clickY; + clickedTileX = -1; + clickedTileY = -1; + } + + /** + * Renders the terrain. + * The coordinates use the WorldCoordinate Axes but the modelWorld coordinates. + * @param cameraXPos The cameraViewpoint's X-coordinate. + * @param cameraYPos The cameraViewpoint's Y-coordinate. + * @param camAngleXY The cameraAngle in the XY-plain. + * @param cameraZPos The cameraViewpoint's X-coordinate. + * @param planeZ The plain the camera's looking at. + * @param camAngleZ The cameraAngle on the Z-axis. + */ + public void render(int cameraXPos, int cameraYPos, int camAngleXY, int cameraZPos, int planeZ, int camAngleZ) { + if (cameraXPos < 0) + cameraXPos = 0; + else if (cameraXPos >= xRegionSize * 128) + cameraXPos = xRegionSize * 128 - 1; + if (cameraYPos < 0) + cameraYPos = 0; + else if (cameraYPos >= yRegionSize * 128) + cameraYPos = yRegionSize * 128 - 1; + anInt448++; + camUpDownY = Model.SINE[camAngleZ]; + camUpDownX = Model.COSINE[camAngleZ]; + camLeftRightY = Model.SINE[camAngleXY]; + camLeftRightX = Model.COSINE[camAngleXY]; + aBooleanArrayArray492 = aBooleanArrayArrayArrayArray491[(camAngleZ - 128) / 32][camAngleXY / 64]; + xCameraPos = cameraXPos; + zCameraPos = cameraZPos; + yCameraPos = cameraYPos; + xCameraTile = cameraXPos / 128; + yCameraTile = cameraYPos / 128; + currentRenderPlane = planeZ; + cameraLowTileX = xCameraTile - 25; + if (cameraLowTileX < 0) + cameraLowTileX = 0; + cameraLowTileY = yCameraTile - 25; + if (cameraLowTileY < 0) + cameraLowTileY = 0; + cameraHighTileX = xCameraTile + 25; + if (cameraHighTileX > xRegionSize) + cameraHighTileX = xRegionSize; + cameraHighTileY = yCameraTile + 25; + if (cameraHighTileY > yRegionSize) + cameraHighTileY = yRegionSize; + method319(); + anInt446 = 0; + for (int zLoc = zAnInt442; zLoc < numberOfZ; zLoc++) { + Tile planeTiles[][] = tileArray[zLoc]; + for (int xLoc = cameraLowTileX; xLoc < cameraHighTileX; xLoc++) { + for (int yLoc = cameraLowTileY; yLoc < cameraHighTileY; yLoc++) { + Tile tile = planeTiles[xLoc][yLoc]; + if (tile != null) + if (tile.logicHeight > planeZ || !aBooleanArrayArray492[(xLoc - xCameraTile) + 25][(yLoc - yCameraTile) + 25] && heightMap[zLoc][xLoc][yLoc] - cameraZPos < 2000) { + tile.aBoolean1322 = false; + tile.aBoolean1323 = false; + tile.someTileMask = 0; + } else { + tile.aBoolean1322 = true; + tile.aBoolean1323 = true; + tile.aBoolean1324 = tile.gameObjectIndex > 0; + anInt446++; + } + } + } + } + + for (int zLoc = zAnInt442; zLoc < numberOfZ; zLoc++) { + Tile plane[][] = tileArray[zLoc]; + for (int dX = -25; dX <= 0; dX++) { + int xLoc1 = xCameraTile + dX; + int xLoc2 = xCameraTile - dX; + if (xLoc1 >= cameraLowTileX || xLoc2 < cameraHighTileX) { + for (int dY = -25; dY <= 0; dY++) { + int yLoc1 = yCameraTile + dY; + int yLoc2 = yCameraTile - dY; + if (xLoc1 >= cameraLowTileX) { + if (yLoc1 >= cameraLowTileY) { + Tile tile = plane[xLoc1][yLoc1]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, true); + } + if (yLoc2 < cameraHighTileY) { + Tile tile = plane[xLoc1][yLoc2]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, true); + } + } + if (xLoc2 < cameraHighTileX) { + if (yLoc1 >= cameraLowTileY) { + Tile tile = plane[xLoc2][yLoc1]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, true); + } + if (yLoc2 < cameraHighTileY) { + Tile tile = plane[xLoc2][yLoc2]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, true); + } + } + if (anInt446 == 0) { + clicked = false; + return; + } + } + } + } + } + + for (int zLoc = zAnInt442; zLoc < numberOfZ; zLoc++) { + Tile plane[][] = tileArray[zLoc]; + for (int dX = -25; dX <= 0; dX++) { + int xLoc1 = xCameraTile + dX; + int xLoc2 = xCameraTile - dX; + if (xLoc1 >= cameraLowTileX || xLoc2 < cameraHighTileX) { + for (int dY = -25; dY <= 0; dY++) { + int yLoc1 = yCameraTile + dY; + int yLoc2 = yCameraTile - dY; + if (xLoc1 >= cameraLowTileX) { + if (yLoc1 >= cameraLowTileY) { + Tile tile = plane[xLoc1][yLoc1]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, false); + } + if (yLoc2 < cameraHighTileY) { + Tile tile = plane[xLoc1][yLoc2]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, false); + } + } + if (xLoc2 < cameraHighTileX) { + if (yLoc1 >= cameraLowTileY) { + Tile tile = plane[xLoc2][yLoc1]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, false); + } + if (yLoc2 < cameraHighTileY) { + Tile tile = plane[xLoc2][yLoc2]; + if (tile != null && tile.aBoolean1322) + renderTileF(tile, false); + } + } + if (anInt446 == 0) { + clicked = false; + return; + } + } + + } + } + + } + + clicked = false; + } + + private void renderTileF(Tile tile, boolean flag) { + tileDeque.insertHead(tile); + do { + Tile currentTile; + do { + currentTile = (Tile) tileDeque.popHead(); + if (currentTile == null) + return; + } while (!currentTile.aBoolean1323); + int i = currentTile.anInt1308; + int j = currentTile.anInt1309; + int k = currentTile.z1AnInt1307; + int l = currentTile.anInt1310; + Tile aclass30_sub3[][] = tileArray[k]; + if (currentTile.aBoolean1322) { + if (flag) { + if (k > 0) { + Tile class30_sub3_2 = tileArray[k - 1][i][j]; + if (class30_sub3_2 != null && class30_sub3_2.aBoolean1323) + continue; + } + if (i <= xCameraTile && i > cameraLowTileX) { + Tile class30_sub3_3 = aclass30_sub3[i - 1][j]; + if (class30_sub3_3 != null && class30_sub3_3.aBoolean1323 + && (class30_sub3_3.aBoolean1322 || (currentTile.totalTiledObjectMask & 1) == 0)) + continue; + } + if (i >= xCameraTile && i < cameraHighTileX - 1) { + Tile class30_sub3_4 = aclass30_sub3[i + 1][j]; + if (class30_sub3_4 != null && class30_sub3_4.aBoolean1323 + && (class30_sub3_4.aBoolean1322 || (currentTile.totalTiledObjectMask & 4) == 0)) + continue; + } + if (j <= yCameraTile && j > cameraLowTileY) { + Tile class30_sub3_5 = aclass30_sub3[i][j - 1]; + if (class30_sub3_5 != null && class30_sub3_5.aBoolean1323 + && (class30_sub3_5.aBoolean1322 || (currentTile.totalTiledObjectMask & 8) == 0)) + continue; + } + if (j >= yCameraTile && j < cameraHighTileY - 1) { + Tile class30_sub3_6 = aclass30_sub3[i][j + 1]; + if (class30_sub3_6 != null && class30_sub3_6.aBoolean1323 + && (class30_sub3_6.aBoolean1322 || (currentTile.totalTiledObjectMask & 2) == 0)) + continue; + } + } else { + flag = true; + } + currentTile.aBoolean1322 = false; + if (currentTile.firstFloorTile != null) { + Tile class30_sub3_7 = currentTile.firstFloorTile; + if (class30_sub3_7.mySimpleTile != null) { + if (!method320(0, i, j)) + method315(class30_sub3_7.mySimpleTile, 0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, i, j); + } else if (class30_sub3_7.myShapedTile != null && !method320(0, i, j)) + method316(i, camUpDownY, camLeftRightY, + class30_sub3_7.myShapedTile, camUpDownX, j, + camLeftRightX); + WallObject class10 = class30_sub3_7.wallObject; + if (class10 != null) + class10.renderable1.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + class10.xPos - xCameraPos, class10.zPos - zCameraPos, class10.yPos - yCameraPos, + class10.uid); + for (int i2 = 0; i2 < class30_sub3_7.gameObjectIndex; i2++) { + GameObject class28 = class30_sub3_7.gameObjects[i2]; + if (class28 != null) + class28.renderable.renderAtPoint(class28.turnValue, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, class28.xPos - xCameraPos, class28.tileHeight - zCameraPos, class28.yPos - yCameraPos, class28.uid); + } + + } + boolean flag1 = false; + if (currentTile.mySimpleTile != null) { + if (!method320(l, i, j)) { + flag1 = true; + method315(currentTile.mySimpleTile, l, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, i, j); + } + } else if (currentTile.myShapedTile != null && !method320(l, i, j)) { + flag1 = true; + method316(i, camUpDownY, camLeftRightY, + currentTile.myShapedTile, camUpDownX, j, camLeftRightX); + } + int j1 = 0; + int j2 = 0; + WallObject class10_3 = currentTile.wallObject; + WallDecoration class26_1 = currentTile.wallDecoration; + if (class10_3 != null || class26_1 != null) { + if (xCameraTile == i) + j1++; + else if (xCameraTile < i) + j1 += 2; + if (yCameraTile == j) + j1 += 3; + else if (yCameraTile > j) + j1 += 6; + j2 = anIntArray478[j1]; + currentTile.anInt1328 = anIntArray480[j1]; + } + if (class10_3 != null) { + if ((class10_3.orientation1 & anIntArray479[j1]) != 0) { + if (class10_3.orientation1 == 16) { + currentTile.someTileMask = 3; + currentTile.anInt1326 = anIntArray481[j1]; + currentTile.anInt1327 = 3 - currentTile.anInt1326; + } else if (class10_3.orientation1 == 32) { + currentTile.someTileMask = 6; + currentTile.anInt1326 = anIntArray482[j1]; + currentTile.anInt1327 = 6 - currentTile.anInt1326; + } else if (class10_3.orientation1 == 64) { + currentTile.someTileMask = 12; + currentTile.anInt1326 = anIntArray483[j1]; + currentTile.anInt1327 = 12 - currentTile.anInt1326; + } else { + currentTile.someTileMask = 9; + currentTile.anInt1326 = anIntArray484[j1]; + currentTile.anInt1327 = 9 - currentTile.anInt1326; + } + } else { + currentTile.someTileMask = 0; + } + if ((class10_3.orientation1 & j2) != 0 && !method321(l, i, j, class10_3.orientation1)) + class10_3.renderable1.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + class10_3.xPos - xCameraPos, class10_3.zPos - zCameraPos, + class10_3.yPos - yCameraPos, class10_3.uid); + if ((class10_3.orientation2 & j2) != 0 && !method321(l, i, j, class10_3.orientation2)) + class10_3.renderable2.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + class10_3.xPos - xCameraPos, class10_3.zPos - zCameraPos, + class10_3.yPos - yCameraPos, class10_3.uid); + } + if (class26_1 != null && !method322(l, i, j, class26_1.renderable.modelBaseY)) + if ((class26_1.orientation & j2) != 0) + class26_1.renderable.renderAtPoint(class26_1.orientation2, camUpDownY, camUpDownX, camLeftRightY, + camLeftRightX, class26_1.xPos - xCameraPos, class26_1.zPos - zCameraPos, + class26_1.yPos - yCameraPos, class26_1.uid); + else if ((class26_1.orientation & 0x300) != 0) { + int j4 = class26_1.xPos - xCameraPos; + int l5 = class26_1.zPos - zCameraPos; + int k6 = class26_1.yPos - yCameraPos; + int i8 = class26_1.orientation2; + int k9; + if (i8 == 1 || i8 == 2) + k9 = -j4; + else + k9 = j4; + int k10; + if (i8 == 2 || i8 == 3) + k10 = -k6; + else + k10 = k6; + if ((class26_1.orientation & 0x100) != 0 && k10 < k9) { + int i11 = j4 + anIntArray463[i8]; + int k11 = k6 + anIntArray464[i8]; + class26_1.renderable.renderAtPoint(i8 * 512 + 256, camUpDownY, camUpDownX, camLeftRightY, + camLeftRightX, i11, l5, k11, class26_1.uid); + } + if ((class26_1.orientation & 0x200) != 0 && k10 > k9) { + int j11 = j4 + anIntArray465[i8]; + int l11 = k6 + anIntArray466[i8]; + class26_1.renderable.renderAtPoint(i8 * 512 + 1280 & 0x7ff, camUpDownY, camUpDownX, + camLeftRightY, camLeftRightX, j11, l5, l11, class26_1.uid); + } + } + if (flag1) { + GroundDecoration class49 = currentTile.groundDecoration; + if (class49 != null) + class49.renderable.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + class49.xPos - xCameraPos, class49.zPos - zCameraPos, class49.yPos - yCameraPos, + class49.uid); + GroundItemTile object4_1 = currentTile.groundItemTile; + if (object4_1 != null && object4_1.itemDropHeight == 0) { + if (object4_1.lowerNode != null) + object4_1.lowerNode.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + object4_1.xPos - xCameraPos, object4_1.zPos - zCameraPos, + object4_1.yPos - yCameraPos, object4_1.uid); + if (object4_1.middleNode != null) + object4_1.middleNode.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + object4_1.xPos - xCameraPos, object4_1.zPos - zCameraPos, + object4_1.yPos - yCameraPos, object4_1.uid); + if (object4_1.topNode != null) + object4_1.topNode.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + object4_1.xPos - xCameraPos, object4_1.zPos - zCameraPos, + object4_1.yPos - yCameraPos, object4_1.uid); + } + } + int k4 = currentTile.totalTiledObjectMask; + if (k4 != 0) { + if (i < xCameraTile && (k4 & 4) != 0) { + Tile class30_sub3_17 = aclass30_sub3[i + 1][j]; + if (class30_sub3_17 != null && class30_sub3_17.aBoolean1323) + tileDeque.insertHead(class30_sub3_17); + } + if (j < yCameraTile && (k4 & 2) != 0) { + Tile class30_sub3_18 = aclass30_sub3[i][j + 1]; + if (class30_sub3_18 != null && class30_sub3_18.aBoolean1323) + tileDeque.insertHead(class30_sub3_18); + } + if (i > xCameraTile && (k4 & 1) != 0) { + Tile class30_sub3_19 = aclass30_sub3[i - 1][j]; + if (class30_sub3_19 != null && class30_sub3_19.aBoolean1323) + tileDeque.insertHead(class30_sub3_19); + } + if (j > yCameraTile && (k4 & 8) != 0) { + Tile class30_sub3_20 = aclass30_sub3[i][j - 1]; + if (class30_sub3_20 != null && class30_sub3_20.aBoolean1323) + tileDeque.insertHead(class30_sub3_20); + } + } + } + if (currentTile.someTileMask != 0) { + boolean flag2 = true; + for (int k1 = 0; k1 < currentTile.gameObjectIndex; k1++) { + if (currentTile.gameObjects[k1].anInt528 == anInt448 || (currentTile.tiledObjectMasks[k1] + & currentTile.someTileMask) != currentTile.anInt1326) + continue; + flag2 = false; + break; + } + + if (flag2) { + WallObject class10_1 = currentTile.wallObject; + if (!method321(l, i, j, class10_1.orientation1)) + class10_1.renderable1.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + class10_1.xPos - xCameraPos, class10_1.zPos - zCameraPos, + class10_1.yPos - yCameraPos, class10_1.uid); + currentTile.someTileMask = 0; + } + } + if (currentTile.aBoolean1324) + try { + int i1 = currentTile.gameObjectIndex; + currentTile.aBoolean1324 = false; + int l1 = 0; + label0: for (int k2 = 0; k2 < i1; k2++) { + GameObject class28_1 = currentTile.gameObjects[k2]; + if (class28_1.anInt528 == anInt448) + continue; + for (int k3 = class28_1.xLocLow; k3 <= class28_1.xLocHigh; k3++) { + for (int l4 = class28_1.yLocHigh; l4 <= class28_1.yLocLow; l4++) { + Tile class30_sub3_21 = aclass30_sub3[k3][l4]; + if (class30_sub3_21.aBoolean1322) { + currentTile.aBoolean1324 = true; + } else { + if (class30_sub3_21.someTileMask == 0) + continue; + int l6 = 0; + if (k3 > class28_1.xLocLow) + l6++; + if (k3 < class28_1.xLocHigh) + l6 += 4; + if (l4 > class28_1.yLocHigh) + l6 += 8; + if (l4 < class28_1.yLocLow) + l6 += 2; + if ((l6 & class30_sub3_21.someTileMask) != currentTile.anInt1327) + continue; + currentTile.aBoolean1324 = true; + } + continue label0; + } + + } + + interactableObjects[l1++] = class28_1; + int i5 = xCameraTile - class28_1.xLocLow; + int i6 = class28_1.xLocHigh - xCameraTile; + if (i6 > i5) + i5 = i6; + int i7 = yCameraTile - class28_1.yLocHigh; + int j8 = class28_1.yLocLow - yCameraTile; + if (j8 > i7) + class28_1.anInt527 = i5 + j8; + else + class28_1.anInt527 = i5 + i7; + } + + while (l1 > 0) { + int i3 = -50; + int l3 = -1; + for (int j5 = 0; j5 < l1; j5++) { + GameObject class28_2 = interactableObjects[j5]; + if (class28_2.anInt528 != anInt448) + if (class28_2.anInt527 > i3) { + i3 = class28_2.anInt527; + l3 = j5; + } else if (class28_2.anInt527 == i3) { + int j7 = class28_2.xPos - xCameraPos; + int k8 = class28_2.yPos - yCameraPos; + int l9 = interactableObjects[l3].xPos - xCameraPos; + int l10 = interactableObjects[l3].yPos - yCameraPos; + if (j7 * j7 + k8 * k8 > l9 * l9 + l10 * l10) + l3 = j5; + } + } + + if (l3 == -1) + break; + GameObject class28_3 = interactableObjects[l3]; + class28_3.anInt528 = anInt448; + if (!method323(l, class28_3.xLocLow, class28_3.xLocHigh, class28_3.yLocHigh, + class28_3.yLocLow, class28_3.renderable.modelBaseY)) + class28_3.renderable.renderAtPoint(class28_3.turnValue, camUpDownY, camUpDownX, camLeftRightY, + camLeftRightX, class28_3.xPos - xCameraPos, class28_3.tileHeight - zCameraPos, + class28_3.yPos - yCameraPos, class28_3.uid); + for (int k7 = class28_3.xLocLow; k7 <= class28_3.xLocHigh; k7++) { + for (int l8 = class28_3.yLocHigh; l8 <= class28_3.yLocLow; l8++) { + Tile class30_sub3_22 = aclass30_sub3[k7][l8]; + if (class30_sub3_22.someTileMask != 0) + tileDeque.insertHead(class30_sub3_22); + else if ((k7 != i || l8 != j) && class30_sub3_22.aBoolean1323) + tileDeque.insertHead(class30_sub3_22); + } + + } + + } + if (currentTile.aBoolean1324) + continue; + } catch (Exception _ex) { + currentTile.aBoolean1324 = false; + } + if (!currentTile.aBoolean1323 || currentTile.someTileMask != 0) + continue; + if (i <= xCameraTile && i > cameraLowTileX) { + Tile class30_sub3_8 = aclass30_sub3[i - 1][j]; + if (class30_sub3_8 != null && class30_sub3_8.aBoolean1323) + continue; + } + if (i >= xCameraTile && i < cameraHighTileX - 1) { + Tile class30_sub3_9 = aclass30_sub3[i + 1][j]; + if (class30_sub3_9 != null && class30_sub3_9.aBoolean1323) + continue; + } + if (j <= yCameraTile && j > cameraLowTileY) { + Tile class30_sub3_10 = aclass30_sub3[i][j - 1]; + if (class30_sub3_10 != null && class30_sub3_10.aBoolean1323) + continue; + } + if (j >= yCameraTile && j < cameraHighTileY - 1) { + Tile class30_sub3_11 = aclass30_sub3[i][j + 1]; + if (class30_sub3_11 != null && class30_sub3_11.aBoolean1323) + continue; + } + currentTile.aBoolean1323 = false; + anInt446--; + GroundItemTile object4 = currentTile.groundItemTile; + if (object4 != null && object4.itemDropHeight != 0) { + if (object4.lowerNode != null) + object4.lowerNode.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + object4.xPos - xCameraPos, object4.zPos - zCameraPos - object4.itemDropHeight, + object4.yPos - yCameraPos, object4.uid); + if (object4.middleNode != null) + object4.middleNode.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + object4.xPos - xCameraPos, object4.zPos - zCameraPos - object4.itemDropHeight, + object4.yPos - yCameraPos, object4.uid); + if (object4.topNode != null) + object4.topNode.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + object4.xPos - xCameraPos, object4.zPos - zCameraPos - object4.itemDropHeight, + object4.yPos - yCameraPos, object4.uid); + } + if (currentTile.anInt1328 != 0) { + WallDecoration class26 = currentTile.wallDecoration; + if (class26 != null && !method322(l, i, j, class26.renderable.modelBaseY)) + if ((class26.orientation & currentTile.anInt1328) != 0) + class26.renderable.renderAtPoint(class26.orientation2, camUpDownY, camUpDownX, camLeftRightY, + camLeftRightX, class26.xPos - xCameraPos, class26.zPos - zCameraPos, + class26.yPos - yCameraPos, class26.uid); + else if ((class26.orientation & 0x300) != 0) { + int l2 = class26.xPos - xCameraPos; + int j3 = class26.zPos - zCameraPos; + int i4 = class26.yPos - yCameraPos; + int k5 = class26.orientation2; + int j6; + if (k5 == 1 || k5 == 2) + j6 = -l2; + else + j6 = l2; + int l7; + if (k5 == 2 || k5 == 3) + l7 = -i4; + else + l7 = i4; + if ((class26.orientation & 0x100) != 0 && l7 >= j6) { + int i9 = l2 + anIntArray463[k5]; + int i10 = i4 + anIntArray464[k5]; + class26.renderable.renderAtPoint(k5 * 512 + 256, camUpDownY, camUpDownX, camLeftRightY, + camLeftRightX, i9, j3, i10, class26.uid); + } + if ((class26.orientation & 0x200) != 0 && l7 <= j6) { + int j9 = l2 + anIntArray465[k5]; + int j10 = i4 + anIntArray466[k5]; + class26.renderable.renderAtPoint(k5 * 512 + 1280 & 0x7ff, camUpDownY, camUpDownX, + camLeftRightY, camLeftRightX, j9, j3, j10, class26.uid); + } + } + WallObject class10_2 = currentTile.wallObject; + if (class10_2 != null) { + if ((class10_2.orientation2 & currentTile.anInt1328) != 0 + && !method321(l, i, j, class10_2.orientation2)) + class10_2.renderable2.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + class10_2.xPos - xCameraPos, class10_2.zPos - zCameraPos, + class10_2.yPos - yCameraPos, class10_2.uid); + if ((class10_2.orientation1 & currentTile.anInt1328) != 0 + && !method321(l, i, j, class10_2.orientation1)) + class10_2.renderable1.renderAtPoint(0, camUpDownY, camUpDownX, camLeftRightY, camLeftRightX, + class10_2.xPos - xCameraPos, class10_2.zPos - zCameraPos, + class10_2.yPos - yCameraPos, class10_2.uid); + } + } + if (k < numberOfZ - 1) { + Tile class30_sub3_12 = tileArray[k + 1][i][j]; + if (class30_sub3_12 != null && class30_sub3_12.aBoolean1323) + tileDeque.insertHead(class30_sub3_12); + } + if (i < xCameraTile) { + Tile class30_sub3_13 = aclass30_sub3[i + 1][j]; + if (class30_sub3_13 != null && class30_sub3_13.aBoolean1323) + tileDeque.insertHead(class30_sub3_13); + } + if (j < yCameraTile) { + Tile class30_sub3_14 = aclass30_sub3[i][j + 1]; + if (class30_sub3_14 != null && class30_sub3_14.aBoolean1323) + tileDeque.insertHead(class30_sub3_14); + } + if (i > xCameraTile) { + Tile class30_sub3_15 = aclass30_sub3[i - 1][j]; + if (class30_sub3_15 != null && class30_sub3_15.aBoolean1323) + tileDeque.insertHead(class30_sub3_15); + } + if (j > yCameraTile) { + Tile class30_sub3_16 = aclass30_sub3[i][j - 1]; + if (class30_sub3_16 != null && class30_sub3_16.aBoolean1323) + tileDeque.insertHead(class30_sub3_16); + } + } while (true); + } + + private void method315(SimpleTile simpleTile, int i, int j, int k, int l, int i1, int j1, int k1) { + int l1; + int i2 = l1 = (j1 << 7) - xCameraPos; + int j2; + int k2 = j2 = (k1 << 7) - yCameraPos; + int l2; + int i3 = l2 = i2 + 128; + int j3; + int k3 = j3 = k2 + 128; + int l3 = heightMap[i][j1][k1] - zCameraPos; + int i4 = heightMap[i][j1 + 1][k1] - zCameraPos; + int j4 = heightMap[i][j1 + 1][k1 + 1] - zCameraPos; + int k4 = heightMap[i][j1][k1 + 1] - zCameraPos; + int l4 = k2 * l + i2 * i1 >> 16; + k2 = k2 * i1 - i2 * l >> 16; + i2 = l4; + l4 = l3 * k - k2 * j >> 16; + k2 = l3 * j + k2 * k >> 16; + l3 = l4; + if (k2 < 50) + return; + l4 = j2 * l + i3 * i1 >> 16; + j2 = j2 * i1 - i3 * l >> 16; + i3 = l4; + l4 = i4 * k - j2 * j >> 16; + j2 = i4 * j + j2 * k >> 16; + i4 = l4; + if (j2 < 50) + return; + l4 = k3 * l + l2 * i1 >> 16; + k3 = k3 * i1 - l2 * l >> 16; + l2 = l4; + l4 = j4 * k - k3 * j >> 16; + k3 = j4 * j + k3 * k >> 16; + j4 = l4; + if (k3 < 50) + return; + l4 = j3 * l + l1 * i1 >> 16; + j3 = j3 * i1 - l1 * l >> 16; + l1 = l4; + l4 = k4 * k - j3 * j >> 16; + j3 = k4 * j + j3 * k >> 16; + k4 = l4; + if (j3 < 50) + return; + int i5 = Rasterizer3D.originViewX + (i2 << viewDistance) / k2; + int j5 = Rasterizer3D.originViewY + (l3 << viewDistance) / k2; + int k5 = Rasterizer3D.originViewX + (i3 << viewDistance) / j2; + int l5 = Rasterizer3D.originViewY + (i4 << viewDistance) / j2; + int i6 = Rasterizer3D.originViewX + (l2 << viewDistance) / k3; + int j6 = Rasterizer3D.originViewY + (j4 << viewDistance) / k3; + int k6 = Rasterizer3D.originViewX + (l1 << viewDistance) / j3; + int l6 = Rasterizer3D.originViewY + (k4 << viewDistance) / j3; + Rasterizer3D.alpha = 0; + if ((i6 - k6) * (l5 - l6) - (j6 - l6) * (k5 - k6) > 0) { + Rasterizer3D.textureOutOfDrawingBounds = i6 < 0 || k6 < 0 || k5 < 0 || i6 > Rasterizer2D.lastX || k6 > Rasterizer2D.lastX || k5 > Rasterizer2D.lastX; + if (clicked && method318(clickScreenX, clickScreenY, j6, l6, l5, i6, k6, k5)) { + clickedTileX = j1; + clickedTileY = k1; + } + if (simpleTile.getTexture() == -1) { + if (simpleTile.getCenterColor() != 0xbc614e) + Rasterizer3D.drawShadedTriangle(j6, l6, l5, i6, k6, k5, simpleTile.getCenterColor(), simpleTile.getEastColor(), simpleTile.getNorthColor(), k3, j3, j2); + } else if (!lowMem) { + if (simpleTile.isFlat()) + Rasterizer3D.drawTexturedTriangle(j6, l6, l5, i6, k6, k5, simpleTile.getCenterColor(), simpleTile.getEastColor(), simpleTile.getNorthColor(), i2, i3, l1, l3, i4, k4, k2, j2, j3, simpleTile.getTexture(), k3, j3, j2); + else + Rasterizer3D.drawTexturedTriangle(j6, l6, l5, i6, k6, k5, simpleTile.getCenterColor(), simpleTile.getEastColor(), simpleTile.getNorthColor(), l2, l1, i3, j4, k4, i4, k3, j3, j2, simpleTile.getTexture(), k3, j3, j2); + } else { + int textureColor = TEXTURE_COLORS[simpleTile.getTexture()]; + Rasterizer3D.drawShadedTriangle(j6, l6, l5, i6, k6, k5, light(textureColor, simpleTile.getCenterColor()), light(textureColor, simpleTile.getEastColor()), light(textureColor, simpleTile.getNorthColor()), k3, j3, j2); + } + } + if ((i5 - k5) * (l6 - l5) - (j5 - l5) * (k6 - k5) > 0) { + Rasterizer3D.textureOutOfDrawingBounds = i5 < 0 || k5 < 0 || k6 < 0 || i5 > Rasterizer2D.lastX || k5 > Rasterizer2D.lastX || k6 > Rasterizer2D.lastX; + if (clicked && method318(clickScreenX, clickScreenY, j5, l5, l6, i5, k5, k6)) { + clickedTileX = j1; + clickedTileY = k1; + } + if (simpleTile.getTexture() == -1) { + if (simpleTile.getNorthEastColor() != 0xbc614e) { + Rasterizer3D.drawShadedTriangle(j5, l5, l6, i5, k5, k6, simpleTile.getNorthEastColor(), simpleTile.getNorthColor(), + simpleTile.getEastColor(), k2, j2, j3); + } + } else { + if (!lowMem) { + Rasterizer3D.drawTexturedTriangle(j5, l5, l6, i5, k5, k6, simpleTile.getNorthEastColor(), simpleTile.getNorthColor(), + simpleTile.getEastColor(), i2, i3, l1, l3, i4, k4, k2, j2, j3, simpleTile.getTexture(), k2, j2, j3); + return; + } + int j7 = TEXTURE_COLORS[simpleTile.getTexture()]; + Rasterizer3D.drawShadedTriangle(j5, l5, l6, i5, k5, k6, light(j7, simpleTile.getNorthEastColor()), light(j7, simpleTile.getNorthColor()), light(j7, simpleTile.getEastColor()), k2, j2, j3); + } + } + } + + private void method316(int i, int j, int k, ShapedTile class40, int l, int i1, int j1) { + int k1 = class40.anIntArray673.length; + for (int l1 = 0; l1 < k1; l1++) { + int i2 = class40.anIntArray673[l1] - xCameraPos; + int k2 = class40.anIntArray674[l1] - zCameraPos; + int i3 = class40.anIntArray675[l1] - yCameraPos; + int k3 = i3 * k + i2 * j1 >> 16; + i3 = i3 * j1 - i2 * k >> 16; + i2 = k3; + k3 = k2 * l - i3 * j >> 16; + i3 = k2 * j + i3 * l >> 16; + k2 = k3; + if (i3 < 50) + return; + if (class40.anIntArray682 != null) { + ShapedTile.anIntArray690[l1] = i2; + ShapedTile.anIntArray691[l1] = k2; + ShapedTile.anIntArray692[l1] = i3; + } + ShapedTile.anIntArray688[l1] = Rasterizer3D.originViewX + (i2 << viewDistance) / i3; + ShapedTile.anIntArray689[l1] = Rasterizer3D.originViewY + (k2 << viewDistance) / i3; + ShapedTile.depthPoint[l1] = i3; + } + + Rasterizer3D.alpha = 0; + k1 = class40.anIntArray679.length; + for (int j2 = 0; j2 < k1; j2++) { + int l2 = class40.anIntArray679[j2]; + int j3 = class40.anIntArray680[j2]; + int l3 = class40.anIntArray681[j2]; + int i4 = ShapedTile.anIntArray688[l2]; + int j4 = ShapedTile.anIntArray688[j3]; + int k4 = ShapedTile.anIntArray688[l3]; + int l4 = ShapedTile.anIntArray689[l2]; + int i5 = ShapedTile.anIntArray689[j3]; + int j5 = ShapedTile.anIntArray689[l3]; + if ((i4 - j4) * (j5 - i5) - (l4 - i5) * (k4 - j4) > 0) { + Rasterizer3D.textureOutOfDrawingBounds = i4 < 0 || j4 < 0 || k4 < 0 || i4 > Rasterizer2D.lastX + || j4 > Rasterizer2D.lastX || k4 > Rasterizer2D.lastX; + if (clicked && method318(clickScreenX, clickScreenY, l4, i5, j5, i4, j4, k4)) { + clickedTileX = i; + clickedTileY = i1; + } + Rasterizer3D.drawDepthTriangle(i4, j4, k4, l4, i5, j5, ShapedTile.depthPoint[l2], ShapedTile.depthPoint[j3], + ShapedTile.depthPoint[l3]); + if (class40.anIntArray682 == null || class40.anIntArray682[j2] == -1) { + if (class40.anIntArray676[j2] != 0xbc614e) + Rasterizer3D.drawShadedTriangle(l4, i5, j5, i4, j4, k4, class40.anIntArray676[j2], + class40.anIntArray677[j2], class40.anIntArray678[j2], ShapedTile.depthPoint[l2], + ShapedTile.depthPoint[j3], ShapedTile.depthPoint[l3]); + } else if (!lowMem) { + if (class40.flat) + Rasterizer3D.drawTexturedTriangle(l4, i5, j5, i4, j4, k4, class40.anIntArray676[j2], + class40.anIntArray677[j2], class40.anIntArray678[j2], ShapedTile.anIntArray690[0], + ShapedTile.anIntArray690[1], ShapedTile.anIntArray690[3], ShapedTile.anIntArray691[0], + ShapedTile.anIntArray691[1], ShapedTile.anIntArray691[3], ShapedTile.anIntArray692[0], + ShapedTile.anIntArray692[1], ShapedTile.anIntArray692[3], class40.anIntArray682[j2], + ShapedTile.depthPoint[l2], ShapedTile.depthPoint[j3], ShapedTile.depthPoint[l3]); + else + Rasterizer3D.drawTexturedTriangle(l4, i5, j5, i4, j4, k4, class40.anIntArray676[j2], + class40.anIntArray677[j2], class40.anIntArray678[j2], ShapedTile.anIntArray690[l2], + ShapedTile.anIntArray690[j3], ShapedTile.anIntArray690[l3], ShapedTile.anIntArray691[l2], + ShapedTile.anIntArray691[j3], ShapedTile.anIntArray691[l3], ShapedTile.anIntArray692[l2], + ShapedTile.anIntArray692[j3], ShapedTile.anIntArray692[l3], class40.anIntArray682[j2], + ShapedTile.depthPoint[l2], ShapedTile.depthPoint[j3], ShapedTile.depthPoint[l3]); + } else { + int k5 = TEXTURE_COLORS[class40.anIntArray682[j2]]; + Rasterizer3D.drawShadedTriangle(l4, i5, j5, i4, j4, k4, light(k5, class40.anIntArray676[j2]), + light(k5, class40.anIntArray677[j2]), light(k5, class40.anIntArray678[j2]), + ShapedTile.depthPoint[l2], ShapedTile.depthPoint[j3], ShapedTile.depthPoint[l3]); + } + } + } + } + + private int light(int j, int k) { + k = 127 - k; + k = (k * (j & 0x7f)) / 160; + if (k < 2) + k = 2; + else if (k > 126) + k = 126; + return (j & 0xff80) + k; + } + + private boolean method318(int i, int j, int k, int l, int i1, int j1, int k1, int l1) { + if (j < k && j < l && j < i1) + return false; + if (j > k && j > l && j > i1) + return false; + if (i < j1 && i < k1 && i < l1) + return false; + if (i > j1 && i > k1 && i > l1) + return false; + int i2 = (j - k) * (k1 - j1) - (i - j1) * (l - k); + int j2 = (j - i1) * (j1 - l1) - (i - l1) * (k - i1); + int k2 = (j - l) * (l1 - k1) - (i - k1) * (i1 - l); + return i2 * k2 > 0 && k2 * j2 > 0; + } + + private void method319() { + int sceneClusterCount = sceneClusterCounts[currentRenderPlane]; + SceneCluster sceneClusters[] = SceneGraph.sceneClusters[currentRenderPlane]; + anInt475 = 0; + for (int sceneIndex = 0; sceneIndex < sceneClusterCount; sceneIndex++) { + SceneCluster sceneCluster = sceneClusters[sceneIndex]; + if (sceneCluster.orientation == 1) { //YZ-plane + int relativeX = (sceneCluster.startXLoc - xCameraTile) + 25; + if (relativeX < 0 || relativeX > 50) + continue; + int minRelativeY = (sceneCluster.startYLoc - yCameraTile) + 25; + if (minRelativeY < 0) + minRelativeY = 0; + int maxRelativeY = (sceneCluster.endYLoc - yCameraTile) + 25; + if (maxRelativeY > 50) + maxRelativeY = 50; + boolean flag = false; + while (minRelativeY <= maxRelativeY) + if (aBooleanArrayArray492[relativeX][minRelativeY++]) { + flag = true; + break; + } + if (!flag) + continue; + int dXPos = xCameraPos - sceneCluster.startXPos; + if (dXPos > 32) { + sceneCluster.cullDirection = 1; + } else { + if (dXPos >= -32) + continue; + sceneCluster.cullDirection = 2; + dXPos = -dXPos; + } + sceneCluster.anInt801 = (sceneCluster.startYPos - yCameraPos << 8) / dXPos; + sceneCluster.anInt802 = (sceneCluster.endYPos - yCameraPos << 8) / dXPos; + sceneCluster.anInt803 = (sceneCluster.startZPos - zCameraPos << 8) / dXPos; + sceneCluster.anInt804 = (sceneCluster.endZPos - zCameraPos << 8) / dXPos; + aClass47Array476[anInt475++] = sceneCluster; + continue; + } + if (sceneCluster.orientation == 2) { //XZ-plane + int relativeY = (sceneCluster.startYLoc - yCameraTile) + 25; + if (relativeY < 0 || relativeY > 50) + continue; + int minRelativeX = (sceneCluster.startXLoc - xCameraTile) + 25; + if (minRelativeX < 0) + minRelativeX = 0; + int maxRelativeX = (sceneCluster.endXLoc - xCameraTile) + 25; + if (maxRelativeX > 50) + maxRelativeX = 50; + boolean flag1 = false; + while (minRelativeX <= maxRelativeX) + if (aBooleanArrayArray492[minRelativeX++][relativeY]) { + flag1 = true; + break; + } + if (!flag1) + continue; + int dYPos = yCameraPos - sceneCluster.startYPos; + if (dYPos > 32) { + sceneCluster.cullDirection = 3; + } else if (dYPos < -32){ + sceneCluster.cullDirection = 4; + dYPos = -dYPos; + } else { + continue; + } + sceneCluster.anInt799 = (sceneCluster.startXPos - xCameraPos << 8) / dYPos; + sceneCluster.anInt800 = (sceneCluster.endXPos - xCameraPos << 8) / dYPos; + sceneCluster.anInt803 = (sceneCluster.startZPos - zCameraPos << 8) / dYPos; + sceneCluster.anInt804 = (sceneCluster.endZPos - zCameraPos << 8) / dYPos; + aClass47Array476[anInt475++] = sceneCluster; + } else if (sceneCluster.orientation == 4) { //XY-plane + int relativeZ = sceneCluster.startZPos - zCameraPos; + if (relativeZ > 128) { + int minRelativeY = (sceneCluster.startYLoc - yCameraTile) + 25; + if (minRelativeY < 0) + minRelativeY = 0; + int maxRelativeY = (sceneCluster.endYLoc - yCameraTile) + 25; + if (maxRelativeY > 50) + maxRelativeY = 50; + if (minRelativeY <= maxRelativeY) { + int minRelativeX = (sceneCluster.startXLoc - xCameraTile) + 25; + if (minRelativeX < 0) + minRelativeX = 0; + int maxRelativeX = (sceneCluster.endXLoc - xCameraTile) + 25; + if (maxRelativeX > 50) + maxRelativeX = 50; + boolean flag2 = false; + label0: for (int i4 = minRelativeX; i4 <= maxRelativeX; i4++) { + for (int j4 = minRelativeY; j4 <= maxRelativeY; j4++) { + if (!aBooleanArrayArray492[i4][j4]) + continue; + flag2 = true; + break label0; + } + + } + + if (flag2) { + sceneCluster.cullDirection = 5; + sceneCluster.anInt799 = (sceneCluster.startXPos - xCameraPos << 8) / relativeZ; + sceneCluster.anInt800 = (sceneCluster.endXPos - xCameraPos << 8) / relativeZ; + sceneCluster.anInt801 = (sceneCluster.startYPos - yCameraPos << 8) / relativeZ; + sceneCluster.anInt802 = (sceneCluster.endYPos - yCameraPos << 8) / relativeZ; + aClass47Array476[anInt475++] = sceneCluster; + } + } + } + } + } + + } + + private boolean method320(int zLoc, int xLoc, int yLoc) { + int l = anIntArrayArrayArray445[zLoc][xLoc][yLoc]; + if (l == -anInt448) + return false; + if (l == anInt448) + return true; + int xPos = xLoc << 7; + int yPos = yLoc << 7; + if (method324(xPos + 1, heightMap[zLoc][xLoc][yLoc], yPos + 1) && method324((xPos + 128) - 1, heightMap[zLoc][xLoc + 1][yLoc], yPos + 1) && method324((xPos + 128) - 1, heightMap[zLoc][xLoc + 1][yLoc + 1], (yPos + 128) - 1) && method324(xPos + 1, heightMap[zLoc][xLoc][yLoc + 1], (yPos + 128) - 1)) { + anIntArrayArrayArray445[zLoc][xLoc][yLoc] = anInt448; + return true; + } else { + anIntArrayArrayArray445[zLoc][xLoc][yLoc] = -anInt448; + return false; + } + } + + private boolean method321(int i, int j, int k, int l) { + if (!method320(i, j, k)) + return false; + int i1 = j << 7; + int j1 = k << 7; + int k1 = heightMap[i][j][k] - 1; + int l1 = k1 - 120; + int i2 = k1 - 230; + int j2 = k1 - 238; + if (l < 16) { + if (l == 1) { + if (i1 > xCameraPos) { + if (!method324(i1, k1, j1)) + return false; + if (!method324(i1, k1, j1 + 128)) + return false; + } + if (i > 0) { + if (!method324(i1, l1, j1)) + return false; + if (!method324(i1, l1, j1 + 128)) + return false; + } + return method324(i1, i2, j1) && method324(i1, i2, j1 + 128); + } + if (l == 2) { + if (j1 < yCameraPos) { + if (!method324(i1, k1, j1 + 128)) + return false; + if (!method324(i1 + 128, k1, j1 + 128)) + return false; + } + if (i > 0) { + if (!method324(i1, l1, j1 + 128)) + return false; + if (!method324(i1 + 128, l1, j1 + 128)) + return false; + } + return method324(i1, i2, j1 + 128) && method324(i1 + 128, i2, j1 + 128); + } + if (l == 4) { + if (i1 < xCameraPos) { + if (!method324(i1 + 128, k1, j1)) + return false; + if (!method324(i1 + 128, k1, j1 + 128)) + return false; + } + if (i > 0) { + if (!method324(i1 + 128, l1, j1)) + return false; + if (!method324(i1 + 128, l1, j1 + 128)) + return false; + } + return method324(i1 + 128, i2, j1) && method324(i1 + 128, i2, j1 + 128); + } + if (l == 8) { + if (j1 > yCameraPos) { + if (!method324(i1, k1, j1)) + return false; + if (!method324(i1 + 128, k1, j1)) + return false; + } + if (i > 0) { + if (!method324(i1, l1, j1)) + return false; + if (!method324(i1 + 128, l1, j1)) + return false; + } + return method324(i1, i2, j1) && method324(i1 + 128, i2, j1); + } + } + if (!method324(i1 + 64, j2, j1 + 64)) + return false; + if (l == 16) + return method324(i1, i2, j1 + 128); + if (l == 32) + return method324(i1 + 128, i2, j1 + 128); + if (l == 64) + return method324(i1 + 128, i2, j1); + if (l == 128) { + return method324(i1, i2, j1); + } else { + System.out.println("Warning unsupported wall type"); //TODO + return true; + } + } + + private boolean method322(int i, int j, int k, int l) { + if (!method320(i, j, k)) + return false; + int i1 = j << 7; + int j1 = k << 7; + return method324(i1 + 1, heightMap[i][j][k] - l, j1 + 1) + && method324((i1 + 128) - 1, heightMap[i][j + 1][k] - l, j1 + 1) + && method324((i1 + 128) - 1, heightMap[i][j + 1][k + 1] - l, (j1 + 128) - 1) + && method324(i1 + 1, heightMap[i][j][k + 1] - l, (j1 + 128) - 1); + } + + private boolean method323(int i, int j, int k, int l, int i1, int j1) { + if (j == k && l == i1) { + if (!method320(i, j, l)) + return false; + int k1 = j << 7; + int i2 = l << 7; + return method324(k1 + 1, heightMap[i][j][l] - j1, i2 + 1) + && method324((k1 + 128) - 1, heightMap[i][j + 1][l] - j1, i2 + 1) + && method324((k1 + 128) - 1, heightMap[i][j + 1][l + 1] - j1, (i2 + 128) - 1) + && method324(k1 + 1, heightMap[i][j][l + 1] - j1, (i2 + 128) - 1); + } + for (int l1 = j; l1 <= k; l1++) { + for (int j2 = l; j2 <= i1; j2++) + if (anIntArrayArrayArray445[i][l1][j2] == -anInt448) + return false; + + } + + int k2 = (j << 7) + 1; + int l2 = (l << 7) + 2; + int i3 = heightMap[i][j][l] - j1; + if (!method324(k2, i3, l2)) + return false; + int j3 = (k << 7) - 1; + if (!method324(j3, i3, l2)) + return false; + int k3 = (i1 << 7) - 1; + return method324(k2, i3, k3) && method324(j3, i3, k3); + } + + private boolean method324(int i, int j, int k) { + for (int l = 0; l < anInt475; l++) { + SceneCluster class47 = aClass47Array476[l]; + if (class47.cullDirection == 1) { + int i1 = class47.startXPos - i; + if (i1 > 0) { + int j2 = class47.startYPos + (class47.anInt801 * i1 >> 8); + int k3 = class47.endYPos + (class47.anInt802 * i1 >> 8); + int l4 = class47.startZPos + (class47.anInt803 * i1 >> 8); + int i6 = class47.endZPos + (class47.anInt804 * i1 >> 8); + if (k >= j2 && k <= k3 && j >= l4 && j <= i6) + return true; + } + } else if (class47.cullDirection == 2) { + int j1 = i - class47.startXPos; + if (j1 > 0) { + int k2 = class47.startYPos + (class47.anInt801 * j1 >> 8); + int l3 = class47.endYPos + (class47.anInt802 * j1 >> 8); + int i5 = class47.startZPos + (class47.anInt803 * j1 >> 8); + int j6 = class47.endZPos + (class47.anInt804 * j1 >> 8); + if (k >= k2 && k <= l3 && j >= i5 && j <= j6) + return true; + } + } else if (class47.cullDirection == 3) { + int k1 = class47.startYPos - k; + if (k1 > 0) { + int l2 = class47.startXPos + (class47.anInt799 * k1 >> 8); + int i4 = class47.endXPos + (class47.anInt800 * k1 >> 8); + int j5 = class47.startZPos + (class47.anInt803 * k1 >> 8); + int k6 = class47.endZPos + (class47.anInt804 * k1 >> 8); + if (i >= l2 && i <= i4 && j >= j5 && j <= k6) + return true; + } + } else if (class47.cullDirection == 4) { + int l1 = k - class47.startYPos; + if (l1 > 0) { + int i3 = class47.startXPos + (class47.anInt799 * l1 >> 8); + int j4 = class47.endXPos + (class47.anInt800 * l1 >> 8); + int k5 = class47.startZPos + (class47.anInt803 * l1 >> 8); + int l6 = class47.endZPos + (class47.anInt804 * l1 >> 8); + if (i >= i3 && i <= j4 && j >= k5 && j <= l6) + return true; + } + } else if (class47.cullDirection == 5) { + int i2 = j - class47.startZPos; + if (i2 > 0) { + int j3 = class47.startXPos + (class47.anInt799 * i2 >> 8); + int k4 = class47.endXPos + (class47.anInt800 * i2 >> 8); + int l5 = class47.startYPos + (class47.anInt801 * i2 >> 8); + int i7 = class47.endYPos + (class47.anInt802 * i2 >> 8); + if (i >= j3 && i <= k4 && k >= l5 && k <= i7) + return true; + } + } + } + + return false; + } + + public static boolean lowMem = true; + private final int numberOfZ; + private final int xRegionSize; + private final int yRegionSize; + private final int[][][] heightMap; + private final Tile[][][] tileArray; + private int zAnInt442; + private int interactableObjectCacheCurrPos; + private final GameObject[] gameObjectsCache; + private final int[][][] anIntArrayArrayArray445; + private static int anInt446; + private static int currentRenderPlane; + private static int anInt448; + private static int cameraLowTileX; + private static int cameraHighTileX; + private static int cameraLowTileY; + private static int cameraHighTileY; + private static int xCameraTile; + private static int yCameraTile; + private static int xCameraPos; + private static int zCameraPos; + private static int yCameraPos; + private static int camUpDownY; + private static int camUpDownX; + private static int camLeftRightY; + private static int camLeftRightX; + private static GameObject[] interactableObjects = new GameObject[100]; + private static final int[] anIntArray463 = { 53, -53, -53, 53 }; + private static final int[] anIntArray464 = { -53, -53, 53, 53 }; + private static final int[] anIntArray465 = { -45, 45, 45, -45 }; + private static final int[] anIntArray466 = { 45, 45, -45, -45 }; + private static boolean clicked; + private static int clickScreenX; + private static int clickScreenY; + public static int clickedTileX = -1; + public static int clickedTileY = -1; + private static final int cullingClusterPlaneCount; + private static int[] sceneClusterCounts; + private static SceneCluster[][] sceneClusters; + private static int anInt475; + private static final SceneCluster[] aClass47Array476 = new SceneCluster[500]; + private static Deque tileDeque = new Deque(); + private static final int[] anIntArray478 = { 19, 55, 38, 155, 255, 110, 137, 205, 76 }; + private static final int[] anIntArray479 = { 160, 192, 80, 96, 0, 144, 80, 48, 160 }; + private static final int[] anIntArray480 = { 76, 8, 137, 4, 0, 1, 38, 2, 19 }; + private static final int[] anIntArray481 = { 0, 0, 2, 0, 0, 2, 1, 1, 0 }; + private static final int[] anIntArray482 = { 2, 0, 0, 2, 0, 0, 0, 4, 4 }; + private static final int[] anIntArray483 = { 0, 4, 4, 8, 0, 0, 8, 0, 0 }; + private static final int[] anIntArray484 = { 1, 1, 0, 0, 0, 8, 0, 0, 8 }; + private static final int[] TEXTURE_COLORS = { 41, 39248, 41, 4643, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 43086, + 41, 41, 41, 41, 41, 41, 41, 8602, 41, 28992, 41, 41, 41, 41, 41, 5056, 41, 41, 41, 7079, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 3131, 41, 41, 41 }; + private final int[] anIntArray486; + private final int[] anIntArray487; + private int anInt488; + private final int[][] tileVertices = { new int[16], { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 }, + { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1 }, { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1 }, + { 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1 } }; + private final int[][] tileVertexIndices = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3 }, + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + { 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12 } }; + private static boolean[][][][] aBooleanArrayArrayArrayArray491 = new boolean[8][32][51][51]; + private static boolean[][] aBooleanArrayArray492; + private static int viewportHalfWidth; + private static int viewportHalfHeight; + private static int anInt495; + private static int anInt496; + private static int viewportWidth; + private static int viewportHeight; + public static int viewDistance = 9; + + static { + cullingClusterPlaneCount = 4; + sceneClusterCounts = new int[cullingClusterPlaneCount]; + sceneClusters = new SceneCluster[cullingClusterPlaneCount][500]; + } +} diff --git a/src/main/java/org/rebotted/scene/SceneObject.java b/src/main/java/org/rebotted/scene/SceneObject.java new file mode 100644 index 0000000..d773c34 --- /dev/null +++ b/src/main/java/org/rebotted/scene/SceneObject.java @@ -0,0 +1,105 @@ +package org.rebotted.scene; +import org.rebotted.Client; +import org.rebotted.cache.anim.Animation; +import org.rebotted.cache.config.Varbit; +import org.rebotted.cache.def.ObjectDefinition; +import org.rebotted.entity.Renderable; +import org.rebotted.entity.model.Model; + +public final class SceneObject extends Renderable { + + private int anInt1599; + private final int[] anIntArray1600; + private final int anInt1601; + private final int anInt1602; + private final int anInt1603; + private final int anInt1604; + private final int anInt1605; + private final int anInt1606; + private Animation aAnimation_1607; + private int anInt1608; + public static Client clientInstance; + private final int anInt1610; + private final int anInt1611; + private final int anInt1612; + + private ObjectDefinition method457() { + int i = -1; + if (anInt1601 != -1) { + try { + Varbit varBit = Varbit.varbits[anInt1601]; + int k = varBit.getSetting(); + int l = varBit.getLow(); + int i1 = varBit.getHigh(); + int j1 = Client.BIT_MASKS[i1 - l]; + i = clientInstance.settings[k] >> l & j1; + } catch (Exception ex) { + } + } else if (anInt1602 != -1) { + i = clientInstance.settings[anInt1602]; + } + if (i < 0 || i >= anIntArray1600.length || anIntArray1600[i] == -1) { + return null; + } else { + return ObjectDefinition.lookup(anIntArray1600[i]); + } + } + + public Model getRotatedModel() { + int j = -1; + if (aAnimation_1607 != null) { + int k = Client.tick - anInt1608; + if (k > 100 && aAnimation_1607.loopOffset > 0) { + k = 100; + } + while (k > aAnimation_1607.duration(anInt1599)) { + k -= aAnimation_1607.duration(anInt1599); + anInt1599++; + if (anInt1599 < aAnimation_1607.frameCount) + continue; + anInt1599 -= aAnimation_1607.loopOffset; + if (anInt1599 >= 0 && anInt1599 < aAnimation_1607.frameCount) + continue; + aAnimation_1607 = null; + break; + } + anInt1608 = Client.tick - k; + if (aAnimation_1607 != null) { + j = aAnimation_1607.primaryFrames[anInt1599]; + } + } + ObjectDefinition class46; + if (anIntArray1600 != null) + class46 = method457(); + else + class46 = ObjectDefinition.lookup(anInt1610); + if (class46 == null) { + return null; + } else { + return class46.modelAt(anInt1611, anInt1612, anInt1603, anInt1604, anInt1605, anInt1606, j); + } + } + + public SceneObject(int i, int j, int k, int l, int i1, int j1, int k1, int l1, boolean flag) { + anInt1610 = i; + anInt1611 = k; + anInt1612 = j; + anInt1603 = j1; + anInt1604 = l; + anInt1605 = i1; + anInt1606 = k1; + if (l1 != -1) { + aAnimation_1607 = Animation.animations[l1]; + anInt1599 = 0; + anInt1608 = Client.tick; + if (flag && aAnimation_1607.loopOffset != -1) { + anInt1599 = (int) (Math.random() * (double) aAnimation_1607.frameCount); + anInt1608 -= (int) (Math.random() * (double) aAnimation_1607.duration(anInt1599)); + } + } + ObjectDefinition objectDef = ObjectDefinition.lookup(anInt1610); + anInt1601 = objectDef.varbit; + anInt1602 = objectDef.varp; + anIntArray1600 = objectDef.childrenIDs; + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/scene/object/GroundDecoration.java b/src/main/java/org/rebotted/scene/object/GroundDecoration.java new file mode 100644 index 0000000..63cf0e1 --- /dev/null +++ b/src/main/java/org/rebotted/scene/object/GroundDecoration.java @@ -0,0 +1,17 @@ +package org.rebotted.scene.object; +import org.rebotted.entity.Renderable; + +public final class GroundDecoration +{ + + public GroundDecoration() + { + } + + public int zPos; + public int xPos; + public int yPos; + public Renderable renderable; + public int uid; + public byte mask; +} diff --git a/src/main/java/org/rebotted/scene/object/SpawnedObject.java b/src/main/java/org/rebotted/scene/object/SpawnedObject.java new file mode 100644 index 0000000..0723369 --- /dev/null +++ b/src/main/java/org/rebotted/scene/object/SpawnedObject.java @@ -0,0 +1,23 @@ +package org.rebotted.scene.object; +import org.rebotted.collection.Linkable; + +public final class SpawnedObject extends Linkable { + + public SpawnedObject() + { + getLongetivity = -1; + } + + public int id; + public int orientation; + public int type; + public int getLongetivity; + public int plane; + public int group; + public int x; + public int y; + public int getPreviousId; + public int previousOrientation; + public int previousType; + public int delay; +} diff --git a/src/main/java/org/rebotted/scene/object/WallDecoration.java b/src/main/java/org/rebotted/scene/object/WallDecoration.java new file mode 100644 index 0000000..2e57512 --- /dev/null +++ b/src/main/java/org/rebotted/scene/object/WallDecoration.java @@ -0,0 +1,15 @@ +package org.rebotted.scene.object; + +import org.rebotted.entity.Renderable; + +public final class WallDecoration { + + public int zPos; + public int xPos; + public int yPos; + public int orientation; + public int orientation2; + public Renderable renderable; + public int uid; + public byte mask; +} diff --git a/src/main/java/org/rebotted/scene/object/WallObject.java b/src/main/java/org/rebotted/scene/object/WallObject.java new file mode 100644 index 0000000..5ed94f6 --- /dev/null +++ b/src/main/java/org/rebotted/scene/object/WallObject.java @@ -0,0 +1,17 @@ +package org.rebotted.scene.object; + +import org.rebotted.entity.Renderable; + +public final class WallObject { + + public int zPos; + public int xPos; + public int yPos; + public int orientation1; + public int orientation2; + public Renderable renderable1; + public Renderable renderable2; + public int uid; + public byte mask; + +} diff --git a/src/main/java/org/rebotted/scene/object/tile/ShapedTile.java b/src/main/java/org/rebotted/scene/object/tile/ShapedTile.java new file mode 100644 index 0000000..2e8667a --- /dev/null +++ b/src/main/java/org/rebotted/scene/object/tile/ShapedTile.java @@ -0,0 +1,301 @@ +package org.rebotted.scene.object.tile; + +public final class ShapedTile{ + public ShapedTile(int yLoc, int j, int k, int l, int texture, int j1, int rotation, int l1, int i2, int j2, int k2, int l2, int i3, int j3, int k3, int l3, int i4, int xLoc, int l4){ + flat = !(i3 != l2 || i3 != l || i3 != k2); + shape = j3; + this.rotation = rotation; + colourRGB = i2; + colourRGBA = l4; + char sideLength = 128; + int halfSizeLength = sideLength / 2; + int quarterSizeLight = sideLength / 4; + int k5 = (sideLength * 3) / 4; + int ai[] = anIntArrayArray696[j3]; + int l5 = ai.length; + anIntArray673 = new int[l5]; + anIntArray674 = new int[l5]; + anIntArray675 = new int[l5]; + int ai1[] = new int[l5]; + int ai2[] = new int[l5]; + int xPos = xLoc * sideLength; + int yPos = yLoc * sideLength; + for(int k6 = 0; k6 < l5; k6++){ + int realShape = ai[k6]; + if((realShape & 1) == 0 && realShape <= 8) + realShape = (realShape - rotation - rotation - 1 & 7) + 1; + if(realShape > 8 && realShape <= 12) + realShape = (realShape - 9 - rotation & 3) + 9; + if(realShape > 12 && realShape <= 16) + realShape = (realShape - 13 - rotation & 3) + 13; + int i7; + int k7; + int i8; + int k8; + int j9; + if(realShape == 1){ + i7 = xPos; + k7 = yPos; + i8 = i3; + k8 = l1; + j9 = j; + } else if(realShape == 2){ + i7 = xPos + halfSizeLength; + k7 = yPos; + i8 = i3 + l2 >> 1; + k8 = l1 + i4 >> 1; + j9 = j + l3 >> 1; + } else if(realShape == 3){ + i7 = xPos + sideLength; + k7 = yPos; + i8 = l2; + k8 = i4; + j9 = l3; + } else if(realShape == 4){ + i7 = xPos + sideLength; + k7 = yPos + halfSizeLength; + i8 = l2 + l >> 1; + k8 = i4 + j2 >> 1; + j9 = l3 + j1 >> 1; + } else if(realShape == 5){ + i7 = xPos + sideLength; + k7 = yPos + sideLength; + i8 = l; + k8 = j2; + j9 = j1; + } else if(realShape == 6){ + i7 = xPos + halfSizeLength; + k7 = yPos + sideLength; + i8 = l + k2 >> 1; + k8 = j2 + k >> 1; + j9 = j1 + k3 >> 1; + } else if(realShape == 7){ + i7 = xPos; + k7 = yPos + sideLength; + i8 = k2; + k8 = k; + j9 = k3; + } else if(realShape == 8){ + i7 = xPos; + k7 = yPos + halfSizeLength; + i8 = k2 + i3 >> 1; + k8 = k + l1 >> 1; + j9 = k3 + j >> 1; + } else if(realShape == 9){ + i7 = xPos + halfSizeLength; + k7 = yPos + quarterSizeLight; + i8 = i3 + l2 >> 1; + k8 = l1 + i4 >> 1; + j9 = j + l3 >> 1; + } else if(realShape == 10){ + i7 = xPos + k5; + k7 = yPos + halfSizeLength; + i8 = l2 + l >> 1; + k8 = i4 + j2 >> 1; + j9 = l3 + j1 >> 1; + } else if(realShape == 11){ + i7 = xPos + halfSizeLength; + k7 = yPos + k5; + i8 = l + k2 >> 1; + k8 = j2 + k >> 1; + j9 = j1 + k3 >> 1; + } else if(realShape == 12){ + i7 = xPos + quarterSizeLight; + k7 = yPos + halfSizeLength; + i8 = k2 + i3 >> 1; + k8 = k + l1 >> 1; + j9 = k3 + j >> 1; + } else if(realShape == 13){ + i7 = xPos + quarterSizeLight; + k7 = yPos + quarterSizeLight; + i8 = i3; + k8 = l1; + j9 = j; + } else if(realShape == 14){ + i7 = xPos + k5; + k7 = yPos + quarterSizeLight; + i8 = l2; + k8 = i4; + j9 = l3; + } else if(realShape == 15){ + i7 = xPos + k5; + k7 = yPos + k5; + i8 = l; + k8 = j2; + j9 = j1; + } else { + i7 = xPos + quarterSizeLight; + k7 = yPos + k5; + i8 = k2; + k8 = k; + j9 = k3; + } + anIntArray673[k6] = i7; + anIntArray674[k6] = i8; + anIntArray675[k6] = k7; + ai1[k6] = k8; + ai2[k6] = j9; + } + + int ai3[] = anIntArrayArray697[j3]; + int j7 = ai3.length / 4; + anIntArray679 = new int[j7]; + anIntArray680 = new int[j7]; + anIntArray681 = new int[j7]; + anIntArray676 = new int[j7]; + anIntArray677 = new int[j7]; + anIntArray678 = new int[j7]; + if(texture != -1) + anIntArray682 = new int[j7]; + int l7 = 0; + for(int j8 = 0; j8 < j7; j8++){ + int l8 = ai3[l7]; + int k9 = ai3[l7 + 1]; + int i10 = ai3[l7 + 2]; + int k10 = ai3[l7 + 3]; + l7 += 4; + if(k9 < 4) + k9 = k9 - rotation & 3; + if(i10 < 4) + i10 = i10 - rotation & 3; + if(k10 < 4) + k10 = k10 - rotation & 3; + anIntArray679[j8] = k9; + anIntArray680[j8] = i10; + anIntArray681[j8] = k10; + if(l8 == 0){ + anIntArray676[j8] = ai1[k9]; + anIntArray677[j8] = ai1[i10]; + anIntArray678[j8] = ai1[k10]; + if(anIntArray682 != null) + anIntArray682[j8] = -1; + } else { + anIntArray676[j8] = ai2[k9]; + anIntArray677[j8] = ai2[i10]; + anIntArray678[j8] = ai2[k10]; + if(anIntArray682 != null) + anIntArray682[j8] = texture; + } + } + + int i9 = i3; + int l9 = l2; + if(l2 < i9) + i9 = l2; + if(l2 > l9) + l9 = l2; + if(l < i9) + i9 = l; + if(l > l9) + l9 = l; + if(k2 < i9) + i9 = k2; + if(k2 > l9) + l9 = k2; + i9 /= 14; + l9 /= 14; + } + + public final int[] anIntArray673; + public final int[] anIntArray674; + public final int[] anIntArray675; + public final int[] anIntArray676; + public final int[] anIntArray677; + public final int[] anIntArray678; + public final int[] anIntArray679; + public final int[] anIntArray680; + public final int[] anIntArray681; + public int anIntArray682[]; + public final boolean flat; + public final int shape; + public final int rotation; + public final int colourRGB; + public final int colourRGBA; + public static final int[] anIntArray688 = new int[6]; + public static final int[] anIntArray689 = new int[6]; + public static final int[] anIntArray690 = new int[6]; + public static final int[] anIntArray691 = new int[6]; + public static final int[] anIntArray692 = new int[6]; + public static final int[] depthPoint = new int[6]; + static final int[] anIntArray693 = { + 1, 0 + }; + static final int[] anIntArray694 = { + 2, 1 + }; + static final int[] anIntArray695 = { + 3, 3 + }; + private static final int[][] anIntArrayArray696 = { + { + 1, 3, 5, 7 + }, { + 1, 3, 5, 7 + }, { + 1, 3, 5, 7 + }, { + 1, 3, 5, 7, 6 + }, { + 1, 3, 5, 7, 6 + }, { + 1, 3, 5, 7, 6 + }, { + 1, 3, 5, 7, 6 + }, { + 1, 3, 5, 7, 2, 6 + }, { + 1, 3, 5, 7, 2, 8 + }, { + 1, 3, 5, 7, 2, 8 + }, { + 1, 3, 5, 7, 11, 12 + }, { + 1, 3, 5, 7, 11, 12 + }, { + 1, 3, 5, 7, 13, 14 + } + }; + private static final int[][] anIntArrayArray697 = { + { + 0, 1, 2, 3, 0, 0, 1, 3 + }, { + 1, 1, 2, 3, 1, 0, 1, 3 + }, { + 0, 1, 2, 3, 1, 0, 1, 3 + }, { + 0, 0, 1, 2, 0, 0, 2, 4, 1, 0, + 4, 3 + }, { + 0, 0, 1, 4, 0, 0, 4, 3, 1, 1, + 2, 4 + }, { + 0, 0, 4, 3, 1, 0, 1, 2, 1, 0, + 2, 4 + }, { + 0, 1, 2, 4, 1, 0, 1, 4, 1, 0, + 4, 3 + }, { + 0, 4, 1, 2, 0, 4, 2, 5, 1, 0, + 4, 5, 1, 0, 5, 3 + }, { + 0, 4, 1, 2, 0, 4, 2, 3, 0, 4, + 3, 5, 1, 0, 4, 5 + }, { + 0, 0, 4, 5, 1, 4, 1, 2, 1, 4, + 2, 3, 1, 4, 3, 5 + }, { + 0, 0, 1, 5, 0, 1, 4, 5, 0, 1, + 2, 4, 1, 0, 5, 3, 1, 5, 4, 3, + 1, 4, 2, 3 + }, { + 1, 0, 1, 5, 1, 1, 4, 5, 1, 1, + 2, 4, 0, 0, 5, 3, 0, 5, 4, 3, + 0, 4, 2, 3 + }, { + 1, 0, 5, 4, 1, 0, 1, 5, 0, 0, + 4, 3, 0, 4, 5, 3, 0, 5, 2, 3, + 0, 1, 2, 5 + } + }; + +} diff --git a/src/main/java/org/rebotted/scene/object/tile/SimpleTile.java b/src/main/java/org/rebotted/scene/object/tile/SimpleTile.java new file mode 100644 index 0000000..547012d --- /dev/null +++ b/src/main/java/org/rebotted/scene/object/tile/SimpleTile.java @@ -0,0 +1,51 @@ +package org.rebotted.scene.object.tile; + +public final class SimpleTile { + + private final int northEastColor; + private final int northColor; + private final int centerColor; + private final int eastColor; + private final int texture; + private final boolean flat; + private final int colorRGB; + + public SimpleTile(int northEastColor, int northColor, int centerColor, int eastColor, int texture, int colorRGB, boolean flat) { + this.northEastColor = northEastColor; + this.northColor = northColor; + this.centerColor = centerColor; + this.eastColor = eastColor; + this.texture = texture; + this.colorRGB = colorRGB; + this.flat = flat; + } + + public int getNorthEastColor() { + return northEastColor; + } + + public int getNorthColor() { + return northColor; + } + + public int getCenterColor() { + return centerColor; + } + + public int getEastColor() { + return eastColor; + } + + public int getTexture() { + return texture; + } + + public boolean isFlat() { + return flat; + } + + public int getColourRGB() { + return colorRGB; + } + +} diff --git a/src/main/java/org/rebotted/scene/object/tile/Tile.java b/src/main/java/org/rebotted/scene/object/tile/Tile.java new file mode 100644 index 0000000..8dc4ca4 --- /dev/null +++ b/src/main/java/org/rebotted/scene/object/tile/Tile.java @@ -0,0 +1,41 @@ +package org.rebotted.scene.object.tile; +import org.rebotted.collection.Linkable; +import org.rebotted.entity.GameObject; +import org.rebotted.entity.GroundItemTile; +import org.rebotted.scene.object.GroundDecoration; +import org.rebotted.scene.object.WallDecoration; +import org.rebotted.scene.object.WallObject; + +public final class Tile extends Linkable { + public Tile(int i, int j, int k){ + gameObjects = new GameObject[5]; + tiledObjectMasks = new int[5]; + anInt1310 = z1AnInt1307 = i; + anInt1308 = j; + anInt1309 = k; + } + + public int z1AnInt1307; + public final int anInt1308; + public final int anInt1309; + public final int anInt1310; + public SimpleTile mySimpleTile; + public ShapedTile myShapedTile; + public WallObject wallObject; + public WallDecoration wallDecoration; + public GroundDecoration groundDecoration; + public GroundItemTile groundItemTile; + public int gameObjectIndex; + public final GameObject[] gameObjects; + public final int[] tiledObjectMasks; + public int totalTiledObjectMask; + public int logicHeight; + public boolean aBoolean1322; + public boolean aBoolean1323; + public boolean aBoolean1324; + public int someTileMask; + public int anInt1326; + public int anInt1327; + public int anInt1328; + public Tile firstFloorTile; +} diff --git a/src/main/java/org/rebotted/sign/SignLink.java b/src/main/java/org/rebotted/sign/SignLink.java new file mode 100644 index 0000000..f5a3e11 --- /dev/null +++ b/src/main/java/org/rebotted/sign/SignLink.java @@ -0,0 +1,423 @@ +package org.rebotted.sign; + +import java.applet.Applet; +import java.io.*; +import java.net.*; + +import javax.sound.midi.*; +import javax.sound.sampled.*; + +import org.rebotted.Configuration; + +public final class SignLink implements Runnable { + + public static final int clientversion = 317; + public static int uid; + public static int storeid = 32; + public static RandomAccessFile cache_dat = null; + public static final RandomAccessFile[] indices = new RandomAccessFile[5]; + public static boolean sunjava; + public static Applet mainapp = null; + private static boolean active; + private static int threadLiveId; + private static InetAddress socketAddress; + private static int socketRequest; + private static Socket socket = null; + private static int threadreqpri = 1; + private static Runnable threadreq = null; + private static String dnsreq = null; + public static String dns = null; + private static String urlRequest = null; + private static DataInputStream urlStream = null; + private static int savelen; + private static String savereq = null; + private static byte[] savebuf = null; + private static boolean play; + private static int midipos; + public static String midi = null; + public static int midiVolume; + public static int fadeMidi; + private static boolean waveplay; + private static int wavepos; + public static int wavevol; + public static boolean reporterror = true; + public static String errorName = ""; + + private SignLink() { + } + + public static void startpriv(InetAddress inetaddress) { + threadLiveId = (int) (Math.random() * 99999999D); + if (active) { + try { + Thread.sleep(500L); + } catch (Exception _ex) { + } + active = false; + } + socketRequest = 0; + threadreq = null; + dnsreq = null; + savereq = null; + urlRequest = null; + socketAddress = inetaddress; + Thread thread = new Thread(new SignLink()); + thread.setDaemon(true); + thread.start(); + while (!active) + try { + Thread.sleep(50L); + } catch (Exception _ex) { + } + } + + public void run() { + active = true; + String directory = findcachedir(); + uid = getUid(directory); + try { + cache_dat = new RandomAccessFile(directory + "main_file_cache.dat", "rw"); + for (int index = 0; index < 5; index++) + indices[index] = new RandomAccessFile(directory + "main_file_cache.idx" + + index, "rw"); + } catch (Exception exception) { + exception.printStackTrace(); + } + for (int i = threadLiveId; threadLiveId == i;) { + if (socketRequest != 0) { + try { + socket = new Socket(socketAddress, socketRequest); + } catch (Exception _ex) { + socket = null; + } + socketRequest = 0; + } else if (threadreq != null) { + Thread thread = new Thread(threadreq); + thread.setDaemon(true); + thread.start(); + thread.setPriority(threadreqpri); + threadreq = null; + } else if (dnsreq != null) { + try { + dns = InetAddress.getByName(dnsreq).getHostName(); + } catch (Exception _ex) { + dns = "unknown"; + } + dnsreq = null; + } else if (savereq != null) { + if (savebuf != null) + try { + FileOutputStream fileoutputstream = new FileOutputStream( + directory + savereq); + fileoutputstream.write(savebuf, 0, savelen); + fileoutputstream.close(); + } catch (Exception _ex) { + } + if (waveplay) { + String wave = directory + savereq; + waveplay = false; + AudioInputStream audioInputStream = null; + try { + audioInputStream = AudioSystem + .getAudioInputStream(new File(wave)); + } catch (UnsupportedAudioFileException e1) { + e1.printStackTrace(); + return; + } catch (IOException e1) { + e1.printStackTrace(); + return; + } + AudioFormat format = audioInputStream.getFormat(); + SourceDataLine auline = null; + DataLine.Info info = new DataLine.Info( + SourceDataLine.class, format); + try { + auline = (SourceDataLine) AudioSystem.getLine(info); + auline.open(format); + } catch (LineUnavailableException e) { + e.printStackTrace(); + return; + } catch (Exception e) { + e.printStackTrace(); + return; + } + + } + if (play) { + midi = directory + savereq; + try { + if (music != null) { + music.stop(); + music.close(); + } + playMidi(midi); + } catch (Exception ex) { + ex.printStackTrace(); + } + play = false; + } + savereq = null; + } else if (urlRequest != null) { + try { + System.out.println("urlstream"); + urlStream = new DataInputStream((new URL( + mainapp.getCodeBase(), urlRequest)).openStream()); + } catch (Exception _ex) { + urlStream = null; + } + urlRequest = null; + } + try { + Thread.sleep(50L); + } catch (Exception _ex) { + } + } + } + + public static String findcachedir() { + final String os = System.getProperty("os.name").toLowerCase(); + + final String cacheLoc = Configuration.CACHE_DIRECTORY; + + final String local = "./Cache/"; + + final File cacheDirectory = new File(Configuration.CACHE_DIRECTORY); + + if (!cacheDirectory.exists()) { + cacheDirectory.mkdirs(); + } + + // windows + if (os.indexOf("win") >= 0) { + return cacheLoc; + + // macintosh + } else if (os.indexOf("mac") >= 0) { + return cacheLoc; + + // linux + } else if (os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0 + || os.indexOf("aix") > 0) { + return cacheLoc; + + // solaris + } else if (os.indexOf("sunos") >= 0) { + return cacheLoc; + } + + return local; + } + + /** + * Plays the specified midi sequence. + * + * @param location + */ + private void playMidi(String location) { + music = null; + synthesizer = null; + sequence = null; + File midiFile = new File(location); + try { + sequence = MidiSystem.getSequence(midiFile); + music = MidiSystem.getSequencer(); + music.open(); + music.setSequence(sequence); + } catch (Exception e) { + System.err.println("Problem loading MIDI file."); + e.printStackTrace(); + return; + } + if (music instanceof Synthesizer) { + synthesizer = (Synthesizer) music; + } else { + try { + synthesizer = MidiSystem.getSynthesizer(); + synthesizer.open(); + if (synthesizer.getDefaultSoundbank() == null) { + music.getTransmitter() + .setReceiver(MidiSystem.getReceiver()); + } else { + music.getTransmitter().setReceiver( + synthesizer.getReceiver()); + } + } catch (Exception e) { + e.printStackTrace(); + return; + } + } + music.setLoopCount(Sequencer.LOOP_CONTINUOUSLY); + music.start(); + } + + /** + * Sets the volume for the midi synthesizer. + * + * @param value + */ + public static void setVolume(int value) { + int CHANGE_VOLUME = 7; + midiVolume = value; + if (synthesizer.getDefaultSoundbank() == null) { + try { + ShortMessage volumeMessage = new ShortMessage(); + for (int i = 0; i < 16; i++) { + volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, + CHANGE_VOLUME, midiVolume); + volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, + 39, midiVolume); + MidiSystem.getReceiver().send(volumeMessage, -1); + } + } catch (Exception e) { + e.printStackTrace(); + } + } else { + MidiChannel[] channels = synthesizer.getChannels(); + for (int c = 0; channels != null && c < channels.length; c++) { + channels[c].controlChange(CHANGE_VOLUME, midiVolume); + channels[c].controlChange(39, midiVolume); + } + } + } + + public static Sequencer music = null; + public static Sequence sequence = null; + public static Synthesizer synthesizer = null; + + public static synchronized boolean saveWave(byte abyte0[], int i) { + if (i > 0x1e8480) + return false; + if (savereq != null) { + return false; + } else { + wavepos = (wavepos + 1) % 5; + savelen = i; + savebuf = abyte0; + waveplay = true; + savereq = "sound" + wavepos + ".wav"; + return true; + } + } + + public static synchronized boolean replayWave() { + if (savereq != null) { + return false; + } else { + savebuf = null; + waveplay = true; + savereq = "sound" + wavepos + ".wav"; + return true; + } + } + + public static synchronized void saveMidi(byte abyte0[], int i) { + if (i > 0x1e8480) + return; + if (savereq != null) { + } else { + midipos = (midipos + 1) % 5; + savelen = i; + savebuf = abyte0; + play = true; + savereq = "jingle" + midipos + ".mid"; + } + } + + private static int getUid(String s) { + try { + File file = new File(s + "uid.dat"); + if (!file.exists() || file.length() < 4L) { + DataOutputStream dataoutputstream = new DataOutputStream( + new FileOutputStream(s + "uid.dat")); + dataoutputstream.writeInt((int) (Math.random() * 99999999D)); + dataoutputstream.close(); + } + } catch (Exception _ex) { + } + try { + DataInputStream datainputstream = new DataInputStream( + new FileInputStream(s + "uid.dat")); + int i = datainputstream.readInt(); + datainputstream.close(); + return i + 1; + } catch (Exception _ex) { + return 0; + } + } + + public static synchronized Socket openSocket(int port) throws IOException { + for (socketRequest = port; socketRequest != 0;) + try { + Thread.sleep(50L); + } catch (Exception _ex) { + } + if (socket == null) + throw new IOException("could not open socket"); + else + return socket; + } + + public static synchronized DataInputStream openUrl(String url) + throws IOException { + for (urlRequest = url; urlRequest != null;) { + try { + Thread.sleep(50L); + } catch (Exception ex) { + } + } + + if (urlStream == null) { + throw new IOException("could not open: " + url); + } + return urlStream; + } + + public static synchronized void dnslookup(String s) { + dns = s; + dnsreq = s; + } + + public static synchronized void startthread(Runnable runnable, int i) { + threadreqpri = i; + threadreq = runnable; + } + + public static synchronized boolean wavesave(byte abyte0[], int i) { + if (i > 0x1e8480) + return false; + if (savereq != null) { + return false; + } else { + wavepos = (wavepos + 1) % 5; + savelen = i; + savebuf = abyte0; + waveplay = true; + savereq = "sound" + wavepos + ".wav"; + return true; + } + } + + public static synchronized boolean wavereplay() { + if (savereq != null) { + return false; + } else { + savebuf = null; + waveplay = true; + savereq = "sound" + wavepos + ".wav"; + return true; + } + } + + public static String indexLocation(int cacheIndex, int index) { + return SignLink.findcachedir() + "index" + cacheIndex + "/" + + (index != -1 ? index + ".gz" : ""); + } + + public static void reporterror(String s) { + System.out.println("Error: " + s); + } + + public static void setError(String error) { + errorName = error; + } +} diff --git a/src/main/java/org/rebotted/sound/Envelope.java b/src/main/java/org/rebotted/sound/Envelope.java new file mode 100644 index 0000000..ab05f0d --- /dev/null +++ b/src/main/java/org/rebotted/sound/Envelope.java @@ -0,0 +1,81 @@ +package org.rebotted.sound; + +import org.rebotted.io.Buffer; + +/** + * A simple envelope generator to control a variety of parameters (such as + * attack and release). + * Refactored using Major's 317 refactored client + * http://www.rune-server.org/runescape-development/rs2-client/downloads/575183-almost-fully-refactored-317-client.html + */ +final class Envelope { + + private int segments; + private int[] durations; + private int[] peaks; + int start; + int end; + int form; + private int threshold; + private int segmentIndex; + private int step; + private int amplitude; + private int ticks; + + public void decode(Buffer stream) { + form = stream.readUnsignedByte(); + start = stream.readInt(); + end = stream.readInt(); + decodeSegments(stream); + } + + /** + * Decodes the segment data from the specified {@link Buffer}. + * + * @param buffer + * The buffer. + */ + public void decodeSegments(Buffer stream) { + segments = stream.readUnsignedByte(); + durations = new int[segments]; + peaks = new int[segments]; + for (int i = 0; i < segments; i++) { + durations[i] = stream.readUShort(); + peaks[i] = stream.readUShort(); + } + + } + + /** + * Resets this envelope. + */ + void resetValues() { + threshold = 0; + segmentIndex = 0; + step = 0; + amplitude = 0; + ticks = 0; + } + + /** + * Proceeds to the next step of the envelope, + * + * @param period + * The current period. + * @return The change. + */ + int step(int period) { + if (ticks >= threshold) { + amplitude = peaks[segmentIndex++] << 15; + if (segmentIndex >= segments) + segmentIndex = segments - 1; + threshold = (int) (((double) durations[segmentIndex] / 65536D) * (double) period); + if (threshold > ticks) + step = ((peaks[segmentIndex] << 15) - amplitude) + / (threshold - ticks); + } + amplitude += step; + ticks++; + return amplitude - step >> 15; + } +} diff --git a/src/main/java/org/rebotted/sound/Filter.java b/src/main/java/org/rebotted/sound/Filter.java new file mode 100644 index 0000000..7d2ade6 --- /dev/null +++ b/src/main/java/org/rebotted/sound/Filter.java @@ -0,0 +1,144 @@ +package org.rebotted.sound; + +import org.rebotted.io.Buffer; + +/** + * an implementation of a reconfigurable filter that calculates + * coefficients from pole magnitude/phases and a serial + * configuration of cascading second-order iir filters + * Refactored information from Major's 317 refactored client + * http://www.rune-server.org/runescape-development/rs2-client/downloads/575183-almost-fully-refactored-317-client.html + */ +final class Filter { + + final int[] pairs; + private final int[][][] phases; + private final int[][][] magnitudes; + private final int[] unity; + private static final float[][] minimisedCoefficients = new float[2][8]; + static final int[][] coefficients = new int[2][8]; + private static float forwardMinimisedCoefficientMultiplier; + static int forwardMultiplier; + + public Filter() { + pairs = new int[2]; + phases = new int[2][2][4]; + magnitudes = new int[2][2][4]; + unity = new int[2]; + } + + /** + * Perform precise linear interpolation on the magnitude (where "precise" means that the result is guaranteed to be + * the first magnitude ({@code magnitudes[direction][1][pair]}) when the step is {@code 1}). + * + * @param direction The direction, where {@code 0} is feedforward, and {@code 1} is feedback. + * @param pair The pair. + * @param step The step (the interpolation parameter). + * @return The interpolated magnitude. + */ + private float interpolateMagnitude(int direction, int pair, float step) { + float magnitude = (float) magnitudes[direction][0][pair] + step + * (float) (magnitudes[direction][1][pair] - magnitudes[direction][0][pair]); + magnitude *= 0.001525879F; + return 1.0F - (float) Math.pow(10D, -magnitude / 20F); + } + + private float normalise(float exponent) { + float f1 = 32.7032F * (float) Math.pow(2D, exponent); + return (f1 * 3.141593F) / 11025F; + } + + /** + * Perform linear interpolation on the phase + * + * @param direction The direction, where {@code 0} is feedforward, and {@code 1} is feedback. + * @param pair The pair. + * @param step The step (the interpolation parameter). + * @return The interpolated phase. + */ + private float interpolatePhase(int direction, int pair, float step) { + float phase = (float) phases[direction][0][pair] + step + * (float) (phases[direction][1][pair] - phases[direction][0][pair]); + phase *= 0.0001220703F; + return normalise(phase); + } + + public int compute(int direction, float step) { + if (direction == 0) { + float unity = (float) this.unity[0] + (float) (this.unity[1] - this.unity[0]) * step; + unity *= 0.003051758F; + forwardMinimisedCoefficientMultiplier = (float) Math.pow( + 0.10000000000000001D, unity / 20F); + forwardMultiplier = (int) (forwardMinimisedCoefficientMultiplier * 65536F); + } + if (pairs[direction] == 0) + return 0; + float initialMagnitude = interpolateMagnitude(direction, 0, step); + minimisedCoefficients[direction][0] = -2F * initialMagnitude + * (float) Math.cos(interpolatePhase(direction, 0, step)); + minimisedCoefficients[direction][1] = initialMagnitude * initialMagnitude; + for (int pair = 1; pair < pairs[direction]; pair++) { + float magnitude = interpolateMagnitude(direction, pair, step); + float f4 = -2F * magnitude * (float) Math.cos(interpolatePhase(direction, pair, step)); + float f5 = magnitude * magnitude; + minimisedCoefficients[direction][pair * 2 + 1] = minimisedCoefficients[direction][pair * 2 - 1] + * f5; + minimisedCoefficients[direction][pair * 2] = minimisedCoefficients[direction][pair * 2 - 1] + * f4 + minimisedCoefficients[direction][pair * 2 - 2] * f5; + for (int j1 = pair * 2 - 1; j1 >= 2; j1--) + minimisedCoefficients[direction][j1] += minimisedCoefficients[direction][j1 - 1] + * f4 + minimisedCoefficients[direction][j1 - 2] * f5; + + minimisedCoefficients[direction][1] += minimisedCoefficients[direction][0] * f4 + + f5; + minimisedCoefficients[direction][0] += f4; + } + + if (direction == 0) { + for (int l = 0; l < pairs[0] * 2; l++) + minimisedCoefficients[0][l] *= forwardMinimisedCoefficientMultiplier; + + } + for (int pair = 0; pair < pairs[direction] * 2; pair++) + coefficients[direction][pair] = (int) (minimisedCoefficients[direction][pair] * 65536F); + + return pairs[direction] * 2; + } + + public void decode(Buffer stream, Envelope soundEnveleope) { + int count = stream.readUnsignedByte(); + pairs[0] = count >> 4; + pairs[1] = count & 0xf; + if (count != 0) { + unity[0] = stream.readUShort(); + unity[1] = stream.readUShort(); + int migration = stream.readUnsignedByte(); + for (int k = 0; k < 2; k++) { + for (int l = 0; l < pairs[k]; l++) { + phases[k][0][l] = stream.readUShort(); + magnitudes[k][0][l] = stream.readUShort(); + } + + } + + for (int direction = 0; direction < 2; direction++) { + for (int pair = 0; pair < pairs[direction]; pair++) + if ((migration & 1 << direction * 4 << pair) != 0) { + phases[direction][1][pair] = stream + .readUShort(); + magnitudes[direction][1][pair] = stream + .readUShort(); + } else { + phases[direction][1][pair] = phases[direction][0][pair]; + magnitudes[direction][1][pair] = magnitudes[direction][0][pair]; + } + + } + + if (migration != 0 || unity[1] != unity[0]) + soundEnveleope.decodeSegments(stream); + } else { + unity[0] = unity[1] = 0; + } + } +} diff --git a/src/main/java/org/rebotted/sound/SoundConstants.java b/src/main/java/org/rebotted/sound/SoundConstants.java new file mode 100644 index 0000000..4e589d9 --- /dev/null +++ b/src/main/java/org/rebotted/sound/SoundConstants.java @@ -0,0 +1,19 @@ +package org.rebotted.sound; +/** + * Class containing sound-related constants. + * @author 7Winds + */ +public class SoundConstants { + + /** + * Music player + */ + public static final int SCAPE_RUNE = 0; + public static final int OLD_THEME = 400; + public static final int HWEEN_THEME = 321; + public static final int XMAS_THEME = 547; + public static final int FARMING_THEME = 466; + public static final int HUNTER_THEME = 207; + public static final int SUMMON_THEME = 457; + +} diff --git a/src/main/java/org/rebotted/sound/SoundPlayer.java b/src/main/java/org/rebotted/sound/SoundPlayer.java new file mode 100644 index 0000000..cec4e69 --- /dev/null +++ b/src/main/java/org/rebotted/sound/SoundPlayer.java @@ -0,0 +1,116 @@ +package org.rebotted.sound; +import java.io.InputStream; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; + +/** + * Custom class which is not found in the 317 deob. + */ +public class SoundPlayer implements Runnable { + + private AudioInputStream stream; + private DataLine.Info info; + private Clip sound; + + private InputStream soundStream; + private Thread player; + private int delay; + private int soundLevel; + public static int volume; + + /** + * Initializes the sound player. + * @param stream + * @param level + * @param delay + */ + public SoundPlayer(InputStream stream, int level, int delay) { + if (level == 0 || volume == 4 || level - volume <= 0) { + return; + } + this.soundStream = stream; + this.soundLevel = level; + this.delay = delay; + player = new Thread(this); + player.start(); + } + + /** + * Plays the sound. + */ + @Override + public void run() { + try { + stream = AudioSystem.getAudioInputStream(soundStream); + info = new DataLine.Info(Clip.class, stream.getFormat()); + sound = (Clip) AudioSystem.getLine(info); + sound.open(stream); + FloatControl volume = (FloatControl) sound.getControl(FloatControl.Type.MASTER_GAIN); + volume.setValue(getDecibels(soundLevel - getVolume())); + if (delay > 0) { + Thread.sleep(delay); + } + sound.start(); + while (sound.isActive()) { + Thread.sleep(250); + } + Thread.sleep(10000); + sound.close(); + stream.close(); + player.interrupt(); + } catch (Exception e) { + player.interrupt(); + e.printStackTrace(); + } + } + + /** + * Sets the client's volume level. + * @param level + */ + public static void setVolume(int level) { + volume = level; + } + + /** + * Returns the client's volume level. + */ + public static int getVolume() { + return volume; + } + + /** + * Returns the decibels for a given volume level. + * @param level + * @return + */ + public float getDecibels(int level) { + switch (level) { + case 1: + return (float) -80.0; + case 2: + return (float) -70.0; + case 3: + return (float) -60.0; + case 4: + return (float) -50.0; + case 5: + return (float) -40.0; + case 6: + return (float) -30.0; + case 7: + return (float) -20.0; + case 8: + return (float) -10.0; + case 9: + return (float) -0.0; + case 10: + return (float) 6.0; + default: + return (float) 0.0; + } + } +} diff --git a/src/main/java/org/rebotted/sound/Synthesizer.java b/src/main/java/org/rebotted/sound/Synthesizer.java new file mode 100644 index 0000000..ba07c51 --- /dev/null +++ b/src/main/java/org/rebotted/sound/Synthesizer.java @@ -0,0 +1,303 @@ +package org.rebotted.sound; + +import org.rebotted.io.Buffer; + +/** + * Refactored reference: + * http://www.rune-server.org/runescape-development/rs2-client/downloads/575183-almost-fully-refactored-317-client.html + */ +final class Synthesizer { + + private Envelope pitch; + private Envelope volume; + private Envelope pitchModifier; + private Envelope pitchModifierAmplitude; + private Envelope volumeMultiplier; + private Envelope volumeMultiplierAmplitude; + private Envelope release; + private Envelope attack; + private final int[] oscillatorVolume; + private final int[] anIntArray107; + private final int[] anIntArray108; + private int delayTime; + private int delayDecay; + private Filter filter; + private Envelope filterEnvelope; + int duration; + int offset; + private static int[] samples; + private static int[] NOISE; + private static int[] SINE; + private static final int[] phases = new int[5]; + private static final int[] delays = new int[5]; + private static final int[] volumeSteps = new int[5]; + private static final int[] pitchSteps = new int[5]; + private static final int[] pitchBaseSteps = new int[5]; + + public Synthesizer() { + oscillatorVolume = new int[5]; + anIntArray107 = new int[5]; + anIntArray108 = new int[5]; + delayDecay = 100; + duration = 500; + } + + public static void init() { + NOISE = new int[32768]; + for (int i = 0; i < 32768; i++) + if (Math.random() > 0.5D) + NOISE[i] = 1; + else + NOISE[i] = -1; + + SINE = new int[32768]; + for (int j = 0; j < 32768; j++) + SINE[j] = (int) (Math.sin((double) j / 5215.1903000000002D) * 16384D); + + samples = new int[0x35d54]; + } + + public int[] synthesize(int sampleCount, int duration) { + for (int k = 0; k < sampleCount; k++) + samples[k] = 0; + + if (duration < 10) + return samples; + double d = (double) sampleCount / ((double) duration + 0.0D); + pitch.resetValues(); + volume.resetValues(); + int pitchMultiplierStep = 0; + int pitchModifierBaseStep = 0; + int pitchModifierPhase = 0; + if (pitchModifier != null) { + pitchModifier.resetValues(); + pitchModifierAmplitude.resetValues(); + pitchMultiplierStep = (int) (((double) (pitchModifier.end - pitchModifier.start) * 32.768000000000001D) / d); + pitchModifierBaseStep = (int) (((double) pitchModifier.start * 32.768000000000001D) / d); + } + int volumeMultiplierStep = 0; + int volumeMultiplierBaseStep = 0; + int volumeMultiplierPhase = 0; + if (volumeMultiplier != null) { + volumeMultiplier.resetValues(); + volumeMultiplierAmplitude.resetValues(); + volumeMultiplierStep = (int) (((double) (volumeMultiplier.end - volumeMultiplier.start) * 32.768000000000001D) / d); + volumeMultiplierBaseStep = (int) (((double) volumeMultiplier.start * 32.768000000000001D) / d); + } + for (int index = 0; index < 5; index++) + if (oscillatorVolume[index] != 0) { + phases[index] = 0; + delays[index] = (int) ((double) anIntArray108[index] * d); + volumeSteps[index] = (oscillatorVolume[index] << 14) / 100; + pitchSteps[index] = (int) (((double) (pitch.end - pitch.start) * 32.768000000000001D * Math + .pow(1.0057929410678534D, anIntArray107[index])) / d); + pitchBaseSteps[index] = (int) (((double) pitch.start * 32.768000000000001D) / d); + } + + for (int sample = 0; sample < sampleCount; sample++) { + int pitchChange = pitch.step(sampleCount); + int volumeChange = volume.step(sampleCount); + if (pitchModifier != null) { + int modifier = pitchModifier.step(sampleCount); + int ampModifier = pitchModifierAmplitude.step(sampleCount); + pitchChange += evaluateWave(ampModifier, pitchModifierPhase, + pitchModifier.form) >> 1; + pitchModifierPhase += (modifier * pitchMultiplierStep >> 16) + + pitchModifierBaseStep; + } + if (volumeMultiplier != null) { + int multiplier = volumeMultiplier.step(sampleCount); + int ampMultiplier = volumeMultiplierAmplitude.step(sampleCount); + volumeChange = volumeChange + * ((evaluateWave(ampMultiplier, volumeMultiplierPhase, + volumeMultiplier.form) >> 1) + 32768) >> 15; + volumeMultiplierPhase += (multiplier * volumeMultiplierStep >> 16) + + volumeMultiplierBaseStep; + } + for (int delay = 0; delay < 5; delay++) + if (oscillatorVolume[delay] != 0) { + int id = sample + delays[delay]; + if (id < sampleCount) { + samples[id] += evaluateWave(volumeChange + * volumeSteps[delay] >> 15, phases[delay], + pitch.form); + phases[delay] += (pitchChange * pitchSteps[delay] >> 16) + + pitchBaseSteps[delay]; + } + } + + } + + if (release != null) { + release.resetValues(); + attack.resetValues(); + int counter = 0; + boolean muted = true; + for (int sample = 0; sample < sampleCount; sample++) { + int on = release.step(sampleCount); + int off = attack.step(sampleCount); + int threshold; + if (muted) + threshold = release.start + + ((release.end - release.start) * on >> 8); + else + threshold = release.start + + ((release.end - release.start) * off >> 8); + if ((counter += 256) >= threshold) { + counter = 0; + muted = !muted; + } + if (muted) + samples[sample] = 0; + } + + } + if (delayTime > 0 && delayDecay > 0) { + int delay = (int) ((double) delayTime * d); + for (int index = delay; index < sampleCount; index++) + samples[index] += (samples[index - delay] * delayDecay) / 100; + + } + if (filter.pairs[0] > 0 || filter.pairs[1] > 0) { + filterEnvelope.resetValues(); + int change = filterEnvelope.step(sampleCount + 1); + int forwardOrder = filter.compute(0, (float) change / 65536F); + int backOrder = filter.compute(1, (float) change / 65536F); + if (sampleCount >= forwardOrder + backOrder) { + int index = 0; + int delay = backOrder; + if (delay > sampleCount - forwardOrder) + delay = sampleCount - forwardOrder; + for (; index < delay; index++) { + int sample = (int) ((long) samples[index + forwardOrder] + * (long) Filter.forwardMultiplier >> 16); + for (int j8 = 0; j8 < forwardOrder; j8++) + sample += (int) ((long) samples[(index + forwardOrder) + - 1 - j8] + * (long) Filter.coefficients[0][j8] >> 16); + + for (int j9 = 0; j9 < index; j9++) + sample -= (int) ((long) samples[index - 1 - j9] + * (long) Filter.coefficients[1][j9] >> 16); + + samples[index] = sample; + change = filterEnvelope.step(sampleCount + 1); + } + + char c = '\200'; + delay = c; + do { + if (delay > sampleCount - forwardOrder) + delay = sampleCount - forwardOrder; + for (; index < delay; index++) { + int l8 = (int) ((long) samples[index + forwardOrder] + * (long) Filter.forwardMultiplier >> 16); + for (int k9 = 0; k9 < forwardOrder; k9++) + l8 += (int) ((long) samples[(index + forwardOrder) + - 1 - k9] + * (long) Filter.coefficients[0][k9] >> 16); + + for (int i10 = 0; i10 < backOrder; i10++) + l8 -= (int) ((long) samples[index - 1 - i10] + * (long) Filter.coefficients[1][i10] >> 16); + + samples[index] = l8; + change = filterEnvelope.step(sampleCount + 1); + } + + if (index >= sampleCount - forwardOrder) + break; + forwardOrder = filter.compute(0, (float) change / 65536F); + backOrder = filter.compute(1, (float) change / 65536F); + delay += c; + } while (true); + for (; index < sampleCount; index++) { + int sample = 0; + for (int l9 = (index + forwardOrder) - sampleCount; l9 < forwardOrder; l9++) + sample += (int) ((long) samples[(index + forwardOrder) + - 1 - l9] + * (long) Filter.coefficients[0][l9] >> 16); + + for (int j10 = 0; j10 < backOrder; j10++) + sample -= (int) ((long) samples[index - 1 - j10] + * (long) Filter.coefficients[1][j10] >> 16); + + samples[index] = sample; + } + + } + } + for (int sample = 0; sample < sampleCount; sample++) { + if (samples[sample] < -32768) + samples[sample] = -32768; + if (samples[sample] > 32767) + samples[sample] = 32767; + } + + return samples; + } + + private int evaluateWave(int amplitude, int phase, int table) { + if (table == 1) + if ((phase & 0x7fff) < 16384) + return amplitude; + else + return -amplitude; + if (table == 2) + return SINE[phase & 0x7fff] * amplitude >> 14; + if (table == 3) + return ((phase & 0x7fff) * amplitude >> 14) - amplitude; + if (table == 4) + return NOISE[phase / 2607 & 0x7fff] * amplitude; + else + return 0; + } + + public void decode(Buffer stream) { + pitch = new Envelope(); + pitch.decode(stream); + volume = new Envelope(); + volume.decode(stream); + int option = stream.readUnsignedByte(); + if (option != 0) { + stream.currentPosition--; + pitchModifier = new Envelope(); + pitchModifier.decode(stream); + pitchModifierAmplitude = new Envelope(); + pitchModifierAmplitude.decode(stream); + } + option = stream.readUnsignedByte(); + if (option != 0) { + stream.currentPosition--; + volumeMultiplier = new Envelope(); + volumeMultiplier.decode(stream); + volumeMultiplierAmplitude = new Envelope(); + volumeMultiplierAmplitude.decode(stream); + } + option = stream.readUnsignedByte(); + if (option != 0) { + stream.currentPosition--; + release = new Envelope(); + release.decode(stream); + attack = new Envelope(); + attack.decode(stream); + } + for (int index = 0; index < 10; index++) { + int volume = stream.readUSmart(); + if (volume == 0) + break; + oscillatorVolume[index] = volume; + anIntArray107[index] = stream.readSmart(); + anIntArray108[index] = stream.readUSmart(); + } + + delayTime = stream.readUSmart(); + delayDecay = stream.readUSmart(); + duration = stream.readUShort(); + offset = stream.readUShort(); + filter = new Filter(); + filterEnvelope = new Envelope(); + filter.decode(stream, filterEnvelope); + } + +} diff --git a/src/main/java/org/rebotted/sound/Track.java b/src/main/java/org/rebotted/sound/Track.java new file mode 100644 index 0000000..969c947 --- /dev/null +++ b/src/main/java/org/rebotted/sound/Track.java @@ -0,0 +1,149 @@ +package org.rebotted.sound; + +import org.rebotted.io.Buffer; + +/** + * Refactored reference: + * http://www.rune-server.org/runescape-development/rs2-client/downloads/575183-almost-fully-refactored-317-client.html + */ +public final class Track { + + private Track() { + synthesizers = new Synthesizer[10]; + } + + public static void unpack(Buffer stream) { + output = new byte[0x6baa8]; + riff = new Buffer(output); + Synthesizer.init(); + do { + int id = stream.readUShort(); + if (id == 65535) + return; + tracks[id] = new Track(); + tracks[id].decode(stream); + delays[id] = tracks[id].calculateDelay(); + } while (true); + } + + public static Buffer data(int loops, int id) { + if (tracks[id] != null) { + Track soundTrack = tracks[id]; + return soundTrack.pack(loops); + } else { + return null; + } + } + + private void decode(Buffer stream) { + for (int synthesizer = 0; synthesizer < 10; synthesizer++) { + int valid = stream.readUnsignedByte(); + if (valid != 0) { + stream.currentPosition--; + synthesizers[synthesizer] = new Synthesizer(); + synthesizers[synthesizer].decode(stream); + } + } + loopStart = stream.readUShort(); + loopEnd = stream.readUShort(); + } + + private int calculateDelay() { + int offset = 0x98967f; + for (int syntheziser = 0; syntheziser < 10; syntheziser++) + if (synthesizers[syntheziser] != null + && synthesizers[syntheziser].offset / 20 < offset) + offset = synthesizers[syntheziser].offset / 20; + + if (loopStart < loopEnd && loopStart / 20 < offset) + offset = loopStart / 20; + if (offset == 0x98967f || offset == 0) + return 0; + for (int synthesizer = 0; synthesizer < 10; synthesizer++) + if (synthesizers[synthesizer] != null) + synthesizers[synthesizer].offset -= offset * 20; + + if (loopStart < loopEnd) { + loopStart -= offset * 20; + loopEnd -= offset * 20; + } + return offset; + } + + private Buffer pack(int loops) { + int size = mix(loops); + riff.currentPosition = 0; + riff.writeInt(0x52494646); + riff.writeLEInt(36 + size); + riff.writeInt(0x57415645); + riff.writeInt(0x666d7420); + riff.writeLEInt(16); + riff.writeLEShort(1); + riff.writeLEShort(1); + riff.writeLEInt(22050); + riff.writeLEInt(22050); + riff.writeLEShort(1); + riff.writeLEShort(8); + riff.writeInt(0x64617461); + riff.writeLEInt(size); + riff.currentPosition += size; + return riff; + } + + private int mix(int loops) { + int duration = 0; + for (int synthesizer = 0; synthesizer < 10; synthesizer++) + if (synthesizers[synthesizer] != null + && synthesizers[synthesizer].duration + synthesizers[synthesizer].offset > duration) + duration = synthesizers[synthesizer].duration + synthesizers[synthesizer].offset; + + if (duration == 0) + return 0; + int sampleCount = (22050 * duration) / 1000; + int loopStart = (22050 * this.loopStart) / 1000; + int loopEnd = (22050 * this.loopEnd) / 1000; + if (loopStart < 0 || loopStart > sampleCount || loopEnd < 0 || loopEnd > sampleCount || loopStart >= loopEnd) + loops = 0; + int size = sampleCount + (loopEnd - loopStart) * (loops - 1); + for (int offset = 44; offset < size + 44; offset++) + output[offset] = -128; + + for (int synthesizer = 0; synthesizer < 10; synthesizer++) + if (synthesizers[synthesizer] != null) { + int synthDuration = (synthesizers[synthesizer].duration * 22050) / 1000; + int synthOffset = (synthesizers[synthesizer].offset * 22050) / 1000; + int samples[] = synthesizers[synthesizer].synthesize(synthDuration, + synthesizers[synthesizer].duration); + for (int sample = 0; sample < synthDuration; sample++) + output[sample + synthOffset + 44] += (byte) (samples[sample] >> 8); + + } + + if (loops > 1) { + loopStart += 44; + loopEnd += 44; + sampleCount += 44; + int k2 = (size += 44) - sampleCount; + for (int j3 = sampleCount - 1; j3 >= loopEnd; j3--) + output[j3 + k2] = output[j3]; + + for (int k3 = 1; k3 < loops; k3++) { + int l2 = (loopEnd - loopStart) * k3; + System.arraycopy(output, loopStart, output, loopStart + l2, loopEnd - loopStart); + + } + + size -= 44; + } + return size; + } + + private static final Track[] tracks = new Track[5000]; + public static final int[] delays = new int[5000]; + private static byte[] output; + private static Buffer riff; + private final Synthesizer[] synthesizers; + private int loopStart; + private int loopEnd; + +} diff --git a/src/main/java/org/rebotted/ui/BotFrame.java b/src/main/java/org/rebotted/ui/BotFrame.java new file mode 100644 index 0000000..21692e0 --- /dev/null +++ b/src/main/java/org/rebotted/ui/BotFrame.java @@ -0,0 +1,48 @@ +package org.rebotted.ui; + +import org.rebotted.Configuration; +import org.rebotted.GameApplet; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public final class BotFrame extends JFrame implements ActionListener { + + private final GameApplet applet; + public Toolkit toolkit = Toolkit.getDefaultToolkit(); + public Dimension screenSize = toolkit.getScreenSize(); + public int screenWidth = (int) screenSize.getWidth(); + public int screenHeight = (int) screenSize.getHeight(); + private static final long serialVersionUID = 1L; + private final BotMenuBar botMenuBar; + protected final Insets insets; + + public BotFrame(GameApplet applet, boolean resizable) { + this.applet = applet; + setTitle(Configuration.CLIENT_NAME); + setResizable(resizable); + insets = getInsets(); + botMenuBar = new BotMenuBar(this); + setJMenuBar(botMenuBar); + add(applet, BorderLayout.CENTER); + setMinimumSize(new Dimension(774, 559)); + setSize(774, 559); + pack(); + setLocationRelativeTo(getParent()); + setLocationRelativeTo(getOwner()); + setVisible(true); + applet.initClientFrame(766, 536); + System.out.println("Client Launched."); + } + + @Override + public void actionPerformed(ActionEvent e) { + switch (e.getActionCommand().toLowerCase()) { + case "run": + System.out.println("run was clicked.."); + break; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/ui/BotMenuBar.java b/src/main/java/org/rebotted/ui/BotMenuBar.java new file mode 100644 index 0000000..5358263 --- /dev/null +++ b/src/main/java/org/rebotted/ui/BotMenuBar.java @@ -0,0 +1,163 @@ +package org.rebotted.ui; + +import javax.swing.*; + +/** + * @author Ethan + */ + +public class BotMenuBar extends JMenuBar { + private BotFrame botUI; + private JButton startButton, pauseButton, stopButton; + private JMenu features, file, scripts; + private JMenuItem cacheClear, notifications, run, pause, stop; + + public BotMenuBar(BotFrame botUI) { + this.botUI = botUI; + configure(); + } + + private final void configure() { + createMenu(); + configureComponents(); + } + + private void createMenu() { + + file = new JMenu("File"); + features = new JMenu("Features"); + scripts = new JMenu("Script"); + + JMenuItem screenshot = new JMenuItem("Create screenshot"); + JMenuItem proxy = new JMenuItem("Network"); + JMenuItem randoms = new JMenuItem("Randoms"); + JMenuItem dialog = new JCheckBoxMenuItem("Disable dialog"); + JMenuItem logger = new JCheckBoxMenuItem("Logger"); + + JMenuItem explorer = new JMenuItem("Reflection explorer"); + JMenuItem exit = new JMenuItem("Exit"); + + + run = createNewJMenuItem( "Run", true); + + pause = createNewJMenuItem("Pause", false); + + stop = createNewJMenuItem("Stop", false); + + cacheClear = new JMenuItem("Clear cache"); + //cacheClear.setIcon(new ImageIcon(Images.getResource("/storage/images/trash.png"))); + + notifications = new JMenuItem("Notifications"); + //notifications.setIcon(new ImageIcon(Images.getResource("/storage/images/bell.png"))); + + + screenshot.addActionListener(botUI); + proxy.addActionListener(botUI); + randoms.addActionListener(botUI); + dialog.addActionListener(botUI); + logger.addActionListener(botUI); + explorer.addActionListener(botUI); + exit.addActionListener(botUI); + cacheClear.addActionListener(botUI); + notifications.addActionListener(botUI); + + scripts.add(run); + scripts.add(pause); + scripts.add(stop); + + file.add(screenshot); + file.add(proxy); + file.add(randoms); + file.add(dialog); + file.add(logger); + file.add(explorer); + file.add(exit); + + features.add(cacheClear); + features.add(notifications); + + + /* startButton = createNewButton(new ImageIcon(Images.getResource("/storage/images/run_button.png")), "Run Script", "Run", true); + + pauseButton = createNewButton(new ImageIcon(Images.getResource("/storage/images/pause_button.png")), "Pause Script", "Pause", false); + + stopButton = createNewButton(new ImageIcon(Images.getResource("/storage/images/stop_button.png")), "Stop Script", "Stop", false);*/ + + } + + private JMenuItem createNewJMenuItem(String name, boolean enabled) { + final JMenuItem tempItem = new JMenuItem(name); + tempItem.setEnabled(enabled); + tempItem.addActionListener(botUI); + return tempItem; + } + + private JButton createNewButton(ImageIcon icon, String tooltip, String action, boolean enabled) { + final JButton tempButton = new JButton(); + tempButton.setIcon(icon); + tempButton.setContentAreaFilled(false); + tempButton.setRolloverEnabled(true); + tempButton.setToolTipText(tooltip); + tempButton.addActionListener(botUI); + tempButton.setActionCommand(action); + tempButton.setEnabled(enabled); + return tempButton; + } + + private void configureComponents() { + removeAll(); + add(file); + add(features); + add(scripts); + add(Box.createHorizontalGlue()); + /*add(startButton); + add(pauseButton); + add(stopButton);*/ + + } + + + public JMenu getFeatures() { + return features; + } + + public JMenu getFile() { + return file; + } + + public JMenuItem getCacheClear() { + return cacheClear; + } + + public JMenuItem getNotifications() { + return notifications; + } + + public JButton getStartButton() { + return startButton; + } + + public JButton getPauseButton() { + return pauseButton; + } + + public JButton getStopButton() { + return stopButton; + } + + public JMenu getScripts() { + return scripts; + } + + public JMenuItem getRun() { + return run; + } + + public JMenuItem getPause() { + return pause; + } + + public JMenuItem getStop() { + return stop; + } +} \ No newline at end of file diff --git a/src/main/java/org/rebotted/ui/themes/DarkTheme.java b/src/main/java/org/rebotted/ui/themes/DarkTheme.java new file mode 100644 index 0000000..ec627eb --- /dev/null +++ b/src/main/java/org/rebotted/ui/themes/DarkTheme.java @@ -0,0 +1,140 @@ +package org.rebotted.ui.themes; + + +import org.pushingpixels.substance.api.*; +import org.pushingpixels.substance.api.painter.border.ClassicBorderPainter; +import org.pushingpixels.substance.api.painter.decoration.FlatDecorationPainter; +import org.pushingpixels.substance.api.painter.fill.FractionBasedFillPainter; +import org.pushingpixels.substance.api.painter.highlight.FractionBasedHighlightPainter; +import org.pushingpixels.substance.api.shaper.ClassicButtonShaper; + +import java.io.File; +import java.net.URL; + +public class DarkTheme extends SubstanceSkin { + private SubstanceColorScheme selected_disabled, selected, disabled, enabled, background, aqua, border, separator, tabHighlight; + private SubstanceColorSchemeBundle bundle; + private ComponentState[] states, states2; + private ColorSchemeAssociationKind associationKind; + private DecorationAreaType[] decorationAreaTypes; + private ColorSchemeSingleColorQuery[] colorSchemeSingleColorQueries; + + public DarkTheme() { + ColorSchemes schemes = SubstanceSkin.getColorSchemes(getClass().getResource("/rebotted.colorschemes")); + selected_disabled = schemes.get("Rebotted Selected Disabled"); + selected = schemes.get("Rebotted Selected"); + disabled = schemes.get("Rebotted Disabled"); + enabled = schemes.get("Rebotted Enabled"); + background = schemes.get("Rebotted Background"); + bundle = new SubstanceColorSchemeBundle(enabled, enabled, disabled); + aqua = schemes.get("Rebotted Dark"); + + states = new ComponentState[1]; + + states[0] = ComponentState.ROLLOVER_UNSELECTED; + bundle.registerHighlightColorScheme(aqua, 0.75F, states); + states = new ComponentState[1]; + states[0] = ComponentState.SELECTED; + bundle.registerHighlightColorScheme(aqua, 0.9F, states); + states = new ComponentState[1]; + states[0] = ComponentState.ROLLOVER_SELECTED; + bundle.registerHighlightColorScheme(aqua, 1.0F, states); + states = new ComponentState[2]; + states[0] = ComponentState.ARMED; + states[1] = ComponentState.ROLLOVER_ARMED; + bundle.registerHighlightColorScheme(aqua, 1.0F, states); + associationKind = ColorSchemeAssociationKind.BORDER; + states = new ComponentState[3]; + states[0] = ComponentState.ROLLOVER_ARMED; + states[1] = ComponentState.ROLLOVER_SELECTED; + states[2] = ComponentState.ROLLOVER_UNSELECTED; + bundle.registerColorScheme(aqua, associationKind, states); + associationKind = ColorSchemeAssociationKind.FILL; + states = new ComponentState[2]; + states[0] = ComponentState.SELECTED; + states[1] = ComponentState.ROLLOVER_SELECTED; + bundle.registerColorScheme(aqua, associationKind, states); + + border = schemes.get("Rebotted Border"); + separator = schemes.get("Rebotted Separator"); + bundle.registerColorScheme(aqua, ColorSchemeAssociationKind.HIGHLIGHT_BORDER, ComponentState.getActiveStates()); + associationKind = ColorSchemeAssociationKind.BORDER; + states = new ComponentState[0]; + bundle.registerColorScheme(border, associationKind, states); + associationKind = ColorSchemeAssociationKind.SEPARATOR; + states = new ComponentState[0]; + bundle.registerColorScheme(separator, associationKind, states); + associationKind = ColorSchemeAssociationKind.MARK; + states = new ComponentState[0]; + bundle.registerColorScheme(border, associationKind, states); + associationKind = ColorSchemeAssociationKind.TEXT_HIGHLIGHT; + states = new ComponentState[2]; + states[0] = ComponentState.SELECTED; + states[1] = ComponentState.ROLLOVER_SELECTED; + bundle.registerColorScheme(aqua, associationKind, states); + states2 = new ComponentState[2]; + states2[0] = ComponentState.ARMED; + states2[1] = ComponentState.ROLLOVER_ARMED; + bundle.registerColorScheme(aqua, states2); + states = new ComponentState[1]; + states[0] = ComponentState.DISABLED_UNSELECTED; + bundle.registerColorScheme(disabled, 0.5F, states); + states = new ComponentState[1]; + states[0] = ComponentState.DISABLED_SELECTED; + bundle.registerColorScheme(selected_disabled, 0.5F, states); + states2 = new ComponentState[1]; + states2[0] = ComponentState.ROLLOVER_SELECTED; + bundle.registerColorScheme(aqua, states2); + states2 = new ComponentState[1]; + states2[0] = ComponentState.SELECTED; + bundle.registerColorScheme(selected, states2); + tabHighlight = schemes.get("Rebotted Tab Highlight"); + associationKind = ColorSchemeAssociationKind.TAB; + states = new ComponentState[1]; + states[0] = ComponentState.ROLLOVER_SELECTED; + bundle.registerColorScheme(tabHighlight, associationKind, states); + decorationAreaTypes = new DecorationAreaType[1]; + decorationAreaTypes[0] = DecorationAreaType.NONE; + this.registerDecorationAreaSchemeBundle(bundle, background, decorationAreaTypes); + this.setSelectedTabFadeStart(0.15D); + this.setSelectedTabFadeEnd(0.25D); + this.buttonShaper = new ClassicButtonShaper(); + this.watermark = null; + float[] floats = new float[3]; + floats[0] = 0.0F; + floats[1] = 0.5F; + floats[2] = 1.0F; + colorSchemeSingleColorQueries = new ColorSchemeSingleColorQuery[3]; + colorSchemeSingleColorQueries[0] = ColorSchemeSingleColorQuery.LIGHT; + colorSchemeSingleColorQueries[1] = ColorSchemeSingleColorQuery.MID; + colorSchemeSingleColorQueries[2] = ColorSchemeSingleColorQuery.MID; + this.fillPainter = new FractionBasedFillPainter("Rebotted", floats, colorSchemeSingleColorQueries); + this.decorationPainter = new FlatDecorationPainter(); + floats = new float[3]; + floats[0] = 0.0F; + floats[1] = 0.5F; + floats[2] = 1.0F; + colorSchemeSingleColorQueries = new ColorSchemeSingleColorQuery[3]; + colorSchemeSingleColorQueries[0] = ColorSchemeSingleColorQuery.EXTRALIGHT; + colorSchemeSingleColorQueries[1] = ColorSchemeSingleColorQuery.LIGHT; + colorSchemeSingleColorQueries[2] = ColorSchemeSingleColorQuery.MID; + this.highlightPainter = new FractionBasedHighlightPainter("Rebotted", floats, colorSchemeSingleColorQueries); + this.borderPainter = new ClassicBorderPainter(); + this.highlightBorderPainter = new ClassicBorderPainter(); + } + + @Override + public String getDisplayName() { + return "Rebotted"; + } + + private URL getColorSchemes() { + try { + final File scheme = new File("C:\\Users\\Ethan\\IdeaProjects\\Rebotted\\src\\main\\resources\\Rebotted.colorschemes"); + return scheme.toURI().toURL(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/org/rebotted/ui/themes/SubstanceDark.java b/src/main/java/org/rebotted/ui/themes/SubstanceDark.java new file mode 100644 index 0000000..d18216e --- /dev/null +++ b/src/main/java/org/rebotted/ui/themes/SubstanceDark.java @@ -0,0 +1,10 @@ +package org.rebotted.ui.themes; + +import org.pushingpixels.substance.api.SubstanceLookAndFeel; + +public final class SubstanceDark extends SubstanceLookAndFeel { + + public SubstanceDark() { + super(new DarkTheme()); + } +} diff --git a/src/main/java/org/rebotted/util/CacheUtils.java b/src/main/java/org/rebotted/util/CacheUtils.java new file mode 100644 index 0000000..44f980f --- /dev/null +++ b/src/main/java/org/rebotted/util/CacheUtils.java @@ -0,0 +1,86 @@ +package org.rebotted.util; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.zip.GZIPOutputStream; + +import org.rebotted.Client; +import org.rebotted.sign.SignLink; +import org.rebotted.cache.FileStore; + +public final class CacheUtils { + + public static void repackCacheIndex(Client client, FileStore.Store cacheIndex) { + System.out.println("Started repacking index " + cacheIndex.getIndex() + "."); + int indexLength = new File(SignLink.indexLocation(cacheIndex.getIndex(), -1)).listFiles().length; + File[] file = new File(SignLink.indexLocation(cacheIndex.getIndex(), -1)).listFiles(); + try { + for (int index = 0; index < indexLength; index++) { + int fileIndex = Integer.parseInt( + Client.getFileNameWithoutExtension(file[index].toString())); + byte[] data = FileUtils.fileToByteArray(cacheIndex.getIndex(), fileIndex); + if (data != null && data.length > 0) { + client.indices[cacheIndex.getIndex()].writeFile(data.length, data, fileIndex); + System.out.println("Repacked " + fileIndex + "."); + } else { + System.out.println("Unable to locate index " + fileIndex + "."); + } + } + } catch (Exception ex) { + System.out.println("Error packing cache index " + cacheIndex.getIndex() + "."); + } + System.out.println("Finished repacking " + cacheIndex.getIndex() + "."); + } + + public static String getFileNameWithoutExtension(String fileName) { + File tmpFile = new File(fileName); + tmpFile.getName(); + int whereDot = tmpFile.getName().lastIndexOf('.'); + if (0 < whereDot && whereDot <= tmpFile.getName().length() - 2) { + return tmpFile.getName().substring(0, whereDot); + } + return ""; + } + + public static void dumpCacheIndex(Client client, FileStore.Store cacheIndex) { + try { + for (int i = 0;; i++) { + try { + byte[] indexByteArray = client.indices[cacheIndex.getIndex()].decompress(i); + if (indexByteArray == null) { + System.out.println("Finished dumping index " + cacheIndex.getIndex() + + ", exiting dump operation."); + break; + } + + final File dir = new File(SignLink.findcachedir() + "dump" + cacheIndex.getIndex() + "/"); + + if (!dir.exists()) { + dir.mkdirs(); + } + + BufferedOutputStream gzip = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(SignLink.findcachedir() + "dump" + cacheIndex.getIndex() + "/" + i + ".gz"))); + + if (indexByteArray.length == 0) { + continue; + } else { + gzip.write(indexByteArray); + System.out.println("Unpacked " + i + "."); + gzip.close(); + + } + } catch (IOException ex) { + throw new IOException( + "Error writing to folder. Ensure you have this directory created: '" + + SignLink.findcachedir() + "dump" + + cacheIndex.getIndex() + "'"); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/org/rebotted/util/ChatMessageCodec.java b/src/main/java/org/rebotted/util/ChatMessageCodec.java new file mode 100644 index 0000000..bf4c920 --- /dev/null +++ b/src/main/java/org/rebotted/util/ChatMessageCodec.java @@ -0,0 +1,100 @@ +package org.rebotted.util; + +import org.rebotted.io.Buffer; + +public final class ChatMessageCodec { + + private static char[] message = new char[100]; + private static Buffer stream = new Buffer(new byte[100]); + private static final char[] VALID_CHARACTERS = { ' ', '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 decode(int length, Buffer buffer) { + int index = 0; + int next = -1; + for (int count = 0; count < length; count++) { + int in = buffer.readUnsignedByte(); + int charIndex = in >> 4 & 0xf; + if (next == -1) { + if (charIndex < 13) + message[index++] = VALID_CHARACTERS[charIndex]; + else + next = charIndex; + } else { + message[index++] = VALID_CHARACTERS[((next << 4) + charIndex) - 195]; + next = -1; + } + charIndex = in & 0xf; + if (next == -1) { + if (charIndex < 13) + message[index++] = VALID_CHARACTERS[charIndex]; + else + next = charIndex; + } else { + message[index++] = VALID_CHARACTERS[((next << 4) + charIndex) - 195]; + next = -1; + } + } + + boolean capitaliseNext = true; + for (int count = 0; count < index; count++) { + char character = message[count]; + if (capitaliseNext && character >= 'a' && character <= 'z') { + message[count] += '\uFFE0'; + capitaliseNext = false; + } + if (character == '.' || character == '!' || character == '?') + capitaliseNext = true; + } + return new String(message, 0, index); + } + + public static void encode(String string, Buffer buffer) { + if (string.length() > 80) + string = string.substring(0, 80); + string = string.toLowerCase(); + int next = -1; + for (int index = 0; index < string.length(); index++) { + char character = string.charAt(index); + int charIndex = 0; + for (int count = 0; count < VALID_CHARACTERS.length; count++) { + if (character != VALID_CHARACTERS[count]) + continue; + charIndex = count; + break; + } + + if (charIndex > 12) { + charIndex += 195; + } + if (next == -1) { + if (charIndex < 13) + next = charIndex; + else + buffer.writeByte(charIndex); + } else if (charIndex < 13) { + buffer.writeByte((next << 4) + charIndex); + next = -1; + } else { + buffer.writeByte((next << 4) + (charIndex >> 4)); + next = charIndex & 0xf; + } + } + if (next != -1) { + buffer.writeByte(next << 4); + } + } + + public static String processText(String string) { + stream.currentPosition = 0; + encode(string, stream); + int length = stream.currentPosition; + stream.currentPosition = 0; + + return decode(length, stream); + } +} diff --git a/src/main/java/org/rebotted/util/ChunkUtil.java b/src/main/java/org/rebotted/util/ChunkUtil.java new file mode 100644 index 0000000..e19d3c1 --- /dev/null +++ b/src/main/java/org/rebotted/util/ChunkUtil.java @@ -0,0 +1,53 @@ +package org.rebotted.util; + +public final class ChunkUtil { + + public static int method155(int i, int j, int k) { + i &= 3; + if (i == 0) + return k; + if (i == 1) + return j; + if (i == 2) + return 7 - k; + else + return 7 - j; + } + + public static int method156(int i, int j, int l) { + j &= 3; + if (j == 0) + return i; + if (j == 1) + return 7 - l; + if (j == 2) + return 7 - i; + else + return l; + } + + public static int method157(int i, int j, int k, int l, int i1) { + i &= 3; + if (i == 0) + return k; + if (i == 1) + return l; + if (i == 2) + return 7 - k - (i1 - 1); + else + return 7 - l - (j - 1); + } + + public static int method158(int j, int k, int l, int i1, int j1) { + l &= 3; + if (l == 0) + return j; + if (l == 1) + return 7 - j1 - (i1 - 1); + if (l == 2) + return 7 - j - (k - 1); + else + return j1; + } + +} diff --git a/src/main/java/org/rebotted/util/CreateUID.java b/src/main/java/org/rebotted/util/CreateUID.java new file mode 100644 index 0000000..f697d6e --- /dev/null +++ b/src/main/java/org/rebotted/util/CreateUID.java @@ -0,0 +1,53 @@ +package org.rebotted.util; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.UUID; + +public final class CreateUID { + + private static final String PATH = + System.getProperty("user.home") + File.separator + "uuid.dat"; + + public static String generateUID() throws Exception { + String uuid = getUUID(); + try { + + File dir = new File(PATH); + + if (!dir.exists()) { + write(uuid); + return uuid; + } + + read(uuid); + + } catch (Exception e) { + e.printStackTrace(); + } + return uuid; + } + + private static void write(String data) throws FileNotFoundException, IOException{ + try(DataOutputStream output = new DataOutputStream(new FileOutputStream(PATH))) { + output.writeUTF(data); + output.flush(); + } + } + + private static void read(String data) throws FileNotFoundException, IOException { + try(DataInputStream input = new DataInputStream(new FileInputStream(PATH))) { + data = input.readUTF(); + } + } + + private static String getUUID() { + return UUID.randomUUID().toString(); + } + +} diff --git a/src/main/java/org/rebotted/util/FileUtils.java b/src/main/java/org/rebotted/util/FileUtils.java new file mode 100644 index 0000000..67a0268 --- /dev/null +++ b/src/main/java/org/rebotted/util/FileUtils.java @@ -0,0 +1,197 @@ +package org.rebotted.util; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageFilter; +import java.awt.image.ImageProducer; +import java.awt.image.RGBImageFilter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.util.zip.CRC32; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import javax.imageio.ImageIO; + +import org.rebotted.sign.SignLink; + +public final class FileUtils { + + public static BufferedImage imageToBufferedImage(Image image) { + BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), + BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = bufferedImage.createGraphics(); + g2.drawImage(image, 0, 0, null); + g2.dispose(); + return bufferedImage; + } + + /** + * Converts an array of bytes to a {@link BufferedImage}. + * + * @param data + * The array of pixels. + * + * @return The newly created image. + */ + public static BufferedImage byteArrayToImage(byte[] data) throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream(data); + BufferedImage image = ImageIO.read(in); + return image; + } + + public static Image makeColorTransparent(BufferedImage im, final Color color) { + ImageFilter filter = new RGBImageFilter() { + + public int markerRGB = color.getRGB() | 0xFF000000; + + public final int filterRGB(int x, int y, int rgb) { + if ((rgb | 0xFF000000) == markerRGB) { + return 0x00FFFFFF & rgb; + } else { + return rgb; + } + } + }; + ImageProducer ip = new FilteredImageSource(im.getSource(), filter); + return Toolkit.getDefaultToolkit().createImage(ip); + } + + public static void writeFile(File f, byte[] data) { + try { + RandomAccessFile raf = new RandomAccessFile(f, "rw"); + try { + raf.write(data); + } finally { + raf.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void writeFile(byte[] data, String fileName) throws IOException { + OutputStream out = new FileOutputStream(fileName); + out.write(data); + out.close(); + } + + public static byte[] fileToByteArray(int cacheIndex, int index) { + try { + if (SignLink.indexLocation(cacheIndex, index).length() <= 0 + || SignLink.indexLocation(cacheIndex, index) == null) { + return null; + } + File file = new File(SignLink.indexLocation(cacheIndex, index)); + byte[] fileData = new byte[(int) file.length()]; + FileInputStream fis = new FileInputStream(file); + fis.read(fileData); + fis.close(); + return fileData; + } catch (Exception e) { + return null; + } + } + + public static int readJAGHash(String string) { + int id = 0; + string = string.toUpperCase(); + for (int j = 0; j < string.length(); j++) { + id = (id * 61 + string.charAt(j)) - 32; + } + return id; + } + + public static int getCRCFromData(byte[] data) { + CRC32 crc = new CRC32(); + crc.update(data); + return (int) crc.getValue(); + } + + public static byte[] gZipDecompress(byte[] b) throws IOException { + GZIPInputStream gzi = new GZIPInputStream(new ByteArrayInputStream(b)); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buf = new byte[1024]; + int len; + try { + while ((len = gzi.read(buf, 0, buf.length)) > 0) { + out.write(buf, 0, len); + } + } finally { + out.close(); + } + return out.toByteArray(); + } + + public static byte[] gzDecompress(byte[] b) throws IOException { + GZIPInputStream gzi = new GZIPInputStream(new ByteArrayInputStream(b)); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buf = new byte[1024]; + int len; + while ((len = gzi.read(buf)) > 0) { + out.write(buf, 0, len); + } + out.close(); + return out.toByteArray(); + } + + public static byte[] unzip(byte[] data) throws IOException { + InputStream in = new ByteArrayInputStream(data); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + in = new GZIPInputStream(in); + byte[] buffer = new byte[65536]; + int noRead; + while ((noRead = in.read(buffer)) != -1) { + out.write(buffer, 0, noRead); + } + } finally { + try { + out.close(); + } catch (Exception e) { + } + } + return out.toByteArray(); + } + + public static byte[] readFile(String name) { + File file = new File(name); + + byte[] data = new byte[(int) file.length()]; + + try (FileInputStream fis = new FileInputStream(file)) { + fis.read(data); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return data.length > 0 ? data : null; + + } + + public static byte[] gZipCompress(byte[] data, int off, int len) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + GZIPOutputStream gzo = new GZIPOutputStream(bos); + try { + gzo.write(data, off, len); + } finally { + gzo.close(); + bos.close(); + } + return bos.toByteArray(); + } +} diff --git a/src/main/java/org/rebotted/util/ImageUtils.java b/src/main/java/org/rebotted/util/ImageUtils.java new file mode 100644 index 0000000..5cc352d --- /dev/null +++ b/src/main/java/org/rebotted/util/ImageUtils.java @@ -0,0 +1,51 @@ +package org.rebotted.util; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageFilter; +import java.awt.image.ImageProducer; +import java.awt.image.RGBImageFilter; + +public final class ImageUtils { + + private ImageUtils() { + + } + + public static BufferedImage imageToBufferedImage(Image image) { + + BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = bufferedImage.createGraphics(); + g2.drawImage(image, 0, 0, null); + g2.dispose(); + + return bufferedImage; + + } + + public static Image makeColorTransparent(BufferedImage im, final Color color) { + ImageFilter filter = new RGBImageFilter() { + + // the color we are looking for... Alpha bits are set to opaque + public int markerRGB = color.getRGB() | 0xFF000000; + + public final int filterRGB(int x, int y, int rgb) { + if ((rgb | 0xFF000000) == markerRGB) { + // Mark the alpha bits as zero - transparent + return 0x00FFFFFF & rgb; + } else { + // nothing to do + return rgb; + } + } + }; + + ImageProducer ip = new FilteredImageSource(im.getSource(), filter); + return Toolkit.getDefaultToolkit().createImage(ip); + } + +} diff --git a/src/main/java/org/rebotted/util/LoggerUtils.java b/src/main/java/org/rebotted/util/LoggerUtils.java new file mode 100644 index 0000000..87fb7f4 --- /dev/null +++ b/src/main/java/org/rebotted/util/LoggerUtils.java @@ -0,0 +1,11 @@ +package org.rebotted.util; + +import java.util.logging.Logger; + +public final class LoggerUtils { + + public static Logger getLogger(Class clazz) { + return Logger.getLogger(clazz.getName()); + } + +} diff --git a/src/main/java/org/rebotted/util/MessageCensor.java b/src/main/java/org/rebotted/util/MessageCensor.java new file mode 100644 index 0000000..10d4eaa --- /dev/null +++ b/src/main/java/org/rebotted/util/MessageCensor.java @@ -0,0 +1,835 @@ +package org.rebotted.util; + +import org.rebotted.cache.FileArchive; +import org.rebotted.io.Buffer; + +public final class MessageCensor { + + private static int[] fragments; + private static char[][] badWords; + private static byte[][][] badEncoding; + private static char[][] domains; + private static char[][] tldList; + private static int[] tlds; + private static final String[] exceptions = { "cook", "cook's", "cooks", + "seeks", "sheet", "woop", "woops", "faq", "noob", "noobs" }; + + public static void load(FileArchive archive) { + Buffer fragments = new Buffer( + archive.readFile("fragmentsenc.txt")); + Buffer bad = new Buffer(archive.readFile("badenc.txt")); + Buffer domain = new Buffer(archive.readFile("domainenc.txt")); + Buffer tldlist = new Buffer(archive.readFile("tldlist.txt")); + decode(fragments, bad, domain, tldlist); + } + + private static void decode(Buffer fragments, Buffer badenc, + Buffer domainenc, Buffer tldlist) { + decodeBadEnc(badenc); + decodeDomainEnc(domainenc); + decodeFragmentsEnc(fragments); + decodeTldList(tldlist); + } + + private static void decodeTldList(Buffer stream) { + int i = stream.readInt(); + tldList = new char[i][]; + tlds = new int[i]; + for (int j = 0; j < i; j++) { + tlds[j] = stream.readUnsignedByte(); + char ac[] = new char[stream.readUnsignedByte()]; + for (int k = 0; k < ac.length; k++) + ac[k] = (char) stream.readUnsignedByte(); + + tldList[j] = ac; + } + + } + + private static void decodeBadEnc(Buffer stream) { + int j = stream.readInt(); + badWords = new char[j][]; + badEncoding = new byte[j][][]; + initBad(stream, badWords, badEncoding); + } + + private static void decodeDomainEnc(Buffer stream) { + int i = stream.readInt(); + domains = new char[i][]; + initDomains(domains, stream); + } + + private static void decodeFragmentsEnc(Buffer stream) { + fragments = new int[stream.readInt()]; + for (int i = 0; i < fragments.length; i++) + fragments[i] = stream.readUShort(); + } + + private static void initBad(Buffer stream, char[][] words, + byte[][][] complexBadEnc) { + for (int index = 0; index < words.length; index++) { + char[] word = new char[stream.readUnsignedByte()]; + for (int character = 0; character < word.length; character++) + word[character] = (char) stream.readUnsignedByte(); + + words[index] = word; + byte complex[][] = new byte[stream.readUnsignedByte()][2]; + for (int l = 0; l < complex.length; l++) { + complex[l][0] = (byte) stream.readUnsignedByte(); + complex[l][1] = (byte) stream.readUnsignedByte(); + } + + if (complex.length > 0) + complexBadEnc[index] = complex; + } + + } + + private static void initDomains(char[][] domains, Buffer stream) { + for (int index = 0; index < domains.length; index++) { + char[] domain = new char[stream.readUnsignedByte()]; + for (int k = 0; k < domain.length; k++) + domain[k] = (char) stream.readUnsignedByte(); + + domains[index] = domain; + } + + } + + private static void stripIllegalCharacters(char ac[]) { + int i = 0; + for (int j = 0; j < ac.length; j++) { + if (legalCharacter(ac[j])) + ac[i] = ac[j]; + else + ac[i] = ' '; + if (i == 0 || ac[i] != ' ' || ac[i - 1] != ' ') + i++; + } + for (int k = i; k < ac.length; k++) + ac[k] = ' '; + + } + + private static boolean legalCharacter(char c) { + return c >= ' ' && c <= '\177' || c == ' ' || c == '\n' || c == '\t' + || c == '\243' || c == '\u20AC'; + } + + public static String apply(String message) { + System.currentTimeMillis(); + char[] chars = message.toCharArray(); + stripIllegalCharacters(chars); + String trimmed = (new String(chars)).trim(); + chars = trimmed.toLowerCase().toCharArray(); + String trimmedLowerCase = trimmed.toLowerCase(); + censorTlds(chars); + censorBad(chars); + censorDomains(chars); + method514(chars); + for (int index = 0; index < exceptions.length; index++) { + for (int k = -1; (k = trimmedLowerCase.indexOf(exceptions[index], + k + 1)) != -1;) { + char ac1[] = exceptions[index].toCharArray(); + System.arraycopy(ac1, 0, chars, k, ac1.length); + + } + } + copyCase(trimmed.toCharArray(), chars); + capitalize(chars); + System.currentTimeMillis(); + return (new String(chars)).trim(); + } + + private static void copyCase(char ac[], char ac1[]) { + for (int j = 0; j < ac.length; j++) + if (ac1[j] != '*' && isUpperCase(ac[j])) + ac1[j] = ac[j]; + } + + private static void capitalize(char[] chars) { + boolean flag = true; + for (int index = 0; index < chars.length; index++) { + char character = chars[index]; + if (isLetter(character)) { + if (flag) { + if (isLowerCase(character)) + flag = false; + } else if (isUpperCase(character)) + chars[index] = (char) ((character + 97) - 65); + } else { + flag = true; + } + } + } + + private static void censorBad(char[] message) { + for (int i = 0; i < 2; i++) { + for (int word = badWords.length - 1; word >= 0; word--) + method509(badEncoding[word], message, badWords[word]); + + } + } + + private static void censorDomains(char ac[]) { + char ac1[] = ac.clone(); + char ac2[] = { '(', 'a', ')' }; + method509(null, ac1, ac2); + char ac3[] = ac.clone(); + char ac4[] = { 'd', 'o', 't' }; + method509(null, ac3, ac4); + for (int i = domains.length - 1; i >= 0; i--) + method502(ac, domains[i], ac3, ac1); + } + + private static void method502(char ac[], char ac1[], char ac2[], char ac3[]) { + if (ac1.length > ac.length) + return; + int j; + for (int k = 0; k <= ac.length - ac1.length; k += j) { + int l = k; + int i1 = 0; + j = 1; + while (l < ac.length) { + int j1; + char c = ac[l]; + char c1 = '\0'; + if (l + 1 < ac.length) + c1 = ac[l + 1]; + if (i1 < ac1.length && (j1 = method511(c, ac1[i1], c1)) > 0) { + l += j1; + i1++; + continue; + } + if (i1 == 0) + break; + if ((j1 = method511(c, ac1[i1 - 1], c1)) > 0) { + l += j1; + if (i1 == 1) + j++; + continue; + } + if (i1 >= ac1.length || !isNotAlphanumeric(c)) + break; + l++; + } + if (i1 >= ac1.length) { + boolean flag1 = false; + int k1 = method503(ac, ac3, k); + int l1 = method504(ac2, l - 1, ac); + if (k1 > 2 || l1 > 2) + flag1 = true; + if (flag1) { + for (int i2 = k; i2 < l; i2++) + ac[i2] = '*'; + + } + } + } + + } + + private static int method503(char ac[], char ac1[], int j) { + if (j == 0) + return 2; + for (int k = j - 1; k >= 0; k--) { + if (!isNotAlphanumeric(ac[k])) + break; + if (ac[k] == '@') + return 3; + } + + int l = 0; + for (int i1 = j - 1; i1 >= 0; i1--) { + if (!isNotAlphanumeric(ac1[i1])) + break; + if (ac1[i1] == '*') + l++; + } + + if (l >= 3) + return 4; + return !isNotAlphanumeric(ac[j - 1]) ? 0 : 1; + } + + private static int method504(char ac[], int i, char ac1[]) { + if (i + 1 == ac1.length) + return 2; + for (int j = i + 1; j < ac1.length; j++) { + if (!isNotAlphanumeric(ac1[j])) + break; + if (ac1[j] == '.' || ac1[j] == ',') + return 3; + } + int k = 0; + for (int l = i + 1; l < ac1.length; l++) { + if (!isNotAlphanumeric(ac[l])) + break; + if (ac[l] == '*') + k++; + } + + if (k >= 3) + return 4; + return !isNotAlphanumeric(ac1[i + 1]) ? 0 : 1; + } + + private static void censorTlds(char[] chars) { + char[] clone = chars.clone(); + char[] dot = { 'd', 'o', 't' }; + method509(null, clone, dot); + char[] clone2 = chars.clone(); + char[] slash = { 's', 'l', 'a', 's', 'h' }; + method509(null, clone2, slash); + for (int index = 0; index < tldList.length; index++) + method506(clone2, tldList[index], tlds[index], clone, + chars); + } + + private static void method506(char ac[], char ac1[], int i, char ac2[], + char ac3[]) { + if (ac1.length > ac3.length) + return; + int j; + for (int k = 0; k <= ac3.length - ac1.length; k += j) { + int l = k; + int i1 = 0; + j = 1; + while (l < ac3.length) { + int j1; + char c = ac3[l]; + char c1 = '\0'; + if (l + 1 < ac3.length) + c1 = ac3[l + 1]; + if (i1 < ac1.length && (j1 = method511(c, ac1[i1], c1)) > 0) { + l += j1; + i1++; + continue; + } + if (i1 == 0) + break; + if ((j1 = method511(c, ac1[i1 - 1], c1)) > 0) { + l += j1; + if (i1 == 1) + j++; + continue; + } + if (i1 >= ac1.length || !isNotAlphanumeric(c)) + break; + l++; + } + if (i1 >= ac1.length) { + boolean flag1 = false; + int k1 = method507(ac3, k, ac2); + int l1 = method508(ac3, ac, l - 1); + if (i == 1 && k1 > 0 && l1 > 0) + flag1 = true; + if (i == 2 && (k1 > 2 && l1 > 0 || k1 > 0 && l1 > 2)) + flag1 = true; + if (i == 3 && k1 > 0 && l1 > 2) + flag1 = true; + if (flag1) { + int i2 = k; + int j2 = l - 1; + if (k1 > 2) { + if (k1 == 4) { + boolean flag2 = false; + for (int l2 = i2 - 1; l2 >= 0; l2--) + if (flag2) { + if (ac2[l2] != '*') + break; + i2 = l2; + } else if (ac2[l2] == '*') { + i2 = l2; + flag2 = true; + } + + } + boolean flag3 = false; + for (int i3 = i2 - 1; i3 >= 0; i3--) + if (flag3) { + if (isNotAlphanumeric(ac3[i3])) + break; + i2 = i3; + } else if (!isNotAlphanumeric(ac3[i3])) { + flag3 = true; + i2 = i3; + } + + } + if (l1 > 2) { + if (l1 == 4) { + boolean flag4 = false; + for (int j3 = j2 + 1; j3 < ac3.length; j3++) + if (flag4) { + if (ac[j3] != '*') + break; + j2 = j3; + } else if (ac[j3] == '*') { + j2 = j3; + flag4 = true; + } + + } + boolean flag5 = false; + for (int k3 = j2 + 1; k3 < ac3.length; k3++) + if (flag5) { + if (isNotAlphanumeric(ac3[k3])) + break; + j2 = k3; + } else if (!isNotAlphanumeric(ac3[k3])) { + flag5 = true; + j2 = k3; + } + + } + for (int k2 = i2; k2 <= j2; k2++) + ac3[k2] = '*'; + + } + } + } + } + + private static int method507(char ac[], int j, char ac1[]) { + if (j == 0) + return 2; + for (int k = j - 1; k >= 0; k--) { + if (!isNotAlphanumeric(ac[k])) + break; + if (ac[k] == ',' || ac[k] == '.') + return 3; + } + + int l = 0; + for (int i1 = j - 1; i1 >= 0; i1--) { + if (!isNotAlphanumeric(ac1[i1])) + break; + if (ac1[i1] == '*') + l++; + } + if (l >= 3) + return 4; + return !isNotAlphanumeric(ac[j - 1]) ? 0 : 1; + } + + private static int method508(char ac[], char ac1[], int i) { + if (i + 1 == ac.length) + return 2; + for (int j = i + 1; j < ac.length; j++) { + if (!isNotAlphanumeric(ac[j])) + break; + if (ac[j] == '\\' || ac[j] == '/') + return 3; + } + + int k = 0; + for (int l = i + 1; l < ac.length; l++) { + if (!isNotAlphanumeric(ac1[l])) + break; + if (ac1[l] == '*') + k++; + } + + if (k >= 5) + return 4; + return !isNotAlphanumeric(ac[i + 1]) ? 0 : 1; + } + + private static void method509(byte abyte0[][], char ac[], char ac1[]) { + if (ac1.length > ac.length) + return; + int j; + for (int k = 0; k <= ac.length - ac1.length; k += j) { + int l = k; + int i1 = 0; + int j1 = 0; + j = 1; + boolean flag1 = false; + boolean flag2 = false; + boolean flag3 = false; + while (l < ac.length && (!flag2 || !flag3)) { + int k1; + char c = ac[l]; + char c2 = '\0'; + if (l + 1 < ac.length) + c2 = ac[l + 1]; + if (i1 < ac1.length && (k1 = method512(c2, c, ac1[i1])) > 0) { + if (k1 == 1 && isDigit(c)) + flag2 = true; + if (k1 == 2 && (isDigit(c) || isDigit(c2))) + flag2 = true; + l += k1; + i1++; + continue; + } + if (i1 == 0) + break; + if ((k1 = method512(c2, c, ac1[i1 - 1])) > 0) { + l += k1; + if (i1 == 1) + j++; + continue; + } + if (i1 >= ac1.length || !method518(c)) + break; + if (isNotAlphanumeric(c) && c != '\'') + flag1 = true; + if (isDigit(c)) + flag3 = true; + l++; + if ((++j1 * 100) / (l - k) > 90) + break; + } + if (i1 >= ac1.length && (!flag2 || !flag3)) { + boolean flag4 = true; + if (!flag1) { + char c1 = ' '; + if (k - 1 >= 0) + c1 = ac[k - 1]; + char c3 = ' '; + if (l < ac.length) + c3 = ac[l]; + byte byte0 = method513(c1); + byte byte1 = method513(c3); + if (abyte0 != null && method510(byte0, abyte0, byte1)) + flag4 = false; + } else { + boolean flag5 = false; + boolean flag6 = false; + if (k - 1 < 0 || isNotAlphanumeric(ac[k - 1]) + && ac[k - 1] != '\'') + flag5 = true; + if (l >= ac.length || isNotAlphanumeric(ac[l]) + && ac[l] != '\'') + flag6 = true; + if (!flag5 || !flag6) { + boolean flag7 = false; + int k2 = k - 2; + if (flag5) + k2 = k; + for (; !flag7 && k2 < l; k2++) + if (k2 >= 0 + && (!isNotAlphanumeric(ac[k2]) || ac[k2] == '\'')) { + char ac2[] = new char[3]; + int j3; + for (j3 = 0; j3 < 3; j3++) { + if (k2 + j3 >= ac.length + || isNotAlphanumeric(ac[k2 + j3]) + && ac[k2 + j3] != '\'') + break; + ac2[j3] = ac[k2 + j3]; + } + + boolean flag8 = true; + if (j3 == 0) + flag8 = false; + if (j3 < 3 + && k2 - 1 >= 0 + && (!isNotAlphanumeric(ac[k2 - 1]) || ac[k2 - 1] == '\'')) + flag8 = false; + if (flag8 && !containsFragment(ac2)) + flag7 = true; + } + + if (!flag7) + flag4 = false; + } + } + if (flag4) { + int l1 = 0; + int i2 = 0; + int j2 = -1; + for (int l2 = k; l2 < l; l2++) + if (isDigit(ac[l2])) + l1++; + else if (isLetter(ac[l2])) { + i2++; + j2 = l2; + } + + if (j2 > -1) + l1 -= l - 1 - j2; + if (l1 <= i2) { + for (int i3 = k; i3 < l; i3++) + ac[i3] = '*'; + + } else { + j = 1; + } + } + } + } + + } + + private static boolean method510(byte byte0, byte abyte0[][], byte byte2) { + int i = 0; + if (abyte0[i][0] == byte0 && abyte0[i][1] == byte2) + return true; + int j = abyte0.length - 1; + if (abyte0[j][0] == byte0 && abyte0[j][1] == byte2) + return true; + do { + int k = (i + j) / 2; + if (abyte0[k][0] == byte0 && abyte0[k][1] == byte2) + return true; + if (byte0 < abyte0[k][0] || byte0 == abyte0[k][0] + && byte2 < abyte0[k][1]) + j = k; + else + i = k; + } while (i != j && i + 1 != j); + return false; + } + + private static int method511(char c, char c1, char c2) { + if (c1 == c) + return 1; + if (c1 == 'o' && c == '0') + return 1; + if (c1 == 'o' && c == '(' && c2 == ')') + return 2; + if (c1 == 'c' && (c == '(' || c == '<' || c == '[')) + return 1; + if (c1 == 'e' && c == '\u20AC') + return 1; + if (c1 == 's' && c == '$') + return 1; + return c1 != 'l' || c != 'i' ? 0 : 1; + } + + private static int method512(char c, char c1, char c2) { + if (c2 == c1) + return 1; + if (c2 >= 'a' && c2 <= 'm') { + if (c2 == 'a') { + if (c1 == '4' || c1 == '@' || c1 == '^') + return 1; + return c1 != '/' || c != '\\' ? 0 : 2; + } + if (c2 == 'b') { + if (c1 == '6' || c1 == '8') + return 1; + return (c1 != '1' || c != '3') && (c1 != 'i' || c != '3') ? 0 + : 2; + } + if (c2 == 'c') + return c1 != '(' && c1 != '<' && c1 != '{' && c1 != '[' ? 0 : 1; + if (c2 == 'd') + return (c1 != '[' || c != ')') && (c1 != 'i' || c != ')') ? 0 + : 2; + if (c2 == 'e') + return c1 != '3' && c1 != '\u20AC' ? 0 : 1; + if (c2 == 'f') { + if (c1 == 'p' && c == 'h') + return 2; + return c1 != '\243' ? 0 : 1; + } + if (c2 == 'g') + return c1 != '9' && c1 != '6' && c1 != 'q' ? 0 : 1; + if (c2 == 'h') + return c1 != '#' ? 0 : 1; + if (c2 == 'i') + return c1 != 'y' && c1 != 'l' && c1 != 'j' && c1 != '1' + && c1 != '!' && c1 != ':' && c1 != ';' && c1 != '|' ? 0 + : 1; + if (c2 == 'j') + return 0; + if (c2 == 'k') + return 0; + if (c2 == 'l') + return c1 != '1' && c1 != '|' && c1 != 'i' ? 0 : 1; + if (c2 == 'm') + return 0; + } + if (c2 >= 'n' && c2 <= 'z') { + if (c2 == 'n') + return 0; + if (c2 == 'o') { + if (c1 == '0' || c1 == '*') + return 1; + return (c1 != '(' || c != ')') && (c1 != '[' || c != ']') + && (c1 != '{' || c != '}') && (c1 != '<' || c != '>') ? 0 + : 2; + } + if (c2 == 'p') + return 0; + if (c2 == 'q') + return 0; + if (c2 == 'r') + return 0; + if (c2 == 's') + return c1 != '5' && c1 != 'z' && c1 != '$' && c1 != '2' ? 0 : 1; + if (c2 == 't') + return c1 != '7' && c1 != '+' ? 0 : 1; + if (c2 == 'u') { + if (c1 == 'v') + return 1; + return (c1 != '\\' || c != '/') && (c1 != '\\' || c != '|') + && (c1 != '|' || c != '/') ? 0 : 2; + } + if (c2 == 'v') + return (c1 != '\\' || c != '/') && (c1 != '\\' || c != '|') + && (c1 != '|' || c != '/') ? 0 : 2; + if (c2 == 'w') + return c1 != 'v' || c != 'v' ? 0 : 2; + if (c2 == 'x') + return (c1 != ')' || c != '(') && (c1 != '}' || c != '{') + && (c1 != ']' || c != '[') && (c1 != '>' || c != '<') ? 0 + : 2; + if (c2 == 'y') + return 0; + if (c2 == 'z') + return 0; + } + if (c2 >= '0' && c2 <= '9') { + if (c2 == '0') { + if (c1 == 'o' || c1 == 'O') + return 1; + return (c1 != '(' || c != ')') && (c1 != '{' || c != '}') + && (c1 != '[' || c != ']') ? 0 : 2; + } + if (c2 == '1') + return c1 != 'l' ? 0 : 1; + else + return 0; + } + if (c2 == ',') + return c1 != '.' ? 0 : 1; + if (c2 == '.') + return c1 != ',' ? 0 : 1; + if (c2 == '!') + return c1 != 'i' ? 0 : 1; + else + return 0; + } + + private static byte method513(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; + } + + private static void method514(char ac[]) { + int j; + int k = 0; + int l = 0; + int i1 = 0; + while ((j = method515(ac, k)) != -1) { + boolean flag = false; + for (int j1 = k; j1 >= 0 && j1 < j && !flag; j1++) + if (!isNotAlphanumeric(ac[j1]) && !method518(ac[j1])) + flag = true; + + if (flag) + l = 0; + if (l == 0) + i1 = j; + k = method516(ac, j); + int k1 = 0; + for (int l1 = j; l1 < k; l1++) + k1 = (k1 * 10 + ac[l1]) - 48; + + if (k1 > 255 || k - j > 8) + l = 0; + else + l++; + if (l == 4) { + for (int i2 = i1; i2 < k; i2++) + ac[i2] = '*'; + + l = 0; + } + } + } + + private static int method515(char ac[], int i) { + for (int k = i; k < ac.length && k >= 0; k++) + if (ac[k] >= '0' && ac[k] <= '9') + return k; + + return -1; + } + + private static int method516(char ac[], int j) { + for (int k = j; k < ac.length && k >= 0; k++) + if (ac[k] < '0' || ac[k] > '9') + return k; + return ac.length; + } + + private static boolean containsFragment(char[] chars) { + boolean onlyDigits = true; + for (int index = 0; index < chars.length; index++) + if (!isDigit(chars[index]) && chars[index] != 0) + onlyDigits = false; + + if (onlyDigits) + return true; + int code = hash(chars); + int index = 0; + int length = fragments.length - 1; + if (code == fragments[index] || code == fragments[length]) + return true; + do { + int i1 = (index + length) / 2; + if (code == fragments[i1]) + return true; + if (code < fragments[i1]) + length = i1; + else + index = i1; + } while (index != length && index + 1 != length); + return false; + } + + private static int hash(char ac[]) { + if (ac.length > 6) + return 0; + int k = 0; + for (int l = 0; l < ac.length; l++) { + char c = ac[ac.length - l - 1]; + if (c >= 'a' && c <= 'z') + k = k * 38 + ((c - 97) + 1); + else if (c == '\'') + k = k * 38 + 27; + else if (c >= '0' && c <= '9') + k = k * 38 + ((c - 48) + 28); + else if (c != 0) + return 0; + } + + return k; + } + + private static boolean isNotAlphanumeric(char c) { + return !isLetter(c) && !isDigit(c); + } + + private static boolean method518(char c) { + return c < 'a' || c > 'z' || c == 'v' || c == 'x' || c == 'j' + || c == 'q' || c == 'z'; + } + + private static boolean isLetter(char c) { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'; + } + + private static boolean isDigit(char c) { + return c >= '0' && c <= '9'; + } + + private static boolean isLowerCase(char c) { + return c >= 'a' && c <= 'z'; + } + + private static boolean isUpperCase(char c) { + return c >= 'A' && c <= 'Z'; + } +} diff --git a/src/main/java/org/rebotted/util/MiscUtils.java b/src/main/java/org/rebotted/util/MiscUtils.java new file mode 100644 index 0000000..7d2a1aa --- /dev/null +++ b/src/main/java/org/rebotted/util/MiscUtils.java @@ -0,0 +1,35 @@ +package org.rebotted.util; + +import java.lang.reflect.Method; + +public final class MiscUtils { + + public static void launchURL(String url) { + String osName = System.getProperty("os.name"); + try { + if (osName.startsWith("Mac OS")) { + Class fileMgr = Class.forName("com.apple.eio.FileManager"); + Method openURL = fileMgr.getDeclaredMethod("openURL", + new Class[] {String.class}); + openURL.invoke(null, new Object[] {url}); + } else if (osName.startsWith("Windows")) + Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url); + else { + String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", + "netscape", "safari"}; + String browser = null; + for (int count = 0; count < browsers.length && browser == null; count++) + if (Runtime.getRuntime().exec(new String[] {"which", browsers[count]}) + .waitFor() == 0) + browser = browsers[count]; + if (browser == null) { + throw new Exception("Could not find web browser"); + } else + Runtime.getRuntime().exec(new String[] {browser, url}); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/src/main/java/org/rebotted/util/MouseDetection.java b/src/main/java/org/rebotted/util/MouseDetection.java new file mode 100644 index 0000000..499efee --- /dev/null +++ b/src/main/java/org/rebotted/util/MouseDetection.java @@ -0,0 +1,37 @@ +package org.rebotted.util; + +import org.rebotted.Client; + +public final class MouseDetection implements Runnable { + + public void run() { + while (running) { + synchronized (syncObject) { + if (coordsIndex < 500) { + coordsX[coordsIndex] = clientInstance.mouseX; + coordsY[coordsIndex] = clientInstance.mouseY; + coordsIndex++; + } + } + try { + Thread.sleep(50L); + } catch (Exception _ex) { + } + } + } + + public MouseDetection(Client client1) { + syncObject = new Object(); + coordsY = new int[500]; + running = true; + coordsX = new int[500]; + clientInstance = client1; + } + + private Client clientInstance; + public final Object syncObject; + public final int[] coordsY; + public boolean running; + public final int[] coordsX; + public int coordsIndex; +} diff --git a/src/main/java/org/rebotted/util/PacketConstants.java b/src/main/java/org/rebotted/util/PacketConstants.java new file mode 100644 index 0000000..b37024b --- /dev/null +++ b/src/main/java/org/rebotted/util/PacketConstants.java @@ -0,0 +1,247 @@ +package org.rebotted.util; +/** + * The class that contains packet-related constants. + * + * @author Seven + * @author TheChosenOne + */ +public final class PacketConstants { + + private PacketConstants() { + + } + + public static final int FOCUS_CHANGE = 3; + + public static final int FLAG_ACCOUNT = 45; + + public static final int ADD_FRIEND = 188; + + public static final int REPORT_PLAYER = 218; + + public static final int IDLE = 0; + + public static final int CAMERA_MOVEMENT = 86; + + public static final int ENTER_REGION = 210; + + public static final int PLAYER_UPDATING = 81; + + public static final int DELETE_GROUND_ITEM = 64; + + public static final int SEND_REMOVE_GROUND_ITEM = 156; + + public static final int SEND_OBJECT = 151; + + public static final int TRANSFORM_PLAYER_TO_OBJECT = 147; + + public static final int SEND_REMOVE_OBJECT = 101; + + public static final int DESIGN_SCREEN = 101; + + public static final int SEND_PROJECTILE = 117; + + public static final int ANIMATE_OBJECT = 160; + + public static final int SEND_ALTER_GROUND_ITEM_COUNT = 84; + + public static final int SEND_GROUND_ITEM = 44; + + public static final int SEND_GFX = 4; + + public static final int OPEN_WELCOME_SCREEN = 176; + + public static final int SHOW_PLAYER_HEAD_ON_INTERFACE = 185; + + public static final int BUTTON_CLICK = 185; + + public static final int CLAN_CHAT = 217; // 317 did not have this + + public static final int RESET_CAMERA = 107; + + public static final int CLEAN_ITEMS_OF_INTERFACE = 72; + + public static final int SHOW_IGNORE_NAMES = 214; + + public static final int MOVE_ITEM = 214; + + public static final int SPIN_CAMERA = 166; + + public static final int SEND_SKILL = 134; + + public static final int SEND_SIDE_TAB = 71; + + public static final int PLAY_SONG = 74; + + public static final int NEXT_OR_PREVIOUS_SONG = 121; + + public static final int LOADED_REGION = 121; + + public static final int LOGOUT = 109; + + public static final int MOVE_COMPONENT = 70; + + public static final int SEND_WALKABLE_INTERFACE = 208; + + public static final int SEND_MINIMAP_STATE = 99; + + public static final int SHOW_NPC_HEAD_ON_INTERFACE = 75; + + public static final int SEND_MULTIPLE_MAP_PACKETS = 60; + + public static final int SEND_EARTHQUAKE = 35; + + public static final int SEND_PLAYER_OPTION = 104; + + public static final int CLEAR_MINIMAP_FLAG = 78; + + public static final int SEND_MESSAGE = 253; + + public static final int STOP_ALL_ANIMATIONS = 1; + + public static final int ADD_SET_FRIEND = 50; + + public static final int SEND_RUN_ENERGY = 110; + + public static final int SEND_HINT_ICON = 254; + + public static final int SEND_DUO_INTERFACE = 248; + + public static final int SEND_RECEIVED_PRIVATE_MESSAGE = 196; + + public static final int SEND_REGION = 85; + + public static final int SEND_ITEM_TO_INTERFACE = 246; + + public static final int SHOW_HIDE_INTERFACE_CONTAINER = 171; + + public static final int SEND_SOLO_NON_WALKABLE_SIDEBAR_INTERFACE = 142; + + public static final int SET_INTERFACE_TEXT = 126; + + public static final int UPDATE_CHAT_MODES = 206; + + public static final int SEND_PLAYER_WEIGHT = 240; + + public static final int SEND_MODEL_TO_INTERFACE = 8; + + public static final int SEND_CHANGE_INTERFACE_COLOUR = 122; + + public static final int SEND_UPDATE_ITEMS = 53; + + public static final int SET_MODEL_INTERFACE_ZOOM = 230; + + public static final int SET_FRIENDSERVER_STATUS = 221; + + public static final int MOVE_CAMERA = 177; + + public static final int SEND_INITIALIZE_PACKET = 249; + + public static final int NPC_UPDATING = 65; + + public static final int SEND_ENTER_AMOUNT = 27; + + public static final int SEND_ENTER_NAME = 187; + + public static final int SEND_NON_WALKABLE_INTERFACE = 97; + + public static final int SEND_WALKABLE_CHATBOX_INTERFACE = 218; + + public static final int SEND_CONFIG_INT = 87; + + public static final int SEND_CONFIG_BYTE = 36; + + public static final int SEND_MULTICOMBAT_ICON = 61; + + public static final int SEND_ANIMATE_INTERFACE = 200; + + public static final int CLOSE_INTERFACE = 219; + + public static final int UPDATE_SPECIFIC_ITEM = 34; + + public static final int SWITCH_TAB = 106; + + public static final int SEND_NONWALKABLE_CHATBOX_INTERFACE = 164; + + public static final int SEND_MAP_REGION = 73; + + public static final int SEND_REGION_MAP_REGION = 241; + + public static final int MOUSE_CLICK = 241; + + public static final int SYSTEM_UPDATE = 114; + + public static final int PLAY_SOUND_EFFECT = 174; + + public static final int IDLE_LOGOUT = 202; + + public static final int ITEM_ON_NPC = 57; + + /** + * This array is interesting, it's never used and it has interesting properites. + * + * It's never used and has a lenght of 257. + * + * This is was used to map obfusticated packet opcodes with their actual opcodes. + * + * In 400+ they switched to using constants instead to make it more difficult. + */ + public static final int[] OBFUSTICATED_OPCODES = { + 6, 21, 25, 33, 254, 127, 183, 87, 216, 215, + 211, 48, 15, 195, 149, 233, 162, 102, 104, 179, + 222, 103, 224, 81, 152, 89, 45, 11, 197, 187, + 210, 37, 135, 220, 137, 128, 63, 188, 207, 144, + 201, 161, 28, 192, 206, 32, 115, 57, 196, 22, + 132, 226, 227, 169, 237, 105, 174, 109, 5, 55, + 205, 156, 8, 34, 113, 176, 209, 3, 50, 117, + 122, 189, 101, 142, 246, 163, 238, 76, 74, 84, + 91, 217, 58, 23, 118, 66, 35, 164, 114, 138, + 96, 110, 29, 235, 147, 249, 214, 198, 242, 56, + 94, 248, 59, 253, 150, 16, 13, 46, 24, 130, + 232, 153, 167, 229, 79, 134, 26, 191, 0, 213, + 204, 241, 160, 39, 180, 49, 250, 47, 140, 193, + 202, 108, 120, 247, 106, 194, 65, 27, 93, 143, + 186, 171, 125, 54, 155, 190, 139, 165, 77, 178, + 72, 99, 61, 141, 116, 100, 80, 184, 154, 145, + 131, 12, 90, 42, 255, 75, 44, 78, 172, 107, + 52, 7, 119, 146, 38, 218, 10, 223, 182, 240, + 159, 88, 158, 64, 221, 200, 1, 43, 252, 62, + 40, 230, 129, 18, 111, 51, 17, 53, 136, 20, + 60, 225, 30, 9, 239, 97, 234, 41, 203, 236, + 36, 185, 212, 19, 245, 251, 208, 175, 243, 86, + 2, 69, 181, 151, 14, 166, 70, 98, 124, 126, + 67, 157, 199, 112, 123, 177, 82, 168, 71, 170, + 95, 31, 92, 4, 231, 219, 73, 85, 244, 148, + 173, 228, 121, 83, 133, 68, 0 + }; + + public static final int[] PACKET_SIZES = { + 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10 + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, //20 + 0, 0, 0, 0, -2, 4, 3, 0, 0, 0, //30 + 0, 0, 0, 0, 5, 0, 0, 6, 0, 0, //40 + 9, 0, 0, -2, 0, 0, 0, 0, 0, 0, //50 + -2, 1, 0, 0, 2, -2, 0, 0, 0, 0, //60 + 6, 3, 2, 4, 2, 4, 0, 0, 0, 4, //70 + 0, -2, 0, 0, 7, 2, 0, 6, 0, 0, //80 + 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, //90 + 0, 2, 0, 0, -1, 4, 1, 0, 0, 0, //100 + 1, 0, 0, 0, 2, 0, 0, 15, 0, 0, //110 + 0, 4, 4, 0, 0, 0, -2, 0, 0, 0, //120 + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, //130 + 0, 0, 2, 0, 0, 0, 0, 14, 0, 0, //140 + 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, //150 + 4, 0, 0, 0, 2, 0, 6, 0, 0, 0, //160 + 0, 3, 0, 0, 5, 0, 10, 6, 0, 0, //170 + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, //180 + 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, //190 + 4, 0, 0, 0, 0, 0, 3, 0, 2, 0, //200 + 0, 0, 0, 0, -2, 7, 0, 0, 2, 0, //210 + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, //220 + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230 + 2, -2, 0, 0, 0, 0, 6, 0, 4, 3, //240 + 0, 0, 0, -1, 6, 0, 0//250 + }; + +} diff --git a/src/main/java/org/rebotted/util/SkillConstants.java b/src/main/java/org/rebotted/util/SkillConstants.java new file mode 100644 index 0000000..4852c1c --- /dev/null +++ b/src/main/java/org/rebotted/util/SkillConstants.java @@ -0,0 +1,17 @@ +package org.rebotted.util; + +public final class SkillConstants { + + public static final int SKILL_COUNT = 23; + + public static final String[] SKILL_NAMES = { "Attack", "Constitution", + "Mining", "Strength", "Agility", "Smithing", "Defence", "Herblore", + "Fishing", "Range", "Thieving", "Cooking", "Prayer", "Crafting", + "Firemaking", "Magic", "Fletching", "Woodcutting", "Runecrafting", + "Slayer", "Farming", "Construction", "-unused", "-unused" }; + + public static final boolean[] ENABLED_SKILLS = { true, true, true, true, + true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, false, false, false }; + +} diff --git a/src/main/java/org/rebotted/util/StringUtils.java b/src/main/java/org/rebotted/util/StringUtils.java new file mode 100644 index 0000000..1810042 --- /dev/null +++ b/src/main/java/org/rebotted/util/StringUtils.java @@ -0,0 +1,93 @@ +package org.rebotted.util; +import org.rebotted.sign.SignLink; + +public final class StringUtils { + + private static final char[] BASE_37_CHARACTERS = { '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + + public static long encodeBase37(String string) { + long encoded = 0L; + for (int index = 0; index < string.length() && index < 12; index++) { + char c = string.charAt(index); + encoded *= 37L; + if (c >= 'A' && c <= 'Z') + encoded += (1 + c) - 65; + else if (c >= 'a' && c <= 'z') + encoded += (1 + c) - 97; + else if (c >= '0' && c <= '9') + encoded += (27 + c) - 48; + } + + for (; encoded % 37L == 0L && encoded != 0L; encoded /= 37L) + ; + return encoded; + } + + public static String decodeBase37(long encoded) { + try { + if (encoded <= 0L || encoded >= 0x5b5b57f8a98a5dd1L) + return "invalid_name"; + if (encoded % 37L == 0L) + return "invalid_name"; + int length = 0; + char chars[] = new char[12]; + while (encoded != 0L) { + long l1 = encoded; + encoded /= 37L; + chars[11 - length++] = BASE_37_CHARACTERS[(int) (l1 - encoded * 37L)]; + } + return new String(chars, 12 - length, length); + } catch (RuntimeException runtimeexception) { + SignLink.reporterror("81570, " + encoded + ", " + (byte) -99 + ", " + runtimeexception.toString()); + } + throw new RuntimeException(); + } + + public static long hashSpriteName(String name) { + name = name.toUpperCase(); + long hash = 0L; + for (int index = 0; index < name.length(); index++) { + hash = (hash * 61L + (long) name.charAt(index)) - 32L; + hash = hash + (hash >> 56) & 0xffffffffffffffL; + } + return hash; + } + + /** + * Used to format a users ip address on the welcome screen. + */ + public static String decodeIp(int ip) { + return (ip >> 24 & 0xff) + "." + (ip >> 16 & 0xff) + "." + (ip >> 8 & 0xff) + "." + (ip & 0xff); + } + + /** + * Used to format a players name. + */ + public static String formatUsername(String name) { + if (name.length() > 0) { + char chars[] = name.toCharArray(); + for (int index = 0; index < chars.length; index++) + if (chars[index] == '_') { + chars[index] = ' '; + if (index + 1 < chars.length && chars[index + 1] >= 'a' && chars[index + 1] <= 'z') + chars[index + 1] = (char) ((chars[index + 1] + 65) - 97); + } + + if (chars[0] >= 'a' && chars[0] <= 'z') + chars[0] = (char) ((chars[0] + 65) - 97); + return new String(chars); + } else { + return name; + } + } + + /** + * Used for the login screen to hide a users password + */ + public static String passwordAsterisks(String password) { + StringBuffer stringbuffer = new StringBuffer(); + for (int index = 0; index < password.length(); index++) + stringbuffer.append("*"); + return stringbuffer.toString(); + } +} diff --git a/src/main/resources/rebotted.colorschemes b/src/main/resources/rebotted.colorschemes new file mode 100644 index 0000000..fc46a19 --- /dev/null +++ b/src/main/resources/rebotted.colorschemes @@ -0,0 +1,142 @@ +Rebotted Enabled { + kind=Dark + colorUltraLight=#3B3B3B + colorExtraLight=#363636 + colorLight=#303030 + colorMid=#2E2E2E + colorDark=#262626 + colorUltraDark=#212121 + colorForeground=#D7D7D7 +} + +Rebotted Border { + kind=Dark + colorUltraLight=#0F0F0F + colorExtraLight=#0F0F0F + colorLight=#0F0F0F + colorMid=#0F0F0F + colorDark=#0F0F0F + colorUltraDark=#0F0F0F + colorForeground=#FFFFFF +} + +Rebotted Background { + kind=Dark + colorUltraLight=#0F0F0F + colorExtraLight=#0F0F0F + colorLight=#0F0F0F + colorMid=#0F0F0F + colorDark=#0F0F0F + colorUltraDark=#0F0F0F + colorForeground=#D7D7D7 +} + +Rebotted Active { + kind=Dark + colorUltraLight=#242424 + colorExtraLight=#1F1F1F + colorLight=#1C1C1C + colorMid=#171717 + colorDark=#121212 + colorUltraDark=#0D0D0D + colorForeground=#D7D7D7 +} + +Rebotted Selected { + kind=Light + colorUltraLight=#575656 + colorExtraLight=#474646 + colorLight=#3D3C3C + colorMid=#363535 + colorDark=#303030 + colorUltraDark=#2B2B2B + colorForeground=#AFAFAF +} + +Rebotted Selected Disabled { + kind=Dark + colorUltraLight=#242424 + colorExtraLight=#1F1F1F + colorLight=#1C1C1C + colorMid=#171717 + colorDark=#121212 + colorUltraDark=#0D0D0D + colorForeground=#AFAFAF +} + +Rebotted Disabled { + kind=Dark + colorUltraLight=#242424 + colorExtraLight=#1F1F1F + colorLight=#1C1C1C + colorMid=#171717 + colorDark=#121212 + colorUltraDark=#0D0D0D + colorForeground=#999999 +} + +Rebotted Highlight { + kind=Dark + colorUltraLight=#242424 + colorExtraLight=#1F1F1F + colorLight=#1C1C1C + colorMid=#171717 + colorDark=#121212 + colorUltraDark=#0D0D0D + colorForeground=#323232 +} + +Rebotted Tab Highlight { + kind=Light + colorUltraLight=#575656 + colorExtraLight=#474646 + colorLight=#3D3C3C + colorMid=#363535 + colorDark=#303030 + colorUltraDark=#2B2B2B + colorForeground=#D7D7D7 +} + +Rebotted Highlight Mark { + kind=Light + colorUltraLight=#242424 + colorExtraLight=#1F1F1F + colorLight=#1C1C1C + colorMid=#171717 + colorDark=#121212 + colorUltraDark=#0D0D0D + colorForeground=#0DFF00 +} + +Rebotted Text Highlight { + kind=Light + colorUltraLight=#242424 + colorExtraLight=#1F1F1F + colorLight=#1C1C1C + colorMid=#171717 + colorDark=#121212 + colorUltraDark=#0D0D0D + colorForeground=#EDEDED +} + +Rebotted Separator { + kind=Light + colorUltraLight=#575656 + colorExtraLight=#474646 + colorLight=#3D3C3C + colorMid=#363535 + colorDark=#303030 + colorUltraDark=#2B2B2B + colorForeground=#0DFF00 +} + +Rebotted Dark { + kind=Light + colorUltraLight=#8A8A8A + colorExtraLight=#8A8A8A + colorLight=#8A8A8A + colorMid=#777777 + colorDark=#636363 + colorUltraDark=#4C4C4C + colorForeground=#323232 +} \ No newline at end of file