diff --git a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java index 2259026a4d..939fdf90da 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java +++ b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java @@ -12,45 +12,40 @@ public class ModelDefinition public int id; public int vertexCount = 0; - public int[] vertexPositionsX; - public int[] vertexPositionsY; - public int[] vertexPositionsZ; + public int[] vertexX; + public int[] vertexY; + public int[] vertexZ; public transient VertexNormal[] vertexNormals; public int faceCount; - public int[] faceVertexIndices1; - public int[] faceVertexIndices2; - public int[] faceVertexIndices3; - public byte[] faceAlphas; + public int[] faceIndices1; + public int[] faceIndices2; + public int[] faceIndices3; + public byte[] faceTransparencies; public short[] faceColors; public byte[] faceRenderPriorities; public byte[] faceRenderTypes; public transient FaceNormal[] faceNormals; - public int textureTriangleCount; - public short[] textureTriangleVertexIndices1; - public short[] textureTriangleVertexIndices2; - public short[] textureTriangleVertexIndices3; + public int numTextureFaces; + public short[] texIndices1; + public short[] texIndices2; + public short[] texIndices3; public transient float[][] faceTextureUCoordinates; public transient float[][] faceTextureVCoordinates; public short[] texturePrimaryColors; public short[] faceTextures; - public byte[] textureCoordinates; + public byte[] textureCoords; public byte[] textureRenderTypes; - public int[] vertexSkins; - public int[] faceSkins; + public int[] packedVertexGroups; + public int[] packedTransparencyVertexGroups; public byte priority; - public short[] aShortArray2574; - public short[] aShortArray2575; - public short[] aShortArray2577; - public short[] aShortArray2578; - public byte[] aByteArray2580; - public short[] aShortArray2586; - private transient int[][] vertexGroups; + public int[][] animayaGroups; + public int[][] animayaScales; private transient int[] origVX; private transient int[] origVY; @@ -77,17 +72,17 @@ public class ModelDefinition for (var1 = 0; var1 < this.faceCount; ++var1) { - int vertexA = this.faceVertexIndices1[var1]; - int vertexB = this.faceVertexIndices2[var1]; - int vertexC = this.faceVertexIndices3[var1]; + int vertexA = this.faceIndices1[var1]; + int vertexB = this.faceIndices2[var1]; + int vertexC = this.faceIndices3[var1]; - int xA = this.vertexPositionsX[vertexB] - this.vertexPositionsX[vertexA]; - int yA = this.vertexPositionsY[vertexB] - this.vertexPositionsY[vertexA]; - int zA = this.vertexPositionsZ[vertexB] - this.vertexPositionsZ[vertexA]; + int xA = this.vertexX[vertexB] - this.vertexX[vertexA]; + int yA = this.vertexY[vertexB] - this.vertexY[vertexA]; + int zA = this.vertexZ[vertexB] - this.vertexZ[vertexA]; - int xB = this.vertexPositionsX[vertexC] - this.vertexPositionsX[vertexA]; - int yB = this.vertexPositionsY[vertexC] - this.vertexPositionsY[vertexA]; - int zB = this.vertexPositionsZ[vertexC] - this.vertexPositionsZ[vertexA]; + int xB = this.vertexX[vertexC] - this.vertexX[vertexA]; + int yB = this.vertexY[vertexC] - this.vertexY[vertexA]; + int zB = this.vertexZ[vertexC] - this.vertexZ[vertexA]; // Compute cross product int var11 = yA * zB - yB * zA; @@ -168,13 +163,13 @@ public class ModelDefinition for (int i = 0; i < faceCount; i++) { int textureCoordinate; - if (textureCoordinates == null) + if (textureCoords == null) { textureCoordinate = -1; } else { - textureCoordinate = textureCoordinates[i]; + textureCoordinate = textureCoords[i]; } int textureIdx; @@ -215,33 +210,33 @@ public class ModelDefinition if (textureRenderType == 0) { - int faceVertexIdx1 = faceVertexIndices1[i]; - int faceVertexIdx2 = faceVertexIndices2[i]; - int faceVertexIdx3 = faceVertexIndices3[i]; + int faceVertexIdx1 = faceIndices1[i]; + int faceVertexIdx2 = faceIndices2[i]; + int faceVertexIdx3 = faceIndices3[i]; - short triangleVertexIdx1 = textureTriangleVertexIndices1[textureCoordinate]; - short triangleVertexIdx2 = textureTriangleVertexIndices2[textureCoordinate]; - short triangleVertexIdx3 = textureTriangleVertexIndices3[textureCoordinate]; + short triangleVertexIdx1 = texIndices1[textureCoordinate]; + short triangleVertexIdx2 = texIndices2[textureCoordinate]; + short triangleVertexIdx3 = texIndices3[textureCoordinate]; - float triangleX = (float) vertexPositionsX[triangleVertexIdx1]; - float triangleY = (float) vertexPositionsY[triangleVertexIdx1]; - float triangleZ = (float) vertexPositionsZ[triangleVertexIdx1]; + float triangleX = (float) vertexX[triangleVertexIdx1]; + float triangleY = (float) vertexY[triangleVertexIdx1]; + float triangleZ = (float) vertexZ[triangleVertexIdx1]; - float f_882_ = (float) vertexPositionsX[triangleVertexIdx2] - triangleX; - float f_883_ = (float) vertexPositionsY[triangleVertexIdx2] - triangleY; - float f_884_ = (float) vertexPositionsZ[triangleVertexIdx2] - triangleZ; - float f_885_ = (float) vertexPositionsX[triangleVertexIdx3] - triangleX; - float f_886_ = (float) vertexPositionsY[triangleVertexIdx3] - triangleY; - float f_887_ = (float) vertexPositionsZ[triangleVertexIdx3] - triangleZ; - float f_888_ = (float) vertexPositionsX[faceVertexIdx1] - triangleX; - float f_889_ = (float) vertexPositionsY[faceVertexIdx1] - triangleY; - float f_890_ = (float) vertexPositionsZ[faceVertexIdx1] - triangleZ; - float f_891_ = (float) vertexPositionsX[faceVertexIdx2] - triangleX; - float f_892_ = (float) vertexPositionsY[faceVertexIdx2] - triangleY; - float f_893_ = (float) vertexPositionsZ[faceVertexIdx2] - triangleZ; - float f_894_ = (float) vertexPositionsX[faceVertexIdx3] - triangleX; - float f_895_ = (float) vertexPositionsY[faceVertexIdx3] - triangleY; - float f_896_ = (float) vertexPositionsZ[faceVertexIdx3] - triangleZ; + float f_882_ = (float) vertexX[triangleVertexIdx2] - triangleX; + float f_883_ = (float) vertexY[triangleVertexIdx2] - triangleY; + float f_884_ = (float) vertexZ[triangleVertexIdx2] - triangleZ; + float f_885_ = (float) vertexX[triangleVertexIdx3] - triangleX; + float f_886_ = (float) vertexY[triangleVertexIdx3] - triangleY; + float f_887_ = (float) vertexZ[triangleVertexIdx3] - triangleZ; + float f_888_ = (float) vertexX[faceVertexIdx1] - triangleX; + float f_889_ = (float) vertexY[faceVertexIdx1] - triangleY; + float f_890_ = (float) vertexZ[faceVertexIdx1] - triangleZ; + float f_891_ = (float) vertexX[faceVertexIdx2] - triangleX; + float f_892_ = (float) vertexY[faceVertexIdx2] - triangleY; + float f_893_ = (float) vertexZ[faceVertexIdx2] - triangleZ; + float f_894_ = (float) vertexX[faceVertexIdx3] - triangleX; + float f_895_ = (float) vertexY[faceVertexIdx3] - triangleY; + float f_896_ = (float) vertexZ[faceVertexIdx3] - triangleZ; float f_897_ = f_883_ * f_887_ - f_884_ * f_886_; float f_898_ = f_884_ * f_885_ - f_882_ * f_887_; @@ -274,7 +269,7 @@ public class ModelDefinition public void computeAnimationTables() { - if (this.vertexSkins != null) + if (this.packedVertexGroups != null) { int[] groupCounts = new int[256]; int numGroups = 0; @@ -282,7 +277,7 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; ++var3) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; ++groupCounts[var4]; if (var4 > numGroups) { @@ -300,10 +295,10 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; this.vertexGroups[var4][groupCounts[var4]++] = var3++) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; } - this.vertexSkins = null; + this.packedVertexGroups = null; } // triangleSkinValues is here @@ -314,13 +309,13 @@ public class ModelDefinition int sin = CircularAngle.SINE[orientation]; int cos = CircularAngle.COSINE[orientation]; - assert vertexPositionsX.length == vertexPositionsY.length; - assert vertexPositionsY.length == vertexPositionsZ.length; + assert vertexX.length == vertexY.length; + assert vertexY.length == vertexZ.length; - for (int i = 0; i < vertexPositionsX.length; ++i) + for (int i = 0; i < vertexX.length; ++i) { - vertexPositionsX[i] = vertexPositionsX[i] * cos + vertexPositionsZ[i] * sin >> 16; - vertexPositionsZ[i] = vertexPositionsZ[i] * cos - vertexPositionsX[i] * sin >> 16; + vertexX[i] = vertexX[i] * cos + vertexZ[i] * sin >> 16; + vertexZ[i] = vertexZ[i] * cos - vertexX[i] * sin >> 16; } reset(); @@ -333,23 +328,23 @@ public class ModelDefinition return; } - System.arraycopy(origVX, 0, vertexPositionsX, 0, origVX.length); - System.arraycopy(origVY, 0, vertexPositionsY, 0, origVY.length); - System.arraycopy(origVZ, 0, vertexPositionsZ, 0, origVZ.length); + System.arraycopy(origVX, 0, vertexX, 0, origVX.length); + System.arraycopy(origVY, 0, vertexY, 0, origVY.length); + System.arraycopy(origVZ, 0, vertexZ, 0, origVZ.length); } public void animate(int type, int[] frameMap, int dx, int dy, int dz) { if (origVX == null) { - origVX = Arrays.copyOf(vertexPositionsX, vertexPositionsX.length); - origVY = Arrays.copyOf(vertexPositionsY, vertexPositionsY.length); - origVZ = Arrays.copyOf(vertexPositionsZ, vertexPositionsZ.length); + origVX = Arrays.copyOf(vertexX, vertexX.length); + origVY = Arrays.copyOf(vertexY, vertexY.length); + origVZ = Arrays.copyOf(vertexZ, vertexZ.length); } - final int[] verticesX = vertexPositionsX; - final int[] verticesY = vertexPositionsY; - final int[] verticesZ = vertexPositionsZ; + final int[] verticesX = vertexX; + final int[] verticesY = vertexY; + final int[] verticesZ = vertexZ; int var6 = frameMap.length; int var7; int var8; @@ -512,14 +507,14 @@ public class ModelDefinition int var1; for (var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } for (var1 = 0; var1 < this.faceCount; ++var1) { - int var2 = this.faceVertexIndices1[var1]; - this.faceVertexIndices1[var1] = this.faceVertexIndices3[var1]; - this.faceVertexIndices3[var1] = var2; + int var2 = this.faceIndices1[var1]; + this.faceIndices1[var1] = this.faceIndices3[var1]; + this.faceIndices3[var1] = var2; } reset(); @@ -529,9 +524,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = -var2; + int var2 = this.vertexX[var1]; + this.vertexX[var1] = this.vertexZ[var1]; + this.vertexZ[var1] = -var2; } reset(); @@ -541,8 +536,8 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsX[var1] = -this.vertexPositionsX[var1]; - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexX[var1] = -this.vertexX[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } reset(); @@ -552,9 +547,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = -var2; + int var2 = this.vertexZ[var1]; + this.vertexZ[var1] = this.vertexX[var1]; + this.vertexX[var1] = -var2; } reset(); @@ -571,9 +566,9 @@ public class ModelDefinition { for (int var4 = 0; var4 < this.vertexCount; ++var4) { - this.vertexPositionsX[var4] = this.vertexPositionsX[var4] * var1 / 128; - this.vertexPositionsY[var4] = var2 * this.vertexPositionsY[var4] / 128; - this.vertexPositionsZ[var4] = var3 * this.vertexPositionsZ[var4] / 128; + this.vertexX[var4] = this.vertexX[var4] * var1 / 128; + this.vertexY[var4] = var2 * this.vertexY[var4] / 128; + this.vertexZ[var4] = var3 * this.vertexZ[var4] / 128; } reset(); @@ -610,9 +605,9 @@ public class ModelDefinition { for (int i = 0; i < this.vertexCount; i++) { - this.vertexPositionsX[i] += xOffset; - this.vertexPositionsY[i] += yOffset; - this.vertexPositionsZ[i] += zOffset; + this.vertexX[i] += xOffset; + this.vertexY[i] += yOffset; + this.vertexZ[i] += zOffset; } this.reset(); } diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java index 4529f8a069..22226c3d8a 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java @@ -10,13 +10,21 @@ public class ModelLoader ModelDefinition def = new ModelDefinition(); def.id = modelId; - if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + if (b[b.length - 1] == -3 && b[b.length - 2] == -1) { - this.load1(def, b); + decodeType3(def, b); + } + else if (b[b.length - 1] == -2 && b[b.length - 2] == -1) + { + decodeType2(def, b); + } + else if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + { + decodeType1(def, b); } else { - this.load2(def, b); + decodeOldFormat(def, b); } def.computeNormals(); @@ -26,702 +34,1356 @@ public class ModelLoader return def; } - private void load1(ModelDefinition model, byte[] var1) + void decodeType3(ModelDefinition def, byte[] var1) { InputStream var2 = new InputStream(var1); - InputStream var24 = new InputStream(var1); InputStream var3 = new InputStream(var1); - InputStream var28 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); InputStream var6 = new InputStream(var1); - InputStream var55 = new InputStream(var1); - InputStream var51 = new InputStream(var1); - var2.setOffset(var1.length - 23); - int verticeCount = var2.readUnsignedShort(); - int triangleCount = var2.readUnsignedShort(); - int textureTriangleCount = var2.readUnsignedByte(); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 26); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); int var13 = var2.readUnsignedByte(); - int modelPriority = var2.readUnsignedByte(); - int var50 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); int var17 = var2.readUnsignedByte(); - int modelTexture = var2.readUnsignedByte(); - int modelVertexSkins = var2.readUnsignedByte(); + int var18 = var2.readUnsignedByte(); + int var19 = var2.readUnsignedShort(); int var20 = var2.readUnsignedShort(); int var21 = var2.readUnsignedShort(); - int var42 = var2.readUnsignedShort(); int var22 = var2.readUnsignedShort(); - int var38 = var2.readUnsignedShort(); - int textureAmount = 0; - int var7 = 0; - int var29 = 0; - int position; - if (textureTriangleCount > 0) + int var23 = var2.readUnsignedShort(); + int var24 = var2.readUnsignedShort(); + int var25 = 0; + int var26 = 0; + int var27 = 0; + int var28; + if (var11 > 0) { - model.textureRenderTypes = new byte[textureTriangleCount]; + def.textureRenderTypes = new byte[var11]; var2.setOffset(0); - for (position = 0; position < textureTriangleCount; ++position) + for (var28 = 0; var28 < var11; ++var28) { - byte renderType = model.textureRenderTypes[position] = var2.readByte(); - if (renderType == 0) + byte var29 = def.textureRenderTypes[var28] = var2.readByte(); + if (var29 == 0) { - ++textureAmount; + ++var25; } - if (renderType >= 1 && renderType <= 3) + if (var29 >= 1 && var29 <= 3) { - ++var7; + ++var26; } - if (renderType == 2) + if (var29 == 2) { - ++var29; + ++var27; } } } - position = textureTriangleCount + verticeCount; - int renderTypePos = position; - if (var13 == 1) + var28 = var11 + var9; + int var58 = var28; + if (var12 == 1) { - position += triangleCount; + var28 += var10; } - int var49 = position; - position += triangleCount; - int priorityPos = position; - if (modelPriority == 255) + int var30 = var28; + var28 += var10; + int var31 = var28; + if (var13 == 255) { - position += triangleCount; + var28 += var10; } - int triangleSkinPos = position; + int var32 = var28; + if (var15 == 1) + { + var28 += var10; + } + + int var33 = var28; + var28 += var24; + int var34 = var28; + if (var14 == 1) + { + var28 += var10; + } + + int var35 = var28; + var28 += var22; + int var36 = var28; + if (var16 == 1) + { + var28 += var10 * 2; + } + + int var37 = var28; + var28 += var23; + int var38 = var28; + var28 += var10 * 2; + int var39 = var28; + var28 += var19; + int var40 = var28; + var28 += var20; + int var41 = var28; + var28 += var21; + int var42 = var28; + var28 += var25 * 6; + int var43 = var28; + var28 += var26 * 6; + int var44 = var28; + var28 += var26 * 6; + int var45 = var28; + var28 += var26 * 2; + int var46 = var28; + var28 += var26; + int var47 = var28; + var28 = var28 + var26 * 2 + var27 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; if (var17 == 1) { - position += triangleCount; + def.packedVertexGroups = new int[var9]; } - int var35 = position; - if (modelVertexSkins == 1) + if (var12 == 1) { - position += verticeCount; + def.faceRenderTypes = new byte[var10]; } - int alphaPos = position; - if (var50 == 1) + if (var13 == 255) { - position += triangleCount; - } - - int var11 = position; - position += var22; - int texturePos = position; - if (modelTexture == 1) - { - position += triangleCount * 2; - } - - int textureCoordPos = position; - position += var38; - int colorPos = position; - position += triangleCount * 2; - int var40 = position; - position += var20; - int var41 = position; - position += var21; - int var8 = position; - position += var42; - int var43 = position; - position += textureAmount * 6; - int var37 = position; - position += var7 * 6; - int var48 = position; - position += var7 * 6; - int var56 = position; - position += var7 * 2; - int var45 = position; - position += var7; - int var46 = position; - position += var7 * 2 + var29 * 2; - model.vertexCount = verticeCount; - model.faceCount = triangleCount; - model.textureTriangleCount = textureTriangleCount; - model.vertexPositionsX = new int[verticeCount]; - model.vertexPositionsY = new int[verticeCount]; - model.vertexPositionsZ = new int[verticeCount]; - model.faceVertexIndices1 = new int[triangleCount]; - model.faceVertexIndices2 = new int[triangleCount]; - model.faceVertexIndices3 = new int[triangleCount]; - if (modelVertexSkins == 1) - { - model.vertexSkins = new int[verticeCount]; - } - - if (var13 == 1) - { - model.faceRenderTypes = new byte[triangleCount]; - } - - if (modelPriority == 255) - { - model.faceRenderPriorities = new byte[triangleCount]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) modelPriority; + def.priority = (byte) var13; } - if (var50 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[triangleCount]; + def.faceTransparencies = new byte[var10]; } - if (var17 == 1) + if (var15 == 1) { - model.faceSkins = new int[triangleCount]; + def.packedTransparencyVertexGroups = new int[var10]; } - if (modelTexture == 1) + if (var16 == 1) { - model.faceTextures = new short[triangleCount]; + def.faceTextures = new short[var10]; } - if (modelTexture == 1 && textureTriangleCount > 0) + if (var16 == 1 && var11 > 0) { - model.textureCoordinates = new byte[triangleCount]; + def.textureCoords = new byte[var10]; } - model.faceColors = new short[triangleCount]; - if (textureTriangleCount > 0) + if (var18 == 1) { - model.textureTriangleVertexIndices1 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices2 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices3 = new short[textureTriangleCount]; - if (var7 > 0) - { - model.aShortArray2574 = new short[var7]; - model.aShortArray2575 = new short[var7]; - model.aShortArray2586 = new short[var7]; - model.aShortArray2577 = new short[var7]; - model.aByteArray2580 = new byte[var7]; - model.aShortArray2578 = new short[var7]; - } - - if (var29 > 0) - { - model.texturePrimaryColors = new short[var29]; - } + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; } - var2.setOffset(textureTriangleCount); - var24.setOffset(var40); - var3.setOffset(var41); - var28.setOffset(var8); - var6.setOffset(var35); - int vX = 0; - int vY = 0; - int vZ = 0; - - int vertexZOffset; - int var10; - int vertexYOffset; - int var15; - int point; - for (point = 0; point < verticeCount; ++point) + def.faceColors = new short[var10]; + if (var11 > 0) { - int vertexFlags = var2.readUnsignedByte(); - int vertexXOffset = 0; - if ((vertexFlags & 1) != 0) - { - vertexXOffset = var24.readShortSmart(); - } - - vertexYOffset = 0; - if ((vertexFlags & 2) != 0) - { - vertexYOffset = var3.readShortSmart(); - } - - vertexZOffset = 0; - if ((vertexFlags & 4) != 0) - { - vertexZOffset = var28.readShortSmart(); - } - - model.vertexPositionsX[point] = vX + vertexXOffset; - model.vertexPositionsY[point] = vY + vertexYOffset; - model.vertexPositionsZ[point] = vZ + vertexZOffset; - vX = model.vertexPositionsX[point]; - vY = model.vertexPositionsY[point]; - vZ = model.vertexPositionsZ[point]; - if (modelVertexSkins == 1) - { - model.vertexSkins[point] = var6.readUnsignedByte(); - } - } - - var2.setOffset(colorPos); - var24.setOffset(renderTypePos); - var3.setOffset(priorityPos); - var28.setOffset(alphaPos); - var6.setOffset(triangleSkinPos); - var55.setOffset(texturePos); - var51.setOffset(textureCoordPos); - - for (point = 0; point < triangleCount; ++point) - { - model.faceColors[point] = (short) var2.readUnsignedShort(); - if (var13 == 1) - { - model.faceRenderTypes[point] = var24.readByte(); - } - - if (modelPriority == 255) - { - model.faceRenderPriorities[point] = var3.readByte(); - } - - if (var50 == 1) - { - model.faceAlphas[point] = var28.readByte(); - } - - if (var17 == 1) - { - model.faceSkins[point] = var6.readUnsignedByte(); - } - - if (modelTexture == 1) - { - model.faceTextures[point] = (short) (var55.readUnsignedShort() - 1); - } - - if (model.textureCoordinates != null && model.faceTextures[point] != -1) - { - model.textureCoordinates[point] = (byte) (var51.readUnsignedByte() - 1); - } + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } var2.setOffset(var11); - var24.setOffset(var49); - int trianglePointX = 0; - int trianglePointY = 0; - int trianglePointZ = 0; - vertexYOffset = 0; + var3.setOffset(var39); + var4.setOffset(var40); + var5.setOffset(var41); + var6.setOffset(var33); + int var48 = 0; + int var49 = 0; + int var50 = 0; - int var16; - for (vertexZOffset = 0; vertexZOffset < triangleCount; ++vertexZOffset) + int var51; + int var52; + int var53; + int var54; + int var55; + for (var51 = 0; var51 < var9; ++var51) { - int numFaces = var24.readUnsignedByte(); - if (numFaces == 1) + var52 = var2.readUnsignedByte(); + var53 = 0; + if ((var52 & 1) != 0) { - trianglePointX = var2.readShortSmart() + vertexYOffset; - trianglePointY = var2.readShortSmart() + trianglePointX; - trianglePointZ = var2.readShortSmart() + trianglePointY; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var53 = var3.readShortSmart(); } - if (numFaces == 2) + var54 = 0; + if ((var52 & 2) != 0) { - trianglePointY = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var54 = var4.readShortSmart(); } - if (numFaces == 3) + var55 = 0; + if ((var52 & 4) != 0) { - trianglePointX = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var55 = var5.readShortSmart(); } - if (numFaces == 4) + def.vertexX[var51] = var48 + var53; + def.vertexY[var51] = var49 + var54; + def.vertexZ[var51] = var50 + var55; + var48 = def.vertexX[var51]; + var49 = def.vertexY[var51]; + var50 = def.vertexZ[var51]; + if (var17 == 1) { - int var57 = trianglePointX; - trianglePointX = trianglePointY; - trianglePointY = var57; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = var57; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + def.packedVertexGroups[var51] = var6.readUnsignedByte(); } } - var2.setOffset(var43); - var24.setOffset(var37); - var3.setOffset(var48); - var28.setOffset(var56); - var6.setOffset(var45); - var55.setOffset(var46); - - for (int texIndex = 0; texIndex < textureTriangleCount; ++texIndex) + if (var18 == 1) { - int type = model.textureRenderTypes[texIndex] & 255; - if (type == 0) + for (var51 = 0; var51 < var9; ++var51) { - model.textureTriangleVertexIndices1[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var2.readUnsignedShort(); - } + var52 = var6.readUnsignedByte(); + def.animayaGroups[var51] = new int[var52]; + def.animayaScales[var51] = new int[var52]; - if (type == 1) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 2) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - model.texturePrimaryColors[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 3) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); + for (var53 = 0; var53 < var52; ++var53) + { + def.animayaGroups[var51][var53] = var6.readUnsignedByte(); + def.animayaScales[var51][var53] = var6.readUnsignedByte(); + } } } - var2.setOffset(position); - vertexZOffset = var2.readUnsignedByte(); - if (vertexZOffset != 0) + var2.setOffset(var38); + var3.setOffset(var58); + var4.setOffset(var31); + var5.setOffset(var34); + var6.setOffset(var32); + var7.setOffset(var36); + var8.setOffset(var37); + + for (var51 = 0; var51 < var10; ++var51) + { + def.faceColors[var51] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var51] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var51] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var51] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var51] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var51] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var51] != -1) + { + def.textureCoords[var51] = (byte) (var8.readUnsignedByte() - 1); + } + } + + var2.setOffset(var35); + var3.setOffset(var30); + var51 = 0; + var52 = 0; + var53 = 0; + var54 = 0; + + int var56; + for (var55 = 0; var55 < var10; ++var55) + { + var56 = var3.readUnsignedByte(); + if (var56 == 1) + { + var51 = var2.readShortSmart() + var54; + var52 = var2.readShortSmart() + var51; + var53 = var2.readShortSmart() + var52; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 2) + { + var52 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 3) + { + var51 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 4) + { + int var57 = var51; + var51 = var52; + var52 = var57; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var57; + def.faceIndices3[var55] = var53; + } + } + + var2.setOffset(var42); + var3.setOffset(var43); + var4.setOffset(var44); + var5.setOffset(var45); + var6.setOffset(var46); + var7.setOffset(var47); + + for (var55 = 0; var55 < var11; ++var55) + { + var56 = def.textureRenderTypes[var55] & 255; + if (var56 == 0) + { + def.texIndices1[var55] = (short) var2.readUnsignedShort(); + def.texIndices2[var55] = (short) var2.readUnsignedShort(); + def.texIndices3[var55] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var28); + var55 = var2.readUnsignedByte(); + if (var55 != 0) { - //new Class41(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readInt(); } + } - private void load2(ModelDefinition model, byte[] var1) + void decodeType2(ModelDefinition def, byte[] var1) { boolean var2 = false; - boolean var43 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); InputStream var5 = new InputStream(var1); - InputStream var39 = new InputStream(var1); - InputStream var26 = new InputStream(var1); - InputStream var9 = new InputStream(var1); - InputStream var3 = new InputStream(var1); - var5.setOffset(var1.length - 18); - int var10 = var5.readUnsignedShort(); - int var11 = var5.readUnsignedShort(); - int var12 = var5.readUnsignedByte(); - int var13 = var5.readUnsignedByte(); - int var14 = var5.readUnsignedByte(); - int var30 = var5.readUnsignedByte(); - int var15 = var5.readUnsignedByte(); - int var28 = var5.readUnsignedByte(); - int var27 = var5.readUnsignedShort(); - int var20 = var5.readUnsignedShort(); - int var36 = var5.readUnsignedShort(); - int var23 = var5.readUnsignedShort(); - byte var16 = 0; - int var46 = var16 + var10; - int var24 = var46; - var46 += var11; - int var25 = var46; - if (var14 == 255) + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 23); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedByte(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + int var21 = var4.readUnsignedShort(); + int var22 = var4.readUnsignedShort(); + byte var23 = 0; + int var24 = var23 + var9; + int var25 = var24; + var24 += var10; + int var26 = var24; + if (var13 == 255) { - var46 += var11; + var24 += var10; } - int var4 = var46; + int var27 = var24; if (var15 == 1) { - var46 += var11; + var24 += var10; } - int var42 = var46; - if (var13 == 1) + int var28 = var24; + if (var12 == 1) { - var46 += var11; + var24 += var10; } - int var37 = var46; - if (var28 == 1) + int var29 = var24; + var24 += var22; + int var30 = var24; + if (var14 == 1) { - var46 += var10; + var24 += var10; } - int var29 = var46; - if (var30 == 1) + int var31 = var24; + var24 += var21; + int var32 = var24; + var24 += var10 * 2; + int var33 = var24; + var24 += var11 * 6; + int var34 = var24; + var24 += var18; + int var35 = var24; + var24 += var19; + int var10000 = var24 + var20; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) { - var46 += var11; + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } - int var44 = var46; - var46 += var23; - int var17 = var46; - var46 += var11 * 2; - int var32 = var46; - var46 += var12 * 6; - int var34 = var46; - var46 += var27; - int var35 = var46; - var46 += var20; - int var10000 = var46 + var36; - model.vertexCount = var10; - model.faceCount = var11; - model.textureTriangleCount = var12; - model.vertexPositionsX = new int[var10]; - model.vertexPositionsY = new int[var10]; - model.vertexPositionsZ = new int[var10]; - model.faceVertexIndices1 = new int[var11]; - model.faceVertexIndices2 = new int[var11]; - model.faceVertexIndices3 = new int[var11]; - if (var12 > 0) + if (var16 == 1) { - model.textureRenderTypes = new byte[var12]; - model.textureTriangleVertexIndices1 = new short[var12]; - model.textureTriangleVertexIndices2 = new short[var12]; - model.textureTriangleVertexIndices3 = new short[var12]; + def.packedVertexGroups = new int[var9]; } - if (var28 == 1) + if (var12 == 1) { - model.vertexSkins = new int[var10]; + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; } - if (var13 == 1) + if (var13 == 255) { - model.faceRenderTypes = new byte[var11]; - model.textureCoordinates = new byte[var11]; - model.faceTextures = new short[var11]; - } - - if (var14 == 255) - { - model.faceRenderPriorities = new byte[var11]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) var14; + def.priority = (byte) var13; } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[var11]; + def.faceTransparencies = new byte[var10]; } if (var15 == 1) { - model.faceSkins = new int[var11]; + def.packedTransparencyVertexGroups = new int[var10]; } - model.faceColors = new short[var11]; - var5.setOffset(var16); - var39.setOffset(var34); - var26.setOffset(var35); - var9.setOffset(var46); - var3.setOffset(var37); - int var41 = 0; - int var33 = 0; - int var19 = 0; - - int var6; - int var7; - int var8; - int var18; - int var31; - for (var18 = 0; var18 < var10; ++var18) + if (var17 == 1) { - var8 = var5.readUnsignedByte(); - var31 = 0; - if ((var8 & 1) != 0) + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var23); + var5.setOffset(var34); + var6.setOffset(var35); + var7.setOffset(var24); + var8.setOffset(var29); + int var37 = 0; + int var38 = 0; + int var39 = 0; + + int var40; + int var41; + int var42; + int var43; + int var44; + for (var40 = 0; var40 < var9; ++var40) + { + var41 = var4.readUnsignedByte(); + var42 = 0; + if ((var41 & 1) != 0) { - var31 = var39.readShortSmart(); + var42 = var5.readShortSmart(); } - var6 = 0; - if ((var8 & 2) != 0) + var43 = 0; + if ((var41 & 2) != 0) { - var6 = var26.readShortSmart(); + var43 = var6.readShortSmart(); } - var7 = 0; - if ((var8 & 4) != 0) + var44 = 0; + if ((var41 & 4) != 0) { - var7 = var9.readShortSmart(); + var44 = var7.readShortSmart(); } - model.vertexPositionsX[var18] = var41 + var31; - model.vertexPositionsY[var18] = var33 + var6; - model.vertexPositionsZ[var18] = var19 + var7; - var41 = model.vertexPositionsX[var18]; - var33 = model.vertexPositionsY[var18]; - var19 = model.vertexPositionsZ[var18]; - if (var28 == 1) + def.vertexX[var40] = var37 + var42; + def.vertexY[var40] = var38 + var43; + def.vertexZ[var40] = var39 + var44; + var37 = def.vertexX[var40]; + var38 = def.vertexY[var40]; + var39 = def.vertexZ[var40]; + if (var16 == 1) { - model.vertexSkins[var18] = var3.readUnsignedByte(); + def.packedVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var17); - var39.setOffset(var42); - var26.setOffset(var25); - var9.setOffset(var29); - var3.setOffset(var4); - - for (var18 = 0; var18 < var11; ++var18) + if (var17 == 1) { - model.faceColors[var18] = (short) var5.readUnsignedShort(); - if (var13 == 1) + for (var40 = 0; var40 < var9; ++var40) { - var8 = var39.readUnsignedByte(); - if ((var8 & 1) == 1) + var41 = var8.readUnsignedByte(); + def.animayaGroups[var40] = new int[var41]; + def.animayaScales[var40] = new int[var41]; + + for (var42 = 0; var42 < var41; ++var42) { - model.faceRenderTypes[var18] = 1; + def.animayaGroups[var40][var42] = var8.readUnsignedByte(); + def.animayaScales[var40][var42] = var8.readUnsignedByte(); + } + } + } + + var4.setOffset(var32); + var5.setOffset(var28); + var6.setOffset(var26); + var7.setOffset(var30); + var8.setOffset(var27); + + for (var40 = 0; var40 < var10; ++var40) + { + def.faceColors[var40] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var41 = var5.readUnsignedByte(); + if ((var41 & 1) == 1) + { + def.faceRenderTypes[var40] = 1; var2 = true; } else { - model.faceRenderTypes[var18] = 0; + def.faceRenderTypes[var40] = 0; } - if ((var8 & 2) == 2) + if ((var41 & 2) == 2) { - model.textureCoordinates[var18] = (byte) (var8 >> 2); - model.faceTextures[var18] = model.faceColors[var18]; - model.faceColors[var18] = 127; - if (model.faceTextures[var18] != -1) + def.textureCoords[var40] = (byte) (var41 >> 2); + def.faceTextures[var40] = def.faceColors[var40]; + def.faceColors[var40] = 127; + if (def.faceTextures[var40] != -1) { - var43 = true; + var3 = true; } } else { - model.textureCoordinates[var18] = -1; - model.faceTextures[var18] = -1; + def.textureCoords[var40] = -1; + def.faceTextures[var40] = -1; } } - if (var14 == 255) + if (var13 == 255) { - model.faceRenderPriorities[var18] = var26.readByte(); + def.faceRenderPriorities[var40] = var6.readByte(); } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas[var18] = var9.readByte(); + def.faceTransparencies[var40] = var7.readByte(); } if (var15 == 1) { - model.faceSkins[var18] = var3.readUnsignedByte(); + def.packedTransparencyVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var44); - var39.setOffset(var24); - var18 = 0; - var8 = 0; - var31 = 0; - var6 = 0; + var4.setOffset(var31); + var5.setOffset(var25); + var40 = 0; + var41 = 0; + var42 = 0; + var43 = 0; - int var21; - int var22; - for (var7 = 0; var7 < var11; ++var7) + int var45; + int var46; + for (var44 = 0; var44 < var10; ++var44) { - var22 = var39.readUnsignedByte(); - if (var22 == 1) + var45 = var5.readUnsignedByte(); + if (var45 == 1) { - var18 = var5.readShortSmart() + var6; - var8 = var5.readShortSmart() + var18; - var31 = var5.readShortSmart() + var8; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var4.readShortSmart() + var43; + var41 = var4.readShortSmart() + var40; + var42 = var4.readShortSmart() + var41; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 2) + if (var45 == 2) { - var8 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var41 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 3) + if (var45 == 3) { - var18 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 4) + if (var45 == 4) { - var21 = var18; - var18 = var8; - var8 = var21; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var21; - model.faceVertexIndices3[var7] = var31; + var46 = var40; + var40 = var41; + var41 = var46; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var46; + def.faceIndices3[var44] = var42; } } + var4.setOffset(var33); + + for (var44 = 0; var44 < var11; ++var44) + { + def.textureRenderTypes[var44] = 0; + def.texIndices1[var44] = (short) var4.readUnsignedShort(); + def.texIndices2[var44] = (short) var4.readUnsignedShort(); + def.texIndices3[var44] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) + { + boolean var47 = false; + + for (var45 = 0; var45 < var10; ++var45) + { + var46 = def.textureCoords[var45] & 255; + if (var46 != 255) + { + if (def.faceIndices1[var45] == (def.texIndices1[var46] & '\uffff') && def.faceIndices2[var45] == (def.texIndices2[var46] & '\uffff') && def.faceIndices3[var45] == (def.texIndices3[var46] & '\uffff')) + { + def.textureCoords[var45] = -1; + } + else + { + var47 = true; + } + } + } + + if (!var47) + { + def.textureCoords = null; + } + } + + if (!var3) + { + def.faceTextures = null; + } + + if (!var2) + { + def.faceRenderTypes = null; + } + + } + + void decodeType1(ModelDefinition def, byte[] var1) + { + InputStream var2 = new InputStream(var1); + InputStream var3 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 23); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); + int var13 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); + int var17 = var2.readUnsignedByte(); + int var18 = var2.readUnsignedShort(); + int var19 = var2.readUnsignedShort(); + int var20 = var2.readUnsignedShort(); + int var21 = var2.readUnsignedShort(); + int var22 = var2.readUnsignedShort(); + int var23 = 0; + int var24 = 0; + int var25 = 0; + int var26; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + var2.setOffset(0); + + for (var26 = 0; var26 < var11; ++var26) + { + byte var27 = def.textureRenderTypes[var26] = var2.readByte(); + if (var27 == 0) + { + ++var23; + } + + if (var27 >= 1 && var27 <= 3) + { + ++var24; + } + + if (var27 == 2) + { + ++var25; + } + } + } + + var26 = var11 + var9; + int var56 = var26; + if (var12 == 1) + { + var26 += var10; + } + + int var28 = var26; + var26 += var10; + int var29 = var26; + if (var13 == 255) + { + var26 += var10; + } + + int var30 = var26; + if (var15 == 1) + { + var26 += var10; + } + + int var31 = var26; + if (var17 == 1) + { + var26 += var9; + } + + int var32 = var26; + if (var14 == 1) + { + var26 += var10; + } + + int var33 = var26; + var26 += var21; + int var34 = var26; + if (var16 == 1) + { + var26 += var10 * 2; + } + + int var35 = var26; + var26 += var22; + int var36 = var26; + var26 += var10 * 2; + int var37 = var26; + var26 += var18; + int var38 = var26; + var26 += var19; + int var39 = var26; + var26 += var20; + int var40 = var26; + var26 += var23 * 6; + int var41 = var26; + var26 += var24 * 6; + int var42 = var26; + var26 += var24 * 6; + int var43 = var26; + var26 += var24 * 2; + int var44 = var26; + var26 += var24; + int var45 = var26; + var26 = var26 + var24 * 2 + var25 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var17 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + if (var16 == 1) + { + def.faceTextures = new short[var10]; + } + + if (var16 == 1 && var11 > 0) + { + def.textureCoords = new byte[var10]; + } + + def.faceColors = new short[var10]; + if (var11 > 0) + { + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + var2.setOffset(var11); + var3.setOffset(var37); + var4.setOffset(var38); + var5.setOffset(var39); + var6.setOffset(var31); + int var46 = 0; + int var47 = 0; + int var48 = 0; + + int var49; + int var50; + int var51; + int var52; + int var53; + for (var49 = 0; var49 < var9; ++var49) + { + var50 = var2.readUnsignedByte(); + var51 = 0; + if ((var50 & 1) != 0) + { + var51 = var3.readShortSmart(); + } + + var52 = 0; + if ((var50 & 2) != 0) + { + var52 = var4.readShortSmart(); + } + + var53 = 0; + if ((var50 & 4) != 0) + { + var53 = var5.readShortSmart(); + } + + def.vertexX[var49] = var46 + var51; + def.vertexY[var49] = var47 + var52; + def.vertexZ[var49] = var48 + var53; + var46 = def.vertexX[var49]; + var47 = def.vertexY[var49]; + var48 = def.vertexZ[var49]; + if (var17 == 1) + { + def.packedVertexGroups[var49] = var6.readUnsignedByte(); + } + } + + var2.setOffset(var36); + var3.setOffset(var56); + var4.setOffset(var29); var5.setOffset(var32); + var6.setOffset(var30); + var7.setOffset(var34); + var8.setOffset(var35); - for (var7 = 0; var7 < var12; ++var7) + for (var49 = 0; var49 < var10; ++var49) { - model.textureRenderTypes[var7] = 0; - model.textureTriangleVertexIndices1[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices2[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices3[var7] = (short) var5.readUnsignedShort(); + def.faceColors[var49] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var49] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var49] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var49] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var49] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var49] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var49] != -1) + { + def.textureCoords[var49] = (byte) (var8.readUnsignedByte() - 1); + } } - if (model.textureCoordinates != null) + var2.setOffset(var33); + var3.setOffset(var28); + var49 = 0; + var50 = 0; + var51 = 0; + var52 = 0; + + int var54; + for (var53 = 0; var53 < var10; ++var53) + { + var54 = var3.readUnsignedByte(); + if (var54 == 1) + { + var49 = var2.readShortSmart() + var52; + var50 = var2.readShortSmart() + var49; + var51 = var2.readShortSmart() + var50; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 2) + { + var50 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 3) + { + var49 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 4) + { + int var55 = var49; + var49 = var50; + var50 = var55; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var55; + def.faceIndices3[var53] = var51; + } + } + + var2.setOffset(var40); + var3.setOffset(var41); + var4.setOffset(var42); + var5.setOffset(var43); + var6.setOffset(var44); + var7.setOffset(var45); + + for (var53 = 0; var53 < var11; ++var53) + { + var54 = def.textureRenderTypes[var53] & 255; + if (var54 == 0) + { + def.texIndices1[var53] = (short) var2.readUnsignedShort(); + def.texIndices2[var53] = (short) var2.readUnsignedShort(); + def.texIndices3[var53] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var26); + var53 = var2.readUnsignedByte(); + if (var53 != 0) + { + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readInt(); + } + + } + + void decodeOldFormat(ModelDefinition def, byte[] var1) + { + boolean var2 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 18); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedShort(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + byte var21 = 0; + int var22 = var21 + var9; + int var23 = var22; + var22 += var10; + int var24 = var22; + if (var13 == 255) + { + var22 += var10; + } + + int var25 = var22; + if (var15 == 1) + { + var22 += var10; + } + + int var26 = var22; + if (var12 == 1) + { + var22 += var10; + } + + int var27 = var22; + if (var16 == 1) + { + var22 += var9; + } + + int var28 = var22; + if (var14 == 1) + { + var22 += var10; + } + + int var29 = var22; + var22 += var20; + int var30 = var22; + var22 += var10 * 2; + int var31 = var22; + var22 += var11 * 6; + int var32 = var22; + var22 += var17; + int var33 = var22; + var22 += var18; + int var10000 = var22 + var19; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + if (var16 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var21); + var5.setOffset(var32); + var6.setOffset(var33); + var7.setOffset(var22); + var8.setOffset(var27); + int var35 = 0; + int var36 = 0; + int var37 = 0; + + int var38; + int var39; + int var40; + int var41; + int var42; + for (var38 = 0; var38 < var9; ++var38) + { + var39 = var4.readUnsignedByte(); + var40 = 0; + if ((var39 & 1) != 0) + { + var40 = var5.readShortSmart(); + } + + var41 = 0; + if ((var39 & 2) != 0) + { + var41 = var6.readShortSmart(); + } + + var42 = 0; + if ((var39 & 4) != 0) + { + var42 = var7.readShortSmart(); + } + + def.vertexX[var38] = var35 + var40; + def.vertexY[var38] = var36 + var41; + def.vertexZ[var38] = var37 + var42; + var35 = def.vertexX[var38]; + var36 = def.vertexY[var38]; + var37 = def.vertexZ[var38]; + if (var16 == 1) + { + def.packedVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var30); + var5.setOffset(var26); + var6.setOffset(var24); + var7.setOffset(var28); + var8.setOffset(var25); + + for (var38 = 0; var38 < var10; ++var38) + { + def.faceColors[var38] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var39 = var5.readUnsignedByte(); + if ((var39 & 1) == 1) + { + def.faceRenderTypes[var38] = 1; + var2 = true; + } + else + { + def.faceRenderTypes[var38] = 0; + } + + if ((var39 & 2) == 2) + { + def.textureCoords[var38] = (byte) (var39 >> 2); + def.faceTextures[var38] = def.faceColors[var38]; + def.faceColors[var38] = 127; + if (def.faceTextures[var38] != -1) + { + var3 = true; + } + } + else + { + def.textureCoords[var38] = -1; + def.faceTextures[var38] = -1; + } + } + + if (var13 == 255) + { + def.faceRenderPriorities[var38] = var6.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var38] = var7.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var29); + var5.setOffset(var23); + var38 = 0; + var39 = 0; + var40 = 0; + var41 = 0; + + int var43; + int var44; + for (var42 = 0; var42 < var10; ++var42) + { + var43 = var5.readUnsignedByte(); + if (var43 == 1) + { + var38 = var4.readShortSmart() + var41; + var39 = var4.readShortSmart() + var38; + var40 = var4.readShortSmart() + var39; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 2) + { + var39 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 3) + { + var38 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 4) + { + var44 = var38; + var38 = var39; + var39 = var44; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var44; + def.faceIndices3[var42] = var40; + } + } + + var4.setOffset(var31); + + for (var42 = 0; var42 < var11; ++var42) + { + def.textureRenderTypes[var42] = 0; + def.texIndices1[var42] = (short) var4.readUnsignedShort(); + def.texIndices2[var42] = (short) var4.readUnsignedShort(); + def.texIndices3[var42] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) { boolean var45 = false; - for (var22 = 0; var22 < var11; ++var22) + for (var43 = 0; var43 < var10; ++var43) { - var21 = model.textureCoordinates[var22] & 255; - if (var21 != 255) + var44 = def.textureCoords[var43] & 255; + if (var44 != 255) { - if ((model.textureTriangleVertexIndices1[var21] & '\uffff') == model.faceVertexIndices1[var22] && (model.textureTriangleVertexIndices2[var21] & '\uffff') == model.faceVertexIndices2[var22] && (model.textureTriangleVertexIndices3[var21] & '\uffff') == model.faceVertexIndices3[var22]) + if (def.faceIndices1[var43] == (def.texIndices1[var44] & '\uffff') && def.faceIndices2[var43] == (def.texIndices2[var44] & '\uffff') && def.faceIndices3[var43] == (def.texIndices3[var44] & '\uffff')) { - model.textureCoordinates[var22] = -1; + def.textureCoords[var43] = -1; } else { @@ -732,19 +1394,19 @@ public class ModelLoader if (!var45) { - model.textureCoordinates = null; + def.textureCoords = null; } } - if (!var43) + if (!var3) { - model.faceTextures = null; + def.faceTextures = null; } if (!var2) { - model.faceRenderTypes = null; + def.faceRenderTypes = null; } - } + } } diff --git a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java index dc8922535e..3898850920 100644 --- a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java +++ b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java @@ -227,22 +227,22 @@ public class ItemSpriteFactory litModel.field1856 = new int[def.faceCount]; litModel.field1854 = new int[def.faceCount]; litModel.field1823 = new int[def.faceCount]; - if (def.textureTriangleCount > 0 && def.textureCoordinates != null) + if (def.numTextureFaces > 0 && def.textureCoords != null) { - int[] var9 = new int[def.textureTriangleCount]; + int[] var9 = new int[def.numTextureFaces]; int var10; for (var10 = 0; var10 < def.faceCount; ++var10) { - if (def.textureCoordinates[var10] != -1) + if (def.textureCoords[var10] != -1) { - ++var9[def.textureCoordinates[var10] & 255]; + ++var9[def.textureCoords[var10] & 255]; } } litModel.field1852 = 0; - for (var10 = 0; var10 < def.textureTriangleCount; ++var10) + for (var10 = 0; var10 < def.numTextureFaces; ++var10) { if (var9[var10] > 0 && def.textureRenderTypes[var10] == 0) { @@ -256,13 +256,13 @@ public class ItemSpriteFactory var10 = 0; - for (int i = 0; i < def.textureTriangleCount; ++i) + for (int i = 0; i < def.numTextureFaces; ++i) { if (var9[i] > 0 && def.textureRenderTypes[i] == 0) { - litModel.field1844[var10] = def.textureTriangleVertexIndices1[i] & '\uffff'; - litModel.field1865[var10] = def.textureTriangleVertexIndices2[i] & '\uffff'; - litModel.field1846[var10] = def.textureTriangleVertexIndices3[i] & '\uffff'; + litModel.field1844[var10] = def.texIndices1[i] & '\uffff'; + litModel.field1865[var10] = def.texIndices2[i] & '\uffff'; + litModel.field1846[var10] = def.texIndices3[i] & '\uffff'; var9[i] = var10++; } else @@ -275,9 +275,9 @@ public class ItemSpriteFactory for (int i = 0; i < def.faceCount; ++i) { - if (def.textureCoordinates[i] != -1) + if (def.textureCoords[i] != -1) { - litModel.field1840[i] = (byte) var9[def.textureCoordinates[i] & 255]; + litModel.field1840[i] = (byte) var9[def.textureCoords[i] & 255]; } else { @@ -299,13 +299,13 @@ public class ItemSpriteFactory } byte faceAlpha; - if (def.faceAlphas == null) + if (def.faceTransparencies == null) { faceAlpha = 0; } else { - faceAlpha = def.faceAlphas[faceIdx]; + faceAlpha = def.faceTransparencies[faceIdx]; } short faceTexture; @@ -355,15 +355,15 @@ public class ItemSpriteFactory else { int var15 = def.faceColors[faceIdx] & '\uffff'; - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = method2608(var15, tmp); @@ -385,15 +385,15 @@ public class ItemSpriteFactory } else { - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = bound2to126(tmp); @@ -401,15 +401,15 @@ public class ItemSpriteFactory } litModel.verticesCount = def.vertexCount; - litModel.verticesX = def.vertexPositionsX; - litModel.verticesY = def.vertexPositionsY; - litModel.verticesZ = def.vertexPositionsZ; + litModel.verticesX = def.vertexX; + litModel.verticesY = def.vertexY; + litModel.verticesZ = def.vertexZ; litModel.indicesCount = def.faceCount; - litModel.indices1 = def.faceVertexIndices1; - litModel.indices2 = def.faceVertexIndices2; - litModel.indices3 = def.faceVertexIndices3; + litModel.indices1 = def.faceIndices1; + litModel.indices2 = def.faceIndices2; + litModel.indices3 = def.faceIndices3; litModel.field1838 = def.faceRenderPriorities; - litModel.field1882 = def.faceAlphas; + litModel.field1882 = def.faceTransparencies; litModel.field1842 = def.priority; litModel.field1841 = def.faceTextures; return litModel; diff --git a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java index fb65f99972..75b67f689f 100644 --- a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java +++ b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java @@ -53,9 +53,9 @@ public class ObjExporter for (int i = 0; i < model.vertexCount; ++i) { - objWriter.println("v " + model.vertexPositionsX[i] + " " - + model.vertexPositionsY[i] * -1 + " " - + model.vertexPositionsZ[i] * -1); + objWriter.println("v " + model.vertexX[i] + " " + + model.vertexY[i] * -1 + " " + + model.vertexZ[i] * -1); } if (model.faceTextures != null) @@ -78,9 +78,9 @@ public class ObjExporter for (int i = 0; i < model.faceCount; ++i) { - int x = model.faceVertexIndices1[i] + 1; - int y = model.faceVertexIndices2[i] + 1; - int z = model.faceVertexIndices3[i] + 1; + int x = model.faceIndices1[i] + 1; + int y = model.faceIndices2[i] + 1; + int z = model.faceIndices3[i] + 1; objWriter.println("usemtl m" + i); if (model.faceTextures != null) @@ -129,9 +129,9 @@ public class ObjExporter int alpha = 0; - if (model.faceAlphas != null) + if (model.faceTransparencies != null) { - alpha = model.faceAlphas[i] & 0xFF; + alpha = model.faceTransparencies[i] & 0xFF; } if (alpha != 0) diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java index de52f5c5aa..af6c461562 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java @@ -93,6 +93,7 @@ public class HiscoreResult private Skill kreearra; private Skill krilTsutsaroth; private Skill mimic; + private Skill nex; private Skill nightmare; private Skill phosanisNightmare; private Skill obor; @@ -244,6 +245,8 @@ public class HiscoreResult return krilTsutsaroth; case MIMIC: return mimic; + case NEX: + return nex; case NIGHTMARE: return nightmare; case PHOSANIS_NIGHTMARE: diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java index 6c88ebcd18..ee8504bc8a 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java @@ -118,6 +118,10 @@ class HiscoreResultBuilder hiscoreResult.setKreearra(skills.get(index++)); hiscoreResult.setKrilTsutsaroth(skills.get(index++)); hiscoreResult.setMimic(skills.get(index++)); + if (skills.size() > 83) + { + hiscoreResult.setNex(skills.get(index++)); + } hiscoreResult.setNightmare(skills.get(index++)); hiscoreResult.setPhosanisNightmare(skills.get(index++)); hiscoreResult.setObor(skills.get(index++)); diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java index 698bd34e8e..0856e9270a 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java @@ -97,6 +97,7 @@ public enum HiscoreSkill KREEARRA("Kree'Arra", BOSS), KRIL_TSUTSAROTH("K'ril Tsutsaroth", BOSS), MIMIC("Mimic", BOSS), + NEX("Nex", BOSS), NIGHTMARE("Nightmare", BOSS), PHOSANIS_NIGHTMARE("Phosani's Nightmare", BOSS), OBOR("Obor", BOSS), diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 080f6443a1..83d0c1cf1b 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -636,6 +636,13 @@ public interface Client extends GameEngine */ World[] getWorldList(); + /** + * Create a new menu entry + * @param idx the index to create the menu entry at. Accepts negative indexes eg. -1 inserts at the end. + * @return the newly created menu entry + */ + MenuEntry createMenuEntry(int idx); + /** * Gets an array of currently open right-click menu entries that can be * clicked and activated. @@ -1133,7 +1140,7 @@ public interface Client extends GameEngine * @param id the ID of the animation. Any int is allowed, but implementations in the client * should be defined in {@link AnimationID} */ - Sequence loadAnimation(int id); + Animation loadAnimation(int id); /** * Gets the music volume @@ -1341,7 +1348,7 @@ public interface Client extends GameEngine /** * Retrieve the nameable container containing friends */ - NameableContainer getFriendContainer(); + FriendContainer getFriendContainer(); /** * Retrieve the nameable container containing ignores diff --git a/runelite-api/src/main/java/net/runelite/api/Sequence.java b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java similarity index 82% rename from runelite-api/src/main/java/net/runelite/api/Sequence.java rename to runelite-api/src/main/java/net/runelite/api/FriendContainer.java index e7e1c8fcb9..b288db028b 100644 --- a/runelite-api/src/main/java/net/runelite/api/Sequence.java +++ b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Trevor + * Copyright (c) 2021, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,8 +25,13 @@ package net.runelite.api; /** - * Represents an animation of a renderable + * A nameable container of friends */ -public interface Sequence +public interface FriendContainer extends NameableContainer { + /** + * Get the recent logins/logouts of friends from the last few seconds + * @return + */ + Deque getPendingLogins(); } diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index 150d534de2..2e17407dec 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -24,6 +24,8 @@ */ package net.runelite.api; +import java.util.Arrays; +import java.util.function.Consumer; import lombok.Data; import lombok.NoArgsConstructor; @@ -94,6 +96,113 @@ public class MenuEntry implements Cloneable } } + public String getOption() + { + return option; + } + + public MenuEntry setOption(String option) + { + this.option = option; + return this; + } + + public String getTarget() + { + return target; + } + + public MenuEntry setTarget(String target) + { + this.target = target; + return this; + } + + public int getIdentifier() + { + return this.identifier; + } + + public MenuEntry setIdentifier(int identifier) + { + this.identifier = identifier; + return this; + } + + public MenuAction getType() + { + return MenuAction.of(this.opcode); + } + + public MenuEntry setType(MenuAction type) + { + this.opcode = type.getId(); + return this; + } + + public int getParam0() + { + return this.param0; + } + + public MenuEntry setParam0(int param0) + { + this.param0 = param0; + return this; + } + + public int getParam1() + { + return this.param1; + } + + public MenuEntry setParam1(int param1) + { + this.param1 = param1; + return this; + } + + public boolean isForceLeftClick() + { + return this.forceLeftClick; + } + + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + this.forceLeftClick = forceLeftClick; + return this; + } + + public boolean isDeprioritized() + { + return opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + + public MenuEntry setDeprioritized(boolean deprioritized) + { + if (deprioritized) + { + if (opcode < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + opcode += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + else + { + if (opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + opcode -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + + return this; + } + + public MenuEntry onClick(Consumer callback) + { + return this; + } + public void setActionParam0(int i) { this.param0 = i; @@ -104,26 +213,6 @@ public class MenuEntry implements Cloneable return this.param0; } - public int getParam0() - { - return this.param0; - } - - public void setParam0(int i) - { - this.param0 = i; - } - - public void setParam1(int i) - { - this.param1 = i; - } - - public int getParam1() - { - return this.param1; - } - public void setActionParam1(int i) { this.param1 = i; @@ -139,11 +228,6 @@ public class MenuEntry implements Cloneable this.opcode = i; } - public int getType() - { - return this.opcode; - } - public void setId(int i) { this.identifier = i; @@ -161,4 +245,19 @@ public class MenuEntry implements Cloneable { return MenuAction.of(getOpcode()); } + + // TODO: Remove this after properly implementing the menu + public void add(Client client) + { + MenuEntry[] menuEntries = client.getMenuEntries(); + menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); + menuEntry.setOption(option); + menuEntry.setTarget(target); + menuEntry.setParam0(param0); + menuEntry.setParam1(param1); + menuEntry.setIdentifier(identifier); + menuEntry.setType(MenuAction.of(getOpcode())); + client.setMenuEntries(menuEntries); + } } diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java index 871f7525cd..71338a968b 100644 --- a/runelite-api/src/main/java/net/runelite/api/Model.java +++ b/runelite-api/src/main/java/net/runelite/api/Model.java @@ -55,13 +55,13 @@ public interface Model extends Renderable int[] getVerticesZ(); - int getTrianglesCount(); + int getFaceCount(); - int[] getTrianglesX(); + int[] getFaceIndices1(); - int[] getTrianglesY(); + int[] getFaceIndices2(); - int[] getTrianglesZ(); + int[] getFaceIndices3(); int[] getFaceColors1(); @@ -69,7 +69,7 @@ public interface Model extends Renderable int[] getFaceColors3(); - byte[] getTriangleTransparencies(); + byte[] getFaceTransparencies(); int getSceneId(); void setSceneId(int sceneId); @@ -109,4 +109,9 @@ public interface Model extends Renderable int[] getVertexNormalsX(); int[] getVertexNormalsY(); int[] getVertexNormalsZ(); + + byte getOverrideAmount(); + byte getOverrideHue(); + byte getOverrideSaturation(); + byte getOverrideLuminance(); } diff --git a/runelite-api/src/main/java/net/runelite/api/PendingLogin.java b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java new file mode 100644 index 0000000000..c7c3a1d1a3 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +/** + * A pending friend login/out. This is used to suppress world hop notifications + * by buffering the pending logins to try to match a pending logout with a pending + * login and cancel both. + */ +public interface PendingLogin +{ + /** + * The name of the player + * @return + */ + String getName(); + + /** + * The world the player logged into, or 0 if a logout. + * @return + */ + short getWorld(); +} diff --git a/runelite-api/src/main/java/net/runelite/api/Perspective.java b/runelite-api/src/main/java/net/runelite/api/Perspective.java index 2ddd236fd5..17360b5c5e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Perspective.java +++ b/runelite-api/src/main/java/net/runelite/api/Perspective.java @@ -782,9 +782,9 @@ public class Perspective final int radius = 5; int[][] tris = new int[][]{ - m.getTrianglesX(), - m.getTrianglesY(), - m.getTrianglesZ() + m.getFaceIndices1(), + m.getFaceIndices2(), + m.getFaceIndices3() }; int vpX1 = client.getViewportXOffset(); @@ -792,10 +792,10 @@ public class Perspective int vpX2 = vpX1 + client.getViewportWidth(); int vpY2 = vpY1 + client.getViewportHeight(); - List rects = new ArrayList<>(m.getTrianglesCount()); + List rects = new ArrayList<>(m.getFaceCount()); nextTri: - for (int tri = 0; tri < m.getTrianglesCount(); tri++) + for (int tri = 0; tri < m.getFaceCount(); tri++) { if (faceColors3[tri] == -2) { diff --git a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java index 20f2fb001e..5fcd50c3e3 100644 --- a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java +++ b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java @@ -41,7 +41,7 @@ public interface RuneLiteObject extends GraphicsObject * Sets the animation of the RuneLiteObject * If animation is null model will be static */ - void setAnimation(Sequence animation); + void setAnimation(Animation animation); /** * Sets whether the animation of the RuneLiteObject should loop when the animation ends. diff --git a/runelite-api/src/main/java/net/runelite/api/ScriptID.java b/runelite-api/src/main/java/net/runelite/api/ScriptID.java index 5205871c64..aafe123a0f 100644 --- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java +++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java @@ -257,6 +257,12 @@ public final class ScriptID @ScriptArguments(integer = 15) public static final int FRIENDS_CHAT_CHANNEL_REBUILD = 1658; + /** + * Builds the widget that holds all of the players inside a clan chat + */ + @ScriptArguments(integer = 7) + public static final int CLAN_SIDEPANEL_DRAW = 4396; + /** * Builds the widget for making an offer in Grand Exchange */ diff --git a/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java b/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java index 6874f4145c..7c33371f94 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java +++ b/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java @@ -31,7 +31,7 @@ public class ClientTick { public static final ClientTick INSTANCE = new ClientTick(); - private ClientTick() + public ClientTick() { // noop } diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java index c7be511bc1..745f939bfa 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java @@ -25,24 +25,50 @@ package net.runelite.api.events; import lombok.Getter; -import net.runelite.api.MenuEntry; /** * An event when a new entry is added to a right-click menu. */ -public class MenuEntryAdded extends MenuEntry +public class MenuEntryAdded { // Here for RuneLite compatibility (different parameter order) public MenuEntryAdded(String option, String target, int type, int identifier, int actionParam0, int actionParam1) { - super(option, target, identifier, type, actionParam0, actionParam1, false); + this(option, target, identifier, type, actionParam0, actionParam1, false); } - public MenuEntryAdded(String option, String target, int identifier, int opcode, int param0, int param1, boolean forceLeftClick) + public MenuEntryAdded(String option, String target, int identifier, int type, int param0, int param1, boolean forceLeftClick) { - super(option, target, identifier, opcode, param0, param1, forceLeftClick); + this.option = option; + this.target = target; + this.identifier = identifier; + this.type = type; + this.actionParam0 = param0; + this.actionParam1 = param1; + this.forceLeftClick = forceLeftClick; } + @Getter + private final String option; + + @Getter + private final String target; + + @Getter + private final int type; + + @Getter + private final int identifier; + + @Getter + private final int actionParam0; + + @Getter + private final int actionParam1; + + @Getter + private final boolean forceLeftClick; + /** * If this is set to true client mixin will update * the menu entry with the modified values. diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java index fe5b90edb2..3a5e884636 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java @@ -91,33 +91,9 @@ public class MenuOptionClicked { this.setMenuOption(entry.getOption()); this.setMenuTarget(entry.getTarget()); - this.setId(entry.getId()); - this.setMenuAction(MenuAction.of(entry.getOpcode())); + this.setId(entry.getIdentifier()); + this.setMenuAction(entry.getType()); this.setParam0(entry.getParam0()); this.setParam1(entry.getParam1()); } - - @Deprecated - public int getActionParam() - { - return param0; - } - - @Deprecated - public void setActionParam(int i) - { - param0 = i; - } - - @Deprecated - public int getWidgetId() - { - return param1; - } - - @Deprecated - public void setWidgetId(int i) - { - param1 = i; - } } diff --git a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java index d3a4dda748..f6f55e89a8 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java @@ -32,6 +32,7 @@ import net.runelite.api.widgets.WidgetInfo; * A MenuManager widget menu was clicked. This event is fired only for MenuManager managed custom menus. */ @Data +@Deprecated public class WidgetMenuOptionClicked { /** @@ -51,4 +52,4 @@ public class WidgetMenuOptionClicked * The widget id of the widget that was clicked. */ private int widgetId; -} +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index a637f90919..6cb8b996be 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -1352,11 +1352,15 @@ public final class WidgetID static class Clan { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } static class ClanGuest { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 1bfd141dfd..a5aa4e6193 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -554,7 +554,12 @@ public enum WidgetInfo TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR), + CLAN_LAYER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.LAYER), + CLAN_HEADER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.HEADER), CLAN_MEMBER_LIST(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.MEMBERS), + + CLAN_GUEST_LAYER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.LAYER), + CLAN_GUEST_HEADER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.HEADER), CLAN_GUEST_MEMBER_LIST(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.MEMBERS), //OpenOSRS diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 05a9f07ef4..857752fb1d 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -395,7 +395,6 @@ public class RuneLite // Add core overlays WidgetOverlay.createOverlays(overlayManager, client).forEach(overlayManager::add); overlayManager.add(worldMapOverlay.get()); - eventBus.register(worldMapOverlay.get()); overlayManager.add(tooltipOverlay.get()); playerManager.get(); diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index d6c9c79893..93459b761c 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -27,10 +27,10 @@ package net.runelite.client.menus; import com.google.common.base.Preconditions; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -67,6 +67,7 @@ public class MenuManager { this.client = client; this.eventBus = eventBus; + eventBus.register(this); } @@ -74,10 +75,12 @@ public class MenuManager * Adds a CustomMenuOption to the list of managed menu options. * * @param customMenuOption The custom menu to add + * @param callback callback to be called when the menu is clicked */ - public void addManagedCustomMenu(WidgetMenuOption customMenuOption) + public void addManagedCustomMenu(WidgetMenuOption customMenuOption, Consumer callback) { managedMenuOptions.put(customMenuOption.getWidgetId(), customMenuOption); + customMenuOption.callback = callback; } /** @@ -113,7 +116,7 @@ public class MenuManager return; } - int widgetId = event.getParam1(); + int widgetId = event.getActionParam1(); Collection options = managedMenuOptions.get(widgetId); if (options.isEmpty()) { @@ -122,11 +125,10 @@ public class MenuManager MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry[] newMenuEntries = Arrays.copyOf(menuEntries, menuEntries.length + options.size()); // Menu entries are sorted with higher-index entries appearing toward the top of the minimenu, so insert older // managed menu entries at higher indices and work backward for newer entries so newly-added entries appear at // the bottom - int insertIdx = newMenuEntries.length - 1; + int insertIdx = -1; for (WidgetMenuOption currentMenu : options) { // Exit if we've inserted the managed menu entries already @@ -135,16 +137,44 @@ public class MenuManager return; } - MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(currentMenu.getMenuOption()); - menuEntry.setParam1(widgetId); - menuEntry.setTarget(currentMenu.getMenuTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(insertIdx--) + .setOption(currentMenu.getMenuOption()) + .setTarget(currentMenu.getMenuTarget()) + .setType(MenuAction.RUNELITE) + .setParam1(widgetId) + .onClick(currentMenu.callback) + // TODO: remove + .add(client); + } + } - newMenuEntries[insertIdx--] = menuEntry; + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) + { + if (event.getMenuAction() != MenuAction.RUNELITE) + { + return; } - client.setMenuEntries(newMenuEntries); + int widgetId = event.getParam1(); + Collection options = managedMenuOptions.get(widgetId); + + for (WidgetMenuOption curMenuOption : options) + { + if (curMenuOption.getMenuTarget().equals(event.getMenuTarget()) + && curMenuOption.getMenuOption().equals(event.getMenuOption())) + { + WidgetMenuOptionClicked widgetMenuOptionClicked = new WidgetMenuOptionClicked(); + widgetMenuOptionClicked.setMenuOption(event.getMenuOption()); + widgetMenuOptionClicked.setMenuTarget(event.getMenuTarget()); + widgetMenuOptionClicked.setWidget(curMenuOption.getWidget()); + widgetMenuOptionClicked.setWidgetId(curMenuOption.getWidgetId()); + + eventBus.post(widgetMenuOptionClicked); + + return; + } + } } public void addPlayerMenuItem(String menuText) @@ -198,33 +228,6 @@ public class MenuManager addPlayerMenuItem(newIdx, menuText); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - int widgetId = event.getParam1(); - Collection options = managedMenuOptions.get(widgetId); - - for (WidgetMenuOption curMenuOption : options) - { - if (curMenuOption.getMenuTarget().equals(event.getMenuTarget()) - && curMenuOption.getMenuOption().equals(event.getMenuOption())) - { - WidgetMenuOptionClicked customMenu = new WidgetMenuOptionClicked(); - customMenu.setMenuOption(event.getMenuOption()); - customMenu.setMenuTarget(event.getMenuTarget()); - customMenu.setWidget(curMenuOption.getWidget()); - customMenu.setWidgetId(curMenuOption.getWidgetId()); - eventBus.post(customMenu); - return; - } - } - } - private void addPlayerMenuItem(int playerOptionIndex, String menuText) { client.getPlayerOptions()[playerOptionIndex] = menuText; diff --git a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java index 1f1a74606b..7727897f3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java @@ -25,9 +25,11 @@ package net.runelite.client.menus; import java.awt.Color; +import java.util.function.Consumer; import javax.annotation.Nullable; import lombok.Getter; import lombok.Setter; +import net.runelite.api.MenuEntry; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; @@ -65,6 +67,8 @@ public final class WidgetMenuOption @Getter private final int widgetId; + Consumer callback; + /** * Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options * diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 6091fefb10..3ee0513b06 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -341,9 +341,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - MenuEntry[] entries = client.getMenuEntries(); - - if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() + if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { Widget container = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER); @@ -357,87 +355,82 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener text += " (" + tagCount + ")"; } - MenuEntry editTags = new MenuEntry(); - editTags.setParam0(event.getActionParam0()); - editTags.setParam1(event.getParam1()); - editTags.setTarget(event.getTarget()); - editTags.setOption(text); - editTags.setType(MenuAction.RUNELITE.getId()); - editTags.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = editTags; - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(event.getTarget()) + .setOption(text) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(this::editTags) + // TODO: remove + .add(client); } tabInterface.handleAdd(event); } + private void editTags(MenuEntry entry) + { + int inventoryIndex = entry.getParam0(); + ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); + if (bankContainer == null) + { + return; + } + Item[] items = bankContainer.getItems(); + if (inventoryIndex < 0 || inventoryIndex >= items.length) + { + return; + } + Item item = bankContainer.getItems()[inventoryIndex]; + if (item == null) + { + return; + } + + int itemId = item.getId(); + ItemComposition itemComposition = itemManager.getItemComposition(itemId); + String name = itemComposition.getName(); + + // Get both tags and vartags and append * to end of vartags name + Collection tags = tagManager.getTags(itemId, false); + tagManager.getTags(itemId, true).stream() + .map(i -> i + "*") + .forEach(tags::add); + + String initialValue = Text.toCSV(tags); + + chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") + .addCharValidator(FILTERED_CHARS) + .value(initialValue) + .onDone((Consumer) (newValue) -> + clientThread.invoke(() -> + { + // Split inputted tags to vartags (ending with *) and regular tags + final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); + final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> + { + newTags.remove(s); + return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); + }).collect(Collectors.toList()); + + // And save them + tagManager.setTagString(itemId, Text.toCSV(newTags), false); + tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); + + // Check both previous and current tags in case the tag got removed in new tags or in case + // the tag got added in new tags + tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + })) + .build(); + } + @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() - && event.getMenuAction() == MenuAction.RUNELITE - && event.getMenuOption().startsWith(EDIT_TAGS_MENU_OPTION)) - { - event.consume(); - int inventoryIndex = event.getParam0(); - ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); - if (bankContainer == null) - { - return; - } - Item[] items = bankContainer.getItems(); - if (inventoryIndex < 0 || inventoryIndex >= items.length) - { - return; - } - Item item = bankContainer.getItems()[inventoryIndex]; - if (item == null) - { - return; - } - - int itemId = item.getId(); - ItemComposition itemComposition = itemManager.getItemComposition(itemId); - String name = itemComposition.getName(); - - // Get both tags and vartags and append * to end of vartags name - Collection tags = tagManager.getTags(itemId, false); - tagManager.getTags(itemId, true).stream() - .map(i -> i + "*") - .forEach(tags::add); - - String initialValue = Text.toCSV(tags); - - chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") - .addCharValidator(FILTERED_CHARS) - .value(initialValue) - .onDone((Consumer) (newValue) -> - clientThread.invoke(() -> - { - // Split inputted tags to vartags (ending with *) and regular tags - final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); - final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> - { - newTags.remove(s); - return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); - }).collect(Collectors.toList()); - - // And save them - tagManager.setTagString(itemId, Text.toCSV(newTags), false); - tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); - - // Check both previous and current tags in case the tag got removed in new tags or in case - // the tag got added in new tags - tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - })) - .build(); - } - else - { - tabInterface.handleClick(event); - } + tabInterface.handleClick(event); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 05a3240f95..1601e0d71f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -618,38 +618,32 @@ public class TabInterface return; } - MenuEntry[] entries = client.getMenuEntries(); if (activeTab != null - && event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() + && event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { - entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries); - client.setMenuEntries(entries); + createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget()); } - else if (event.getParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() + else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() && event.getOption().equals("Deposit inventory")) { - entries = createMenuEntry(event, TAG_INVENTORY, event.getTarget(), entries); + createMenuEntry(event, TAG_INVENTORY, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } - else if (event.getParam1() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() + else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() && event.getOption().equals("Deposit worn items")) { - entries = createMenuEntry(event, TAG_GEAR, event.getTarget(), entries); + createMenuEntry(event, TAG_GEAR, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } } @@ -773,7 +767,6 @@ public class TabInterface { entry.setOption(TAG_SEARCH + Text.removeTags(entry.getTarget()) + (shiftDown ? VAR_TAG_SUFFIX : "")); entry.setTarget(draggedWidget.getName()); - client.setMenuEntries(entries); } if (entry.getOption().equals(SCROLL_UP)) @@ -1195,17 +1188,16 @@ public class TabInterface searchButtonBackground.setSpriteId(SpriteID.EQUIPMENT_SLOT_TILE); } - private static MenuEntry[] createMenuEntry(MenuEntryAdded event, String option, String target, MenuEntry[] entries) + private void createMenuEntry(MenuEntryAdded event, String option, String target) { - final MenuEntry entry = new MenuEntry(); - entry.setParam0(event.getActionParam0()); - entry.setParam1(event.getParam1()); - entry.setTarget(target); - entry.setOption(option); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = entry; - return entries; + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(target) + .setOption(option) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + // TODO: remove + .add(client); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java index dfb29e8950..21c495b603 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java @@ -294,7 +294,7 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener { for (MenuEntry menuEntry : menuEntries) { - MenuAction action = MenuAction.of(menuEntry.getType()); + MenuAction action = menuEntry.getType(); switch (action) { case CANCEL: diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java index eeffc30f4d..66739bf5a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java @@ -206,6 +206,18 @@ public interface ChatChannelConfig extends Config return false; } + @ConfigItem( + keyName = "clanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online clan members at the end of the clan's name.", + position = 1, + section = clanChatSection + ) + default boolean clanChatShowOnlineMemberCount() + { + return false; + } + @ConfigItem( keyName = "guestClanChatShowJoinLeave", name = "Show Join/Leave", @@ -217,4 +229,16 @@ public interface ChatChannelConfig extends Config { return false; } + + @ConfigItem( + keyName = "guestClanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online guest clan members at the end of the clan's name.", + position = 1, + section = guestClanChatSection + ) + default boolean guestClanChatShowOnlineMemberCount() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java index 25ac07f449..d1277b981d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java @@ -145,6 +145,8 @@ public class ChatChannelPlugin extends Plugin { clientThread.invoke(() -> colorIgnoredPlayers(config.showIgnoresColor())); } + + rebuildClanTitle(); } @Override @@ -153,6 +155,7 @@ public class ChatChannelPlugin extends Plugin chats = null; clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE)); rebuildFriendsChat(); + rebuildClanTitle(); } @Subscribe @@ -167,6 +170,8 @@ public class ChatChannelPlugin extends Plugin Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE; clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor)); + + rebuildClanTitle(); } } @@ -606,6 +611,18 @@ public class ChatChannelPlugin extends Plugin chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)"); } } + else if (event.getScriptId() == ScriptID.CLAN_SIDEPANEL_DRAW) + { + if (config.clanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_HEADER, client.getClanChannel()); + } + + if (config.guestClanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_GUEST_HEADER, client.getGuestClanChannel()); + } + } } private void insertRankIcon(final ChatMessage message) @@ -740,4 +757,35 @@ public class ChatChannelPlugin extends Plugin listWidget.setTextColor(ignoreColor.getRGB()); } } + + private void rebuildClanTitle() + { + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_GUEST_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + } + + private void updateClanTitle(WidgetInfo widget, ClanChannel channel) + { + Widget header = client.getWidget(widget); + if (header != null && channel != null) + { + Widget title = header.getChild(0); + title.setText(title.getText() + " (" + channel.getMembers().size() + ")"); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java index 39d736d4c5..a529800017 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java @@ -201,6 +201,9 @@ public class ChatFilterPlugin extends Plugin case NPC_EXAMINE: case OBJECT_EXAMINE: case SPAM: + case CLAN_MESSAGE: + case CLAN_GUEST_MESSAGE: + case CLAN_GIM_MESSAGE: if (config.filterGameChat()) { message = censorMessage(null, message); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index ad6530a2e7..c5f1996275 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -25,7 +25,6 @@ */ package net.runelite.client.plugins.chathistory; -import com.google.common.base.Strings; import com.google.common.collect.EvictingQueue; import com.google.inject.Provides; import java.awt.Toolkit; @@ -83,8 +82,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener private Queue messageQueue; private Deque friends; - private String currentMessage = null; - @Inject private Client client; @@ -121,7 +118,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener messageQueue = null; friends.clear(); friends = null; - currentMessage = null; keyManager.unregisterKeyListener(this); } @@ -195,7 +191,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener // Use second entry as first one can be walk here with transparent chatbox final MenuEntry entry = event.getMenuEntries()[event.getMenuEntries().length - 2]; - if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY.getId() && entry.getType() != MenuAction.RUNELITE.getId()) + if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY && entry.getType() != MenuAction.RUNELITE) { return; } @@ -236,16 +232,19 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - currentMessage = messageContents.getText(); + String currentMessage = messageContents.getText(); - final MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(COPY_TO_CLIPBOARD); - menuEntry.setTarget(entry.getTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - menuEntry.setParam0(entry.getParam0()); - menuEntry.setParam1(entry.getParam1()); - menuEntry.setIdentifier(entry.getIdentifier()); - client.setMenuEntries(ArrayUtils.insert(1, client.getMenuEntries(), menuEntry)); + client.createMenuEntry(1) + .setOption(COPY_TO_CLIPBOARD) + .setTarget(entry.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); + }) + // TODO: remove + .add(client); } @Subscribe @@ -258,11 +257,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener { clearChatboxHistory(ChatboxTab.of(event.getParam1())); } - else if (COPY_TO_CLIPBOARD.equals(menuOption) && !Strings.isNullOrEmpty(currentMessage)) - { - final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); - } } @Subscribe @@ -279,10 +273,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - final MenuEntry clearEntry = new MenuEntry(); - clearEntry.setTarget(""); - clearEntry.setType(MenuAction.RUNELITE_HIGH_PRIORITY.getId()); - clearEntry.setParam0(entry.getActionParam0()); + final MenuEntry clearEntry = client.createMenuEntry(-2) + .setType(MenuAction.RUNELITE_HIGH_PRIORITY); clearEntry.setParam1(entry.getActionParam1()); final StringBuilder optionBuilder = new StringBuilder(); @@ -298,10 +290,9 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener } optionBuilder.append(CLEAR_HISTORY); - clearEntry.setOption(optionBuilder.toString()); - - final MenuEntry[] menuEntries = client.getMenuEntries(); - client.setMenuEntries(ArrayUtils.insert(menuEntries.length - 1, menuEntries, clearEntry)); + clearEntry.setOption(optionBuilder.toString()) + // TODO: remove + .add(client); } private void clearMessageQueue(ChatboxTab tab) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index 64e12e7841..792e648f63 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -490,7 +490,6 @@ public class DevToolsPlugin extends Plugin } entry.setTarget(entry.getTarget() + " " + ColorUtil.prependColorTag("(" + info + ")", JagexColors.MENU_TARGET)); - client.setMenuEntries(entries); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java index 5e5e9a6011..ed99e6ef70 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java @@ -48,16 +48,16 @@ public class WidgetInfoTableModel extends AbstractTableModel private static final int COL_FIELD = 0; private static final int COL_VALUE = 1; - private final List fields = populateWidgetFields(); + private final List> fields = populateWidgetFields(); private Widget widget = null; - private Map values = null; + private Map, Object> values = null; public void setWidget(Widget w) { clientThread.invoke(() -> { - Map newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( + Map, Object> newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( Function.identity(), i -> i.getValue(w) )); @@ -137,9 +137,9 @@ public class WidgetInfoTableModel extends AbstractTableModel }); } - private List populateWidgetFields() + private List> populateWidgetFields() { - List out = new ArrayList<>(); + List> out = new ArrayList<>(); out.add(new WidgetField<>("Id", Widget::getId)); out.add(new WidgetField<>("Type", Widget::getType, Widget::setType, Integer.class)); @@ -209,6 +209,11 @@ public class WidgetInfoTableModel extends AbstractTableModel } return null; })); + out.add(new WidgetField<>("OnOpListener", Widget::getOnOpListener)); + out.add(new WidgetField<>("OnKeyListener", Widget::getOnKeyListener)); + out.add(new WidgetField<>("OnLoadListener", Widget::getOnLoadListener)); + out.add(new WidgetField<>("OnInvTransmitListener", Widget::getOnInvTransmitListener)); + out.add(new WidgetField<>("OnVarTransmitListener", Widget::getOnVarTransmitListener)); return out; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java index 8bdc7baa00..592561219f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java @@ -487,7 +487,7 @@ class WidgetInspector extends DevToolsFrame client.setSpellSelected(false); ev.consume(); - Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction().getId(), ev.getParam0(), ev.getParam1()); + Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction(), ev.getParam0(), ev.getParam1()); if (target == null) { return; @@ -516,8 +516,8 @@ class WidgetInspector extends DevToolsFrame for (int i = 0; i < menuEntries.length; i++) { MenuEntry entry = menuEntries[i]; - if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET.getId() - && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET + && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET) { continue; } @@ -532,8 +532,6 @@ class WidgetInspector extends DevToolsFrame entry.setTarget(ColorUtil.wrapWithColorTag(name, color)); } - - client.setMenuEntries(menuEntries); } Color colorForWidget(int index, int length) @@ -543,9 +541,9 @@ class WidgetInspector extends DevToolsFrame return Color.getHSBColor(h, 1, 1); } - Object getWidgetOrWidgetItemForMenuOption(int type, int param0, int param1) + Object getWidgetOrWidgetItemForMenuOption(MenuAction type, int param0, int param1) { - if (type == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (type == MenuAction.SPELL_CAST_ON_WIDGET) { Widget w = client.getWidget(param1); if (param0 != -1) @@ -555,7 +553,7 @@ class WidgetInspector extends DevToolsFrame return w; } - else if (type == MenuAction.ITEM_USE_ON_WIDGET.getId()) + else if (type == MenuAction.ITEM_USE_ON_WIDGET) { Widget w = client.getWidget(param1); return w.getWidgetItem(param0); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java index 8eb163ba53..8d64881631 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java @@ -93,6 +93,7 @@ enum Emoji XD("Xd"), SPOON("--o"), WEARY_FACE("Dx"), + ROCKETSHIP("=="), // >==> ; private static final Map emojiMap; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java index 441820c465..9c556c3dec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java @@ -28,9 +28,11 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup("friendlist") +@ConfigGroup(FriendListConfig.GROUP) public interface FriendListConfig extends Config { + String GROUP = "friendlist"; + @ConfigItem( keyName = "showWorldOnLogin", name = "Show world on login", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index da5ebda38b..cadefce9c0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -26,30 +26,40 @@ package net.runelite.client.plugins.friendlist; import com.google.inject.Provides; +import java.time.temporal.ChronoUnit; +import java.util.Iterator; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.ChatPlayer; import net.runelite.api.Client; import net.runelite.api.Friend; import net.runelite.api.Ignore; +import net.runelite.api.MenuAction; import net.runelite.api.MessageNode; import net.runelite.api.NameableContainer; +import net.runelite.api.PendingLogin; import net.runelite.api.ScriptID; import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptPostFired; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.task.Schedule; import net.runelite.client.util.Text; @PluginDescriptor( name = "Friend List", description = "Add extra information to the friend and ignore lists" ) +@Slf4j public class FriendListPlugin extends Plugin { private static final int MAX_FRIENDS_P2P = 400; @@ -58,12 +68,21 @@ public class FriendListPlugin extends Plugin private static final int MAX_IGNORES_P2P = 400; private static final int MAX_IGNORES_F2P = 100; + private static final String HIDE_NOTIFICATIONS = "Hide notifications"; + private static final String SHOW_NOTIFICATIONS = "Show notifications"; + @Inject private Client client; @Inject private FriendListConfig config; + @Inject + private ConfigManager configManager; + + @Inject + private ChatMessageManager chatMessageManager; + @Provides FriendListConfig getConfig(ConfigManager configManager) { @@ -144,6 +163,48 @@ public class FriendListPlugin extends Plugin } } + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); + + // Look for "Message" on friends list + if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) + { + String friend = Text.toJagexName(Text.removeTags(event.getTarget())); + + client.createMenuEntry(-1) + .setOption(isHideNotification(friend) ? SHOW_NOTIFICATIONS : HIDE_NOTIFICATIONS) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + boolean hidden = isHideNotification(friend); + setHideNotifications(friend, !hidden); + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .value("Login notifications for " + friend + " are now " + (hidden ? "shown." : "hidden.")) + .build()); + }) + // TODO: remove + .add(client); + } + } + + @Schedule(period = 5, unit = ChronoUnit.SECONDS) + public void setHideNotifications() + { + for (Iterator it = client.getFriendContainer().getPendingLogins().iterator(); it.hasNext(); ) + { + PendingLogin pendingLogin = it.next(); + if (isHideNotification(Text.toJagexName(pendingLogin.getName()))) + { + log.debug("Removing login notification for {}", pendingLogin.getName()); + it.remove(); + } + } + } + private void setFriendsListTitle(final String title) { Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE); @@ -173,4 +234,21 @@ public class FriendListPlugin extends Plugin return null; } + + private void setHideNotifications(String friend, boolean hide) + { + if (hide) + { + configManager.setConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, true); + } + else + { + configManager.unsetConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend); + } + } + + private boolean isHideNotification(String friend) + { + return configManager.getConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, Boolean.class) == Boolean.TRUE; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java index 088a782c9d..24e321ae08 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java @@ -28,7 +28,6 @@ package net.runelite.client.plugins.friendnotes; import com.google.common.base.Strings; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.Color; import java.awt.image.BufferedImage; @@ -43,12 +42,10 @@ import net.runelite.api.GameState; import net.runelite.api.Ignore; import net.runelite.api.IndexedSprite; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Nameable; import net.runelite.api.ScriptID; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NameableNameChanged; import net.runelite.api.events.RemovedFriend; import net.runelite.api.events.ScriptCallbackEvent; @@ -235,7 +232,7 @@ public class FriendNotesPlugin extends Plugin @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - final int groupId = WidgetInfo.TO_GROUP(event.getParam1()); + final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); // Look for "Message" on friends list if ((groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) || @@ -245,16 +242,33 @@ public class FriendNotesPlugin extends Plugin setHoveredFriend(Text.toJagexName(Text.removeTags(event.getTarget()))); // Build "Add Note" or "Edit Note" menu entry - final MenuEntry addNote = new MenuEntry(); - addNote.setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE); - addNote.setType(MenuAction.RUNELITE.getId()); - addNote.setTarget(event.getTarget()); //Preserve color codes here - addNote.setParam0(event.getActionParam0()); - addNote.setParam1(event.getParam1()); + client.createMenuEntry(-1) + .setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + //Friends have color tags + final String sanitizedTarget = Text.toJagexName(Text.removeTags(e.getTarget())); + final String note = getFriendNote(sanitizedTarget); - // Add menu entry - final MenuEntry[] menuEntries = ObjectArrays.concat(client.getMenuEntries(), addNote); - client.setMenuEntries(menuEntries); + // Open the new chatbox input dialog + chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) + .value(Strings.nullToEmpty(note)) + .onDone((content) -> + { + if (content == null) + { + return; + } + + content = Text.removeTags(content).trim(); + log.debug("Set note for '{}': '{}'", sanitizedTarget, content); + setFriendNote(sanitizedTarget, content); + }).build(); + }) + // TODO: remove + .add(client); } else if (hoveredFriend != null) { @@ -262,46 +276,6 @@ public class FriendNotesPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - final int groupId = WidgetInfo.TO_GROUP(event.getParam1()); - - if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() || groupId == WidgetInfo.IGNORE_LIST.getGroupId()) - { - if (Strings.isNullOrEmpty(event.getMenuTarget())) - { - return; - } - - // Handle clicks on "Add Note" or "Edit Note" - if (event.getMenuOption().equals(ADD_NOTE) || event.getMenuOption().equals(EDIT_NOTE)) - { - event.consume(); - - //Friends have color tags - final String sanitizedTarget = Text.toJagexName(Text.removeTags(event.getMenuTarget())); - final String note = getFriendNote(sanitizedTarget); - - // Open the new chatbox input dialog - chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) - .value(Strings.nullToEmpty(note)) - .onDone((content) -> - { - if (content == null) - { - return; - } - - content = Text.removeTags(content).trim(); - log.debug("Set note for '{}': '{}'", sanitizedTarget, content); - setFriendNote(sanitizedTarget, content); - }).build(); - } - } - - } - @Subscribe public void onNameableNameChanged(NameableNameChanged event) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index b275fd7d4e..062c810ffa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -1608,7 +1608,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks modelY = y + client.getCameraY2(); modelZ = z + client.getCameraZ2(); modelOrientation = orientation; - int triangleCount = model.getTrianglesCount(); + int triangleCount = model.getFaceCount(); vertexBuffer.ensureCapacity(12 * triangleCount); uvBuffer.ensureCapacity(12 * triangleCount); @@ -1632,7 +1632,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks model.calculateExtreme(orientation); client.checkClickbox(model, orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash); - int tc = Math.min(MAX_TRIANGLE, model.getTrianglesCount()); + int tc = Math.min(MAX_TRIANGLE, model.getFaceCount()); int uvOffset = model.getUvBufferOffset(); GpuIntBuffer b = bufferForTriangles(tc); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index 910f8b3147..82f8676ce5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -379,7 +379,7 @@ class SceneUploader public int pushModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) { - final int triangleCount = Math.min(model.getTrianglesCount(), GpuPlugin.MAX_TRIANGLE); + final int triangleCount = Math.min(model.getFaceCount(), GpuPlugin.MAX_TRIANGLE); vertexBuffer.ensureCapacity(triangleCount * 12); uvBuffer.ensureCapacity(triangleCount * 12); @@ -388,20 +388,25 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); float[] uv = model.getFaceTextureUVCoordinates(); + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int len = 0; for (int face = 0; face < triangleCount; ++face) { @@ -429,12 +434,22 @@ class SceneUploader len += 3; continue; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + int triangleA = indices1[face]; + int triangleB = indices2[face]; + int triangleC = indices3[face]; vertexBuffer.put(vertexX[triangleA], vertexY[triangleA], vertexZ[triangleA], packAlphaPriority | color1); vertexBuffer.put(vertexX[triangleB], vertexY[triangleB], vertexZ[triangleB], packAlphaPriority | color2); @@ -458,26 +473,31 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + final int triangleA = indices1[face]; + final int triangleB = indices2[face]; + final int triangleC = indices3[face]; int color1 = color1s[face]; int color2 = color2s[face]; int color3 = color3s[face]; + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int packedAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); int sin = 0, cos = 0; @@ -505,6 +525,16 @@ class SceneUploader } return 3; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int a, b, c; @@ -605,4 +635,28 @@ class SceneUploader uvBuffer.put(0, 0, 0, 0); } } + + private static int interpolateHSL(int hsl, byte hue2, byte sat2, byte lum2, byte lerp) + { + int hue = hsl >> 10 & 63; + int sat = hsl >> 7 & 7; + int lum = hsl & 127; + int var9 = lerp & 255; + if (hue2 != -1) + { + hue += var9 * (hue2 - hue) >> 7; + } + + if (sat2 != -1) + { + sat += var9 * (sat2 - sat) >> 7; + } + + if (lum2 != -1) + { + lum += var9 * (lum2 - lum) >> 7; + } + + return (hue << 10 | sat << 7 | lum) & 65535; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index 6075b23e11..f5458b9562 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -66,6 +66,7 @@ import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.ScriptID; import net.runelite.api.VarClientStr; +import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.FocusChanged; import net.runelite.api.events.GameStateChanged; @@ -74,7 +75,6 @@ import net.runelite.api.events.GrandExchangeSearched; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptPostFired; -import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; @@ -120,10 +120,9 @@ public class GrandExchangePlugin extends Plugin @VisibleForTesting static final int GE_SLOTS = 8; private static final int GE_LOGIN_BURST_WINDOW = 2; // ticks - private static final int OFFER_CONTAINER_ITEM = 21; - private static final int OFFER_DEFAULT_ITEM_ID = 6512; + private static final int GE_MAX_EXAMINE_LEN = 100; - private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; + private static final String BUY_LIMIT_GE_TEXT = "Buy limit: "; private static final String BUY_LIMIT_KEY = "buylimit"; private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4); @@ -182,9 +181,6 @@ public class GrandExchangePlugin extends Plugin @Inject private RuneLiteConfig runeLiteConfig; - private Widget grandExchangeText; - private String grandExchangeExamine; - @Inject private GrandExchangeClient grandExchangeClient; private int lastLoginTick; @@ -317,7 +313,6 @@ public class GrandExchangePlugin extends Plugin clientToolbar.removeNavigation(button); mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); - grandExchangeText = null; lastUsername = machineUuid = null; tradeSeq = 0; } @@ -574,8 +569,7 @@ public class GrandExchangePlugin extends Plugin case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID: case WidgetID.SHOP_INVENTORY_GROUP_ID: menuEntry.setOption(SEARCH_GRAND_EXCHANGE); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(entries); + menuEntry.setType(MenuAction.RUNELITE); } } @@ -588,31 +582,10 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - switch (event.getGroupId()) - { - // Grand exchange was opened. - case WidgetID.GRAND_EXCHANGE_GROUP_ID: - grandExchangeText = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_TEXT); - break; - // Grand exchange was closed (if it was open before). - case WidgetID.INVENTORY_GROUP_ID: - grandExchangeText = null; - break; - } - } - @Subscribe public void onScriptPostFired(ScriptPostFired event) { - // GE offers setup init - if (event.getScriptId() == ScriptID.GE_OFFERS_SETUP_BUILD) - { - rebuildGeText(); - } - else if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) + if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) { highlightSearchMatches(); } @@ -739,7 +712,30 @@ public class GrandExchangePlugin extends Plugin @Subscribe public void onScriptCallbackEvent(ScriptCallbackEvent event) { - if (!event.getEventName().equals("setGETitle") || !config.showTotal()) + switch (event.getEventName()) + { + case "setGETitle": + setGeTitle(); + break; + case "geExamineText": + { + String[] stack = client.getStringStack(); + int sz = client.getStringStackSize(); + String fee = stack[sz - 2]; + String examine = stack[sz - 3]; + String text = setExamineText(examine, fee); + if (text != null) + { + stack[sz - 1] = text; + } + break; + } + } + } + + private void setGeTitle() + { + if (!config.showTotal()) { return; } @@ -818,39 +814,10 @@ public class GrandExchangePlugin extends Plugin } } - private void rebuildGeText() + private String setExamineText(String examine, String fee) { - if (grandExchangeText == null) - { - return; - } - Widget grandExchangeOffer = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER); - if (grandExchangeOffer == null) - { - return; - } - Widget grandExchangeItem = grandExchangeOffer.getChild(OFFER_CONTAINER_ITEM); - if (grandExchangeItem == null || grandExchangeItem.isHidden()) - { - return; - } - - final Widget geText = grandExchangeText; - final int itemId = grandExchangeItem.getItemId(); - - if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1) - { - // This item is invalid/nothing has been searched for - return; - } - - if (geText.getText() == grandExchangeExamine) - { - // if we've already set the text, don't set it again - return; - } - - String text = geText.getText(); + final int itemId = client.getVar(VarPlayer.CURRENT_GE_ITEM); + StringBuilder sb = new StringBuilder(); if (config.enableGELimits()) { @@ -859,7 +826,7 @@ public class GrandExchangePlugin extends Plugin // If we have item buy limit, append it if (itemStats != null && itemStats.getGeLimit() > 0) { - text += BUY_LIMIT_GE_TEXT + QuantityFormatter.formatNumber(itemStats.getGeLimit()); + sb.append(BUY_LIMIT_GE_TEXT).append(QuantityFormatter.formatNumber(itemStats.getGeLimit())); } } @@ -869,7 +836,7 @@ public class GrandExchangePlugin extends Plugin if (resetTime != null) { Duration remaining = Duration.between(Instant.now(), resetTime); - text += " (" + DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm") + ")"; + sb.append(" (").append(DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm")).append(")"); } } @@ -878,12 +845,41 @@ public class GrandExchangePlugin extends Plugin final int price = itemManager.getItemPriceWithSource(itemId, true); if (price > 0) { - text += "
Actively traded price: " + QuantityFormatter.formatNumber(price); + if (sb.length() > 0) + { + sb.append(" / "); + } + sb.append("Actively traded price: ").append(QuantityFormatter.formatNumber(price)); } } - grandExchangeExamine = text; - geText.setText(text); + if (sb.length() == 0) + { + return null; + } + + return shortenExamine(examine) + "
" + sb + "
" + fee; + } + + private static String shortenExamine(String examine) + { + int from = 0; + int idx; + while (true) + { + idx = examine.indexOf(' ', from); + if (idx == -1) + { + return examine; + } + if (idx > GE_MAX_EXAMINE_LEN && from > 0) + { + break; // use from + } + from = idx + 1; + } + + return examine.substring(0, from - 1) + "..."; } void openGeLink(String name, int itemId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 22f74c2353..6490f4d8d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -115,14 +115,6 @@ public class GroundItemsPlugin extends Plugin static final int MAX_QUANTITY = 65535; // ItemID for coins private static final int COINS = ItemID.COINS_995; - // Ground item menu options - private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId(); - private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId(); - private static final int THIRD_OPTION = MenuAction.GROUND_ITEM_THIRD_OPTION.getId(); // this is Take - private static final int FOURTH_OPTION = MenuAction.GROUND_ITEM_FOURTH_OPTION.getId(); - private static final int FIFTH_OPTION = MenuAction.GROUND_ITEM_FIFTH_OPTION.getId(); - private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId(); - private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE); @@ -344,9 +336,10 @@ public class GroundItemsPlugin extends Plugin { MenuEntry menuEntry = menuEntries[i]; - int menuType = menuEntry.getType(); - if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION - || menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM) + MenuAction menuType = menuEntry.getType(); + if (menuType == MenuAction.GROUND_ITEM_FIRST_OPTION || menuType == MenuAction.GROUND_ITEM_SECOND_OPTION + || menuType == MenuAction.GROUND_ITEM_THIRD_OPTION || menuType == MenuAction.GROUND_ITEM_FOURTH_OPTION + || menuType == MenuAction.GROUND_ITEM_FIFTH_OPTION || menuType == MenuAction.SPELL_CAST_ON_GROUND_ITEM) { for (MenuEntryWithCount entryWCount : newEntries) { @@ -490,15 +483,15 @@ public class GroundItemsPlugin extends Plugin { if (config.itemHighlightMode() == ItemHighlightMode.MENU || config.itemHighlightMode() == ItemHighlightMode.BOTH) { - final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == CAST_ON_ITEM; - if (!(event.getOption().equals("Take") && event.getType() == THIRD_OPTION) && !telegrabEntry) + final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); + if (!(event.getOption().equals("Take") && event.getType() == MenuAction.GROUND_ITEM_THIRD_OPTION.getId()) && !telegrabEntry) { return; } final int itemId = event.getIdentifier(); final int sceneX = event.getActionParam0(); - final int sceneY = event.getParam1(); + final int sceneY = event.getActionParam1(); MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; @@ -548,8 +541,6 @@ public class GroundItemsPlugin extends Plugin { lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")"); } - - client.setMenuEntries(menuEntries); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index 850f383439..baebf52248 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -30,7 +30,6 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -44,13 +43,11 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Tile; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; @@ -243,48 +240,38 @@ public class GroundMarkerPlugin extends Plugin final GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getRegionX(), worldPoint.getRegionY(), client.getPlane(), null, null); final boolean exists = getPoints(regionId).contains(point); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + (exists ? 2 : 1)); - - MenuEntry mark = menuEntries[menuEntries.length - 1] = new MenuEntry(); - mark.setOption(exists ? UNMARK : MARK); - mark.setTarget(event.getTarget()); - mark.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-1) + .setOption(exists ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + markTile(target.getLocalLocation()); + } + }) + // TODO: remove + .add(client); if (exists) { - MenuEntry label = menuEntries[menuEntries.length - 2] = new MenuEntry(); - label.setOption(LABEL); - label.setTarget(event.getTarget()); - label.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-2) + .setOption(LABEL) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + labelTile(target); + } + }) + // TODO: remove + .add(client); } - - client.setMenuEntries(menuEntries); - } - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId()) - { - return; - } - - Tile target = client.getSelectedSceneTile(); - if (target == null) - { - return; - } - - final String option = event.getMenuOption(); - if (option.equals(MARK) || option.equals(UNMARK)) - { - markTile(target.getLocalLocation()); - } - else if (option.equals(LABEL)) - { - labelTile(target); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java index d311a51319..a7661ff202 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -45,11 +45,10 @@ import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; -import net.runelite.api.events.WidgetMenuOptionClicked; +import net.runelite.api.MenuEntry; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; @@ -82,13 +81,13 @@ class GroundMarkerSharingManager void addImportExportMenuOptions() { - menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION); - menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION); + menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION, this::exportGroundMarkers); + menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION, this::promptForImport); } void addClearMenuOption() { - menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION); + menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION, this::promptForClear); } void removeMenuOptions() @@ -98,36 +97,7 @@ class GroundMarkerSharingManager menuManager.removeManagedCustomMenu(CLEAR_MARKERS_OPTION); } - private boolean widgetMenuClickedEquals(final WidgetMenuOptionClicked event, final WidgetMenuOption target) - { - return event.getMenuTarget().equals(target.getMenuTarget()) && - event.getMenuOption().equals(target.getMenuOption()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - // ensure that the option clicked is the export markers option - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (widgetMenuClickedEquals(event, EXPORT_MARKERS_OPTION)) - { - exportGroundMarkers(); - } - else if (widgetMenuClickedEquals(event, IMPORT_MARKERS_OPTION)) - { - promptForImport(); - } - else if (widgetMenuClickedEquals(event, CLEAR_MARKERS_OPTION)) - { - promptForClear(); - } - } - - private void exportGroundMarkers() + private void exportGroundMarkers(MenuEntry menuEntry) { int[] regions = client.getMapRegions(); if (regions == null) @@ -156,7 +126,7 @@ class GroundMarkerSharingManager sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard."); } - private void promptForImport() + private void promptForImport(MenuEntry menuEntry) { final String clipboardText; try @@ -244,7 +214,7 @@ class GroundMarkerSharingManager sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard."); } - private void promptForClear() + private void promptForClear(MenuEntry entry) { int[] regions = client.getMapRegions(); if (regions == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index 56673629e4..b823a57f62 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -105,13 +105,13 @@ public class HiscorePanel extends PluginPanel GIANT_MOLE, GROTESQUE_GUARDIANS, HESPORI, KALPHITE_QUEEN, KING_BLACK_DRAGON, KRAKEN, KREEARRA, KRIL_TSUTSAROTH, MIMIC, - NIGHTMARE, PHOSANIS_NIGHTMARE, OBOR, SARACHNIS, - SCORPIA, SKOTIZO, TEMPOROSS, - THE_GAUNTLET, THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, - THEATRE_OF_BLOOD_HARD_MODE, THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, - TZTOK_JAD, VENENATIS, VETION, - VORKATH, WINTERTODT, ZALCANO, - ZULRAH + NEX, NIGHTMARE, PHOSANIS_NIGHTMARE, + OBOR, SARACHNIS, SCORPIA, + SKOTIZO, TEMPOROSS, THE_GAUNTLET, + THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, THEATRE_OF_BLOOD_HARD_MODE, + THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, TZTOK_JAD, + VENENATIS, VETION, VORKATH, + WINTERTODT, ZALCANO, ZULRAH ); private static final HiscoreEndpoint[] ENDPOINTS = { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index 95f12ec821..42354c73bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.hiscore; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.util.EnumSet; @@ -39,7 +38,6 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.IconID; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Player; import net.runelite.api.WorldType; import net.runelite.api.events.ChatMessage; @@ -59,7 +57,6 @@ import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; import net.runelite.http.api.hiscore.HiscoreEndpoint; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "HiScore", @@ -169,46 +166,39 @@ public class HiscorePlugin extends Plugin || groupId == WidgetID.GROUP_IRON_GROUP_ID && (option.equals("Add friend") || option.equals("Remove friend") || option.equals("Remove ignore")) ) { - final MenuEntry lookup = new MenuEntry(); - lookup.setOption(LOOKUP); - lookup.setTarget(event.getTarget()); - lookup.setType(MenuAction.RUNELITE.getId()); - lookup.setParam0(event.getActionParam0()); - lookup.setParam1(event.getActionParam1()); - lookup.setIdentifier(event.getIdentifier()); - - insertMenuEntry(lookup, client.getMenuEntries()); + client.createMenuEntry(-2) + .setOption(LOOKUP) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(e -> + { + // Determine proper endpoint from player name. + // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. + HiscoreEndpoint endpoint = findHiscoreEndpointFromPlayerName(e.getTarget()); + String target = Text.removeTags(e.getTarget()); + lookupPlayer(target, endpoint); + }) + // TODO: remove + .add(client); } } @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER) - && event.getMenuOption().equals(LOOKUP)) + if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER && event.getMenuOption().equals(LOOKUP)) { - final String target; - HiscoreEndpoint endpoint; - if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + // The player id is included in the event, so we can use that to get the player name, + // which avoids having to parse out the combat level and any icons preceding the name. + Player player = client.getCachedPlayers()[event.getId()]; + if (player == null) { - // The player id is included in the event, so we can use that to get the player name, - // which avoids having to parse out the combat level and any icons preceding the name. - Player player = client.getCachedPlayers()[event.getId()]; - if (player == null) - { - return; - } + return; + } - endpoint = getWorldEndpoint(); - target = player.getName(); - } - else - { - // Determine proper endpoint from player name. - // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. - endpoint = findHiscoreEndpointFromPlayerName(event.getMenuTarget()); - target = Text.removeTags(event.getMenuTarget()); - } + String target = player.getName(); + HiscoreEndpoint endpoint = getWorldEndpoint(); lookupPlayer(target, endpoint); } @@ -236,14 +226,6 @@ public class HiscorePlugin extends Plugin localHiscoreEndpoint = findHiscoreEndpointFromLocalPlayer(); } - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - client.setMenuEntries(newMenu); - } - private void lookupPlayer(String playerName, HiscoreEndpoint endpoint) { SwingUtilities.invokeLater(() -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java index 00cadc1e22..3870803490 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java @@ -242,6 +242,7 @@ class NameAutocompleter implements KeyListener autocompleteName = Arrays.stream(cachedPlayers) .filter(Objects::nonNull) .map(Player::getName) + .filter(Objects::nonNull) .filter(n -> pattern.matcher(n).matches()) .findFirst(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java index f5cc4b6a51..8ed901350a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.instancemap; import com.google.inject.Binder; import javax.inject.Inject; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.WidgetMenuOptionClicked; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyManager; @@ -72,7 +71,17 @@ public class InstanceMapPlugin extends Plugin private void addCustomOptions() { - menuManager.addManagedCustomMenu(openMapOption); + menuManager.addManagedCustomMenu(openMapOption, entry -> + { + if (overlay.isMapShown()) + { + closeMap(); + } + else + { + showMap(); + } + }); } private void removeCustomOptions() @@ -107,32 +116,6 @@ public class InstanceMapPlugin extends Plugin overlay.onGameStateChange(event); } - private boolean clickedOptionEquals(WidgetMenuOptionClicked event, WidgetMenuOption widgetMenuOption) - { - return event.getMenuOption().equals(widgetMenuOption.getMenuOption()) && event.getMenuTarget().equals(widgetMenuOption.getMenuTarget()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (clickedOptionEquals(event, openMapOption)) - { - if (overlay.isMapShown()) - { - closeMap(); - } - else - { - showMap(); - } - } - } - public void showMap() { overlay.setShowMap(true); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java index a5dd9c95da..0a14053e36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java @@ -79,7 +79,7 @@ class InteractHighlightOverlay extends Overlay } MenuEntry top = menuEntries[menuEntries.length - 1]; - MenuAction menuAction = MenuAction.of(top.getType()); + MenuAction menuAction = top.getType(); switch (menuAction) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java index cdbf26a845..c0e7a60cde 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java @@ -28,14 +28,13 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.inject.Provides; import java.awt.Color; +import java.util.Arrays; import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.events.MenuOpened; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -46,7 +45,6 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; -import net.runelite.client.util.Text; @PluginDescriptor( name = "Inventory Tags", @@ -157,44 +155,11 @@ public class InventoryTagsPlugin extends Plugin } } - @Subscribe - public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - editorMode = event.getMenuOption().equals(CONFIGURE) && Text.removeTags(event.getMenuTarget()).equals(MENU_TARGET); - refreshInventoryMenuOptions(); - } - } - - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - final String selectedMenu = Text.removeTags(event.getMenuTarget()); - - if (event.getMenuOption().equals(MENU_SET)) - { - setTag(event.getId(), selectedMenu); - } - else if (event.getMenuOption().equals(MENU_REMOVE)) - { - unsetTag(event.getId()); - } - } - @Subscribe public void onMenuOpened(final MenuOpened event) { final MenuEntry firstEntry = event.getFirstEntry(); - - if (firstEntry == null) + if (firstEntry == null || !editorMode) { return; } @@ -202,7 +167,7 @@ public class InventoryTagsPlugin extends Plugin final int widgetId = firstEntry.getParam1(); // Inventory item menu - if (widgetId == WidgetInfo.INVENTORY.getId() && editorMode) + if (widgetId == WidgetInfo.INVENTORY.getId()) { int itemId = firstEntry.getIdentifier(); @@ -211,26 +176,32 @@ public class InventoryTagsPlugin extends Plugin return; } - MenuEntry[] menuList = new MenuEntry[GROUPS.size() + 1]; - int num = 0; - - // preserve the 'Cancel' option as the client will reuse the first entry for Cancel and only resets option/action - menuList[num++] = event.getMenuEntries()[0]; + // Set menu to only be Cancel + client.setMenuEntries(Arrays.copyOf(client.getMenuEntries(), 1)); for (final String groupName : GROUPS) { final String group = getTag(itemId); - final MenuEntry newMenu = new MenuEntry(); final Color color = getGroupNameColor(groupName); - newMenu.setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET); - newMenu.setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))); - newMenu.setIdentifier(itemId); - newMenu.setParam1(widgetId); - newMenu.setType(MenuAction.RUNELITE.getId()); - menuList[num++] = newMenu; - } - client.setMenuEntries(menuList); + client.createMenuEntry(-1) + .setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET) + .setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (e.getOption().equals(MENU_SET)) + { + setTag(itemId, groupName); + } + else + { + unsetTag(itemId); + } + }) + // TODO: remove + .add(client); + } } } @@ -270,15 +241,27 @@ public class InventoryTagsPlugin extends Plugin removeInventoryMenuOptions(); if (editorMode) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE, this::save); } else { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE, this::configure); } } + + private void save(MenuEntry menuEntry) + { + editorMode = false; + refreshInventoryMenuOptions(); + } + + private void configure(MenuEntry menuEntry) + { + editorMode = true; + refreshInventoryMenuOptions(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java index ea33e614f8..bea5de5af5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java @@ -90,7 +90,7 @@ class ItemPricesOverlay extends Overlay } final MenuEntry menuEntry = menuEntries[last]; - final MenuAction action = MenuAction.of(menuEntry.getType()); + final MenuAction action = menuEntry.getType(); final int widgetId = menuEntry.getParam1(); final int groupId = WidgetInfo.TO_GROUP(widgetId); final boolean isAlching = menuEntry.getOption().equals("Cast") && menuEntry.getTarget().contains("High Level Alchemy"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 6a457ce2b7..a06ad3cbf7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -56,7 +56,6 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.PostItemComposition; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; @@ -75,7 +74,6 @@ import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfi import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.MorytaniaLegsMode; import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.RadasBlessingMode; import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "Menu Entry Swapper", @@ -516,24 +514,6 @@ public class MenuEntrySwapperPlugin extends Plugin clientThread.invoke(this::resetItemCompositionCache); } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - String option = event.getMenuOption(); - String target = Text.removeTags(event.getMenuTarget()); - if ((option.equals(CONFIGURE) || option.equals(SAVE)) && (target.equals(LEFT_CLICK_MENU_TARGET) || target.equals(SHIFT_CLICK_MENU_TARGET))) - { - configuringShiftClick = option.equals(CONFIGURE) && target.equals(SHIFT_CLICK_MENU_TARGET); - configuringLeftClick = option.equals(CONFIGURE) && target.equals(LEFT_CLICK_MENU_TARGET); - rebuildCustomizationMenus(); - } - } - } - @Subscribe public void onMenuOpened(MenuOpened event) { @@ -601,11 +581,11 @@ public class MenuEntrySwapperPlugin extends Plugin for (MenuEntry entry : entries) { - final MenuAction menuAction = MenuAction.of(entry.getType()); + final MenuAction menuAction = entry.getType(); if (ITEM_MENU_TYPES.contains(menuAction) && entry.getIdentifier() == itemId) { - entry.setType(MenuAction.RUNELITE.getId()); + entry.setType(MenuAction.RUNELITE); if (activeAction == menuAction) { @@ -614,13 +594,13 @@ public class MenuEntrySwapperPlugin extends Plugin } } - final MenuEntry resetShiftClickEntry = new MenuEntry(); - resetShiftClickEntry.setOption(RESET); - resetShiftClickEntry.setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET); - resetShiftClickEntry.setIdentifier(itemId); - resetShiftClickEntry.setParam1(widgetId); - resetShiftClickEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(ArrayUtils.addAll(entries, resetShiftClickEntry)); + client.createMenuEntry(-1) + .setOption(RESET) + .setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET) + .setType(MenuAction.RUNELITE) + .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)) + // TODO: remove + .add(client); } @Subscribe @@ -646,8 +626,8 @@ public class MenuEntrySwapperPlugin extends Plugin final int opId = isDepositBoxPlayerInventory ? shiftDepositMode.getIdentifierDepositBox() : isChambersOfXericStorageUnitPlayerInventory ? shiftDepositMode.getIdentifierChambersStorageUnit() : shiftDepositMode.getIdentifier(); - final int actionId = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY.getId() : MenuAction.CC_OP.getId(); - bankModeSwap(actionId, opId); + final MenuAction action = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY : MenuAction.CC_OP; + bankModeSwap(action, opId); } // Swap to shift-click withdraw behavior @@ -657,22 +637,23 @@ public class MenuEntrySwapperPlugin extends Plugin && menuEntryAdded.getOption().startsWith("Withdraw")) { ShiftWithdrawMode shiftWithdrawMode = config.bankWithdrawShiftClick(); - final int actionId, opId; + final MenuAction action; + final int opId; if (widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_PRIVATE_GROUP_ID || widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_SHARED_GROUP_ID) { - actionId = MenuAction.CC_OP.getId(); + action = MenuAction.CC_OP; opId = shiftWithdrawMode.getIdentifierChambersStorageUnit(); } else { - actionId = shiftWithdrawMode.getMenuAction().getId(); + action = shiftWithdrawMode.getMenuAction(); opId = shiftWithdrawMode.getIdentifier(); } - bankModeSwap(actionId, opId); + bankModeSwap(action, opId); } } - private void bankModeSwap(int entryTypeId, int entryIdentifier) + private void bankModeSwap(MenuAction entryType, int entryIdentifier) { MenuEntry[] menuEntries = client.getMenuEntries(); @@ -680,10 +661,10 @@ public class MenuEntrySwapperPlugin extends Plugin { MenuEntry entry = menuEntries[i]; - if (entry.getType() == entryTypeId && entry.getIdentifier() == entryIdentifier) + if (entry.getType() == entryType && entry.getIdentifier() == entryIdentifier) { // Raise the priority of the op so it doesn't get sorted later - entry.setType(MenuAction.CC_OP.getId()); + entry.setType(MenuAction.CC_OP); menuEntries[i] = menuEntries[menuEntries.length - 1]; menuEntries[menuEntries.length - 1] = entry; @@ -713,17 +694,6 @@ public class MenuEntrySwapperPlugin extends Plugin String target = event.getMenuTarget(); ItemComposition itemComposition = itemManager.getItemComposition(itemId); - if (option.equals(RESET) && target.equals(SHIFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(true, itemId); - return; - } - if (option.equals(RESET) && target.equals(LEFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(false, itemId); - return; - } - if (!itemComposition.getName().equals(Text.removeTags(target))) { return; @@ -751,7 +721,7 @@ public class MenuEntrySwapperPlugin extends Plugin private void swapMenuEntry(MenuEntry[] menuEntries, int index, MenuEntry menuEntry) { final int eventId = menuEntry.getIdentifier(); - final MenuAction menuAction = MenuAction.of(menuEntry.getType()); + final MenuAction menuAction = menuEntry.getType(); final String option = Text.removeTags(menuEntry.getOption()).toLowerCase(); final String target = Text.removeTags(menuEntry.getTarget()).toLowerCase(); final NPC hintArrowNpc = client.getHintArrowNpc(); @@ -978,31 +948,31 @@ public class MenuEntrySwapperPlugin extends Plugin removeCusomizationMenus(); if (configuringLeftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC, this::save); } else if (configuringShiftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC, this::save); } else { // Left click if (config.leftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC, this::configure); } // Shift click if (config.shiftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC, this::configure); } } } @@ -1011,4 +981,18 @@ public class MenuEntrySwapperPlugin extends Plugin { return client.isKeyPressed(KeyCode.KC_SHIFT); } + + private void save(MenuEntry menuEntry) + { + configuringLeftClick = configuringShiftClick = false; + rebuildCustomizationMenus(); + } + + private void configure(MenuEntry menuEntry) + { + String target = Text.removeTags(menuEntry.getTarget()); + configuringShiftClick = target.equals(SHIFT_CLICK_MENU_TARGET); + configuringLeftClick = target.equals(LEFT_CLICK_MENU_TARGET); + rebuildCustomizationMenus(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java index 1e56b743eb..f9355f0aa5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java @@ -108,7 +108,7 @@ class MouseHighlightOverlay extends Overlay MenuEntry menuEntry = menuEntries[last]; String target = menuEntry.getTarget(); String option = menuEntry.getOption(); - MenuAction type = MenuAction.of(menuEntry.getType()); + MenuAction type = menuEntry.getType(); if (type == MenuAction.RUNELITE_OVERLAY || type == MenuAction.CC_OP_LOW_PRIORITY) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index 679f773913..4ad21005b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -91,13 +91,6 @@ class NightmareZoneOverlay extends OverlayPanel return null; } - Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); - - if (nmzWidget != null) - { - nmzWidget.setHidden(true); - } - renderAbsorptionCounter(); final int currentPoints = client.getVar(Varbits.NMZ_POINTS); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java index ccd2a775c0..f95e2ab8a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java @@ -33,6 +33,7 @@ import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Varbits; +import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ChatMessage; import net.runelite.client.events.ConfigChanged; import net.runelite.api.events.GameTick; @@ -121,6 +122,21 @@ public class NightmareZonePlugin extends Plugin return configManager.getConfig(NightmareZoneConfig.class); } + @Subscribe + public void onBeforeRender(BeforeRender beforeRender) + { + if (!isInNightmareZone() || !config.moveOverlay()) + { + return; + } + + Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); + if (nmzWidget != null) + { + nmzWidget.setHidden(true); + } + } + @Subscribe public void onGameTick(GameTick event) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 7efaa91640..ff775e7129 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -31,7 +31,6 @@ import com.google.inject.Provides; import java.awt.Color; import java.time.Instant; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -57,7 +56,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.GraphicsObjectCreated; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; @@ -271,7 +269,6 @@ public class NpcIndicatorsPlugin extends Plugin final MenuEntry menuEntry = menuEntries[menuEntries.length - 1]; final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color); menuEntry.setTarget(target); - client.setMenuEntries(menuEntries); } } else if (menuAction == MenuAction.EXAMINE_NPC && client.isKeyPressed(KeyCode.KC_SHIFT)) @@ -291,48 +288,33 @@ public class NpcIndicatorsPlugin extends Plugin .filter(highlight -> !highlight.equalsIgnoreCase(npcName)) .anyMatch(highlight -> WildcardMatcher.matches(highlight, npcName)); - MenuEntry[] menuEntries = client.getMenuEntries(); - // Only add Untag-All option to npcs not highlighted by a wildcard entry, because untag-all will not remove wildcards if (!matchesList) { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 2); - final MenuEntry tagAllEntry = menuEntries[menuEntries.length - 2] = new MenuEntry(); - tagAllEntry.setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL); - tagAllEntry.setTarget(event.getTarget()); - tagAllEntry.setParam0(event.getActionParam0()); - tagAllEntry.setParam1(event.getParam1()); - tagAllEntry.setIdentifier(event.getIdentifier()); - tagAllEntry.setType(MenuAction.RUNELITE.getId()); - } - else - { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + client.createMenuEntry(-1) + .setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag) + // TODO: remove + .add(client); } - final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - tagEntry.setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG); - tagEntry.setTarget(event.getTarget()); - tagEntry.setParam0(event.getActionParam0()); - tagEntry.setParam1(event.getParam1()); - tagEntry.setIdentifier(event.getIdentifier()); - tagEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag) + // TODO: remove + .add(client); } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked click) + private void tag(MenuEntry entry) { - if (click.getMenuAction() != MenuAction.RUNELITE || - !(click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG) || - click.getMenuOption().equals(TAG_ALL) || click.getMenuOption().equals(UNTAG_ALL))) - { - return; - } - - final int id = click.getId(); + final int id = entry.getIdentifier(); final NPC[] cachedNPCs = client.getCachedNPCs(); final NPC npc = cachedNPCs[id]; @@ -341,7 +323,7 @@ public class NpcIndicatorsPlugin extends Plugin return; } - if (click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG)) + if (entry.getOption().equals(TAG) || entry.getOption().equals(UNTAG)) { final boolean removed = npcTags.remove(id); @@ -371,8 +353,6 @@ public class NpcIndicatorsPlugin extends Plugin // this trips a config change which triggers the overlay rebuild updateNpcsToHighlight(name); } - - click.consume(); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java index 403a19fe04..2985ca8d12 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java @@ -31,7 +31,6 @@ import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.awt.Color; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -65,7 +64,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; @@ -222,7 +220,7 @@ public class ObjectIndicatorsPlugin extends Plugin return; } - final Tile tile = client.getScene().getTiles()[client.getPlane()][event.getActionParam0()][event.getParam1()]; + final Tile tile = client.getScene().getTiles()[client.getPlane()][event.getActionParam0()][event.getActionParam1()]; final TileObject tileObject = findTileObject(tile, event.getIdentifier()); if (tileObject == null) @@ -230,35 +228,28 @@ public class ObjectIndicatorsPlugin extends Plugin return; } - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK); - menuEntry.setTarget(event.getTarget()); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(event.getParam1()); - menuEntry.setIdentifier(event.getIdentifier()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::markObject) + // TODO: remove + .add(client); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void markObject(MenuEntry entry) { - if (event.getMenuAction() != MenuAction.RUNELITE - || !(event.getMenuOption().equals(MARK) || event.getMenuOption().equals(UNMARK))) - { - return; - } - Scene scene = client.getScene(); Tile[][][] tiles = scene.getTiles(); - final int x = event.getParam0(); - final int y = event.getParam1(); + final int x = entry.getParam0(); + final int y = entry.getParam1(); final int z = client.getPlane(); final Tile tile = tiles[z][x][y]; - TileObject object = findTileObject(tile, event.getId()); + TileObject object = findTileObject(tile, entry.getIdentifier()); if (object == null) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index 4d58b924d1..330f4dfb42 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -184,7 +184,6 @@ public class OpponentInfoPlugin extends Plugin { MenuEntry[] menuEntries = client.getMenuEntries(); menuEntries[menuEntries.length - 1].setTarget("*" + menuEntries[menuEntries.length - 1].getTarget()); - client.setMenuEntries(menuEntries); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java index 5d38da1b3d..4d484f4cdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java @@ -99,4 +99,23 @@ public interface PartyConfig extends Config { return false; } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + default String previousPartyId() + { + return ""; + } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + void setPreviousPartyId(String id); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java index 3c3c1bba95..52d4799e95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java @@ -26,6 +26,12 @@ package net.runelite.client.plugins.party; import com.google.inject.Inject; import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -55,6 +61,9 @@ class PartyPanel extends PluginPanel private final Map memberBoxes = new HashMap<>(); private final JButton startButton = new JButton(); + private final JButton joinPartyButton = new JButton(); + private final JButton rejoinPartyButton = new JButton(); + private final JButton copyPartyIdButton = new JButton(); private final PluginErrorPanel noPartyPanel = new PluginErrorPanel(); private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel(); @@ -79,10 +88,29 @@ class PartyPanel extends PluginPanel final JPanel topPanel = new JPanel(); - topPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); - topPanel.setLayout(new BorderLayout()); + topPanel.setBorder(new EmptyBorder(0, 0, 4, 0)); + topPanel.setLayout(new GridBagLayout()); - topPanel.add(startButton, BorderLayout.CENTER); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(0, 2, 4, 2); + + c.gridx = 0; + c.gridy = 0; + topPanel.add(startButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(joinPartyButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(copyPartyIdButton, c); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 2; + topPanel.add(rejoinPartyButton, c); layoutPanel.add(topPanel); layoutPanel.add(requestBoxPanel); @@ -91,7 +119,14 @@ class PartyPanel extends PluginPanel startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); startButton.setFocusable(false); - topPanel.add(startButton); + joinPartyButton.setText("Join party"); + joinPartyButton.setFocusable(false); + + rejoinPartyButton.setText("Join previous party"); + rejoinPartyButton.setFocusable(false); + + copyPartyIdButton.setText("Copy party id"); + copyPartyIdButton.setFocusable(false); startButton.addActionListener(e -> { @@ -115,6 +150,63 @@ class PartyPanel extends PluginPanel } }); + joinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + String s = (String) JOptionPane.showInputDialog( + joinPartyButton, + "Please enter the party id:", + "Party Id", + JOptionPane.PLAIN_MESSAGE, + null, + null, + ""); + + if (s == null) + { + return; + } + + try + { + party.changeParty(UUID.fromString(s)); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(joinPartyButton, "You have entered an invalid party id.", "Invalid Party Id", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + rejoinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + try + { + party.changeParty(UUID.fromString(config.previousPartyId())); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(rejoinPartyButton, + "Failed to join your previous party, create a new party or join a new one.", + "Failed to Join Party", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + copyPartyIdButton.addActionListener(e -> + { + if (party.isInParty()) + { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(String.valueOf(party.getPartyId())), null); + } + }); + noPartyPanel.setContent("Not in a party", "Create a party to begin."); partyEmptyPanel.setContent("Party created", "You can now invite friends!"); @@ -127,6 +219,9 @@ class PartyPanel extends PluginPanel remove(partyEmptyPanel); startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); + joinPartyButton.setVisible(!party.isInParty()); + rejoinPartyButton.setVisible(!party.isInParty()); + copyPartyIdButton.setVisible(party.isInParty()); if (!party.isInParty()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index e9287210a8..ae13a4a22f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -66,8 +66,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.discord.events.DiscordJoinRequest; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; import net.runelite.client.plugins.Plugin; @@ -585,6 +585,11 @@ public class PartyPlugin extends Plugin pendingTilePings.clear(); worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); + if (event.getPartyId() != null) + { + config.setPreviousPartyId(String.valueOf(event.getPartyId())); + } + SwingUtilities.invokeLater(() -> { panel.removeAllMembers(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java index df72925bb8..eaa841a620 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java @@ -31,8 +31,8 @@ import lombok.Value; import net.runelite.api.Client; import net.runelite.api.FriendsChatRank; import static net.runelite.api.FriendsChatRank.UNRANKED; +import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; -import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; @@ -118,29 +118,23 @@ public class PlayerIndicatorsPlugin extends Plugin } MenuEntry[] menuEntries = client.getMenuEntries(); - boolean modified = false; for (MenuEntry entry : menuEntries) { - int type = entry.getType(); + MenuAction type = entry.getType(); - if (type >= MENU_ACTION_DEPRIORITIZE_OFFSET) - { - type -= MENU_ACTION_DEPRIORITIZE_OFFSET; - } - - if (type == WALK.getId() - || type == SPELL_CAST_ON_PLAYER.getId() - || type == ITEM_USE_ON_PLAYER.getId() - || type == PLAYER_FIRST_OPTION.getId() - || type == PLAYER_SECOND_OPTION.getId() - || type == PLAYER_THIRD_OPTION.getId() - || type == PLAYER_FOURTH_OPTION.getId() - || type == PLAYER_FIFTH_OPTION.getId() - || type == PLAYER_SIXTH_OPTION.getId() - || type == PLAYER_SEVENTH_OPTION.getId() - || type == PLAYER_EIGTH_OPTION.getId() - || type == RUNELITE_PLAYER.getId()) + if (type == WALK + || type == SPELL_CAST_ON_PLAYER + || type == ITEM_USE_ON_PLAYER + || type == PLAYER_FIRST_OPTION + || type == PLAYER_SECOND_OPTION + || type == PLAYER_THIRD_OPTION + || type == PLAYER_FOURTH_OPTION + || type == PLAYER_FIFTH_OPTION + || type == PLAYER_SIXTH_OPTION + || type == PLAYER_SEVENTH_OPTION + || type == PLAYER_EIGTH_OPTION + || type == RUNELITE_PLAYER) { Player[] players = client.getCachedPlayers(); Player player = null; @@ -149,7 +143,7 @@ public class PlayerIndicatorsPlugin extends Plugin // 'Walk here' identifiers are offset by 1 because the default // identifier for this option is 0, which is also a player index. - if (type == WALK.getId()) + if (type == WALK) { identifier--; } @@ -175,14 +169,8 @@ public class PlayerIndicatorsPlugin extends Plugin String newTarget = decorateTarget(oldTarget, decorations); entry.setTarget(newTarget); - modified = true; } } - - if (modified) - { - client.setMenuEntries(menuEntries); - } } private Decorations getDecorations(Player player) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java index 2e8297c83a..9761c5935e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java @@ -70,7 +70,7 @@ import okhttp3.HttpUrl; ) public class WikiPlugin extends Plugin { - static final HttpUrl WIKI_BASE = HttpUrl.parse("https://oldschool.runescape.wiki"); + static final HttpUrl WIKI_BASE = HttpUrl.get("https://oldschool.runescape.wiki"); static final HttpUrl WIKI_API = WIKI_BASE.newBuilder().addPathSegments("api.php").build(); static final String UTM_SORUCE_KEY = "utm_source"; static final String UTM_SORUCE_VALUE = "runelite"; @@ -335,20 +335,6 @@ public class WikiPlugin extends Plugin LinkBrowser.browse(url.toString()); return; } - - if (ev.getMenuAction() == MenuAction.RUNELITE) - { - switch (ev.getMenuOption()) - { - case MENUOP_WIKI: - LinkBrowser.browse(WIKI_BASE.newBuilder() - .addPathSegment("w") - .addPathSegment(Text.removeTags(ev.getMenuTarget())) - .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) - .build().toString()); - - } - } } private void openSearchInput() @@ -371,18 +357,18 @@ public class WikiPlugin extends Plugin public void onMenuEntryAdded(MenuEntryAdded event) { int widgetIndex = event.getActionParam0(); - int widgetID = event.getParam1(); - MenuEntry[] menuEntries = client.getMenuEntries(); + int widgetID = event.getActionParam1(); if (wikiSelected && event.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) { + MenuEntry[] menuEntries = client.getMenuEntries(); Widget w = getWidget(widgetID, widgetIndex); if (w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1) { for (int ourEntry = menuEntries.length - 1;ourEntry >= 0; ourEntry--) { MenuEntry entry = menuEntries[ourEntry]; - if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET) { int id = itemManager.canonicalize(w.getItemId()); String name = itemManager.getItemComposition(id).getName(); @@ -390,7 +376,6 @@ public class WikiPlugin extends Plugin break; } } - client.setMenuEntries(menuEntries); } else { @@ -400,7 +385,7 @@ public class WikiPlugin extends Plugin MenuEntry[] oldEntries = menuEntries; menuEntries = Arrays.copyOf(menuEntries, menuEntries.length - 1); for (int ourEntry = oldEntries.length - 1; - ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId(); + ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET; ourEntry--) { menuEntries[ourEntry - 1] = oldEntries[ourEntry]; @@ -425,16 +410,17 @@ public class WikiPlugin extends Plugin return; } - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(action.replace("View ", "").replace(" guide", "")); - menuEntry.setOption(MENUOP_WIKI); - menuEntry.setParam0(widgetIndex); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setTarget(action.replace("View ", "").replace(" guide", "")) + .setOption(MENUOP_WIKI) + .setType(MenuAction.RUNELITE) + .onClick(ev -> LinkBrowser.browse(WIKI_BASE.newBuilder() + .addPathSegment("w") + .addPathSegment(Text.removeTags(ev.getTarget())) + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) + .build().toString())) + // TODO: remove + .add(client); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java index f6cc53254f..f87bcaeef3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java @@ -53,26 +53,27 @@ import static net.runelite.api.ObjectID.WILLOW_10833; import static net.runelite.api.ObjectID.YEW; import static net.runelite.api.NullObjectID.NULL_10823; import static net.runelite.api.ObjectID.YEW_36683; +import static net.runelite.client.util.RSTimeUnit.GAME_TICKS; @Getter enum Tree { REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280), - OAK_TREE(Duration.ofMillis(8500), OAK_TREE_4540, OAK_10820), - WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), - MAPLE_TREE(Duration.ofSeconds(35), MAPLE_TREE_10832, MAPLE_TREE_36681) + OAK_TREE(Duration.of(14, GAME_TICKS), OAK_TREE_4540, OAK_10820), + WILLOW_TREE(Duration.of(14, GAME_TICKS), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), + MAPLE_TREE(Duration.of(59, GAME_TICKS), MAPLE_TREE_10832, MAPLE_TREE_36681) { @Override Duration getRespawnTime(int region) { - return region == MISCELLANIA_REGION ? Duration.ofMillis(8500) : super.respawnTime; + return region == MISCELLANIA_REGION ? Duration.of(14, GAME_TICKS) : super.respawnTime; } }, - TEAK_TREE(Duration.ofMillis(8500), TEAK, TEAK_36686), - MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688), - YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683), - MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835), - REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670); + TEAK_TREE(Duration.of(15, GAME_TICKS), TEAK, TEAK_36686), + MAHOGANY_TREE(Duration.of(14, GAME_TICKS), MAHOGANY, MAHOGANY_36688), + YEW_TREE(Duration.of(99, GAME_TICKS), YEW, NULL_10823, YEW_36683), + MAGIC_TREE(Duration.of(199, GAME_TICKS), MAGIC_TREE_10834, NULL_10835), + REDWOOD(Duration.of(199, GAME_TICKS), ObjectID.REDWOOD, REDWOOD_29670); @Nullable private final Duration respawnTime; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index dcb8d5e560..06a0fcb5a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -28,7 +28,6 @@ package net.runelite.client.plugins.worldhopper; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.Instant; @@ -53,7 +52,6 @@ import net.runelite.api.FriendsChatManager; import net.runelite.api.FriendsChatMember; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NameableContainer; import net.runelite.api.Varbits; import net.runelite.api.clan.ClanChannel; @@ -62,7 +60,6 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WorldListLoad; import net.runelite.api.widgets.WidgetInfo; @@ -91,7 +88,6 @@ import net.runelite.client.util.WorldUtil; import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldType; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "World Hopper", @@ -355,7 +351,7 @@ public class WorldHopperPlugin extends Plugin return; } - final int componentId = event.getParam1(); + final int componentId = event.getActionParam1(); int groupId = WidgetInfo.TO_GROUP(componentId); String option = event.getOption(); @@ -396,43 +392,21 @@ public class WorldHopperPlugin extends Plugin return; } - final MenuEntry hopTo = new MenuEntry(); - hopTo.setOption(HOP_TO); - hopTo.setTarget(event.getTarget()); - hopTo.setType(MenuAction.RUNELITE.getId()); - hopTo.setParam0(event.getActionParam0()); - hopTo.setParam1(event.getParam1()); + client.createMenuEntry(after ? -2 : -1) + .setOption(HOP_TO) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + ChatPlayer p = getChatPlayerFromName(e.getTarget()); - insertMenuEntry(hopTo, client.getMenuEntries(), after); - } - } - - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries, boolean after) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - - if (after) - { - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - } - - client.setMenuEntries(newMenu); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE || !event.getMenuOption().equals(HOP_TO)) - { - return; - } - - ChatPlayer player = getChatPlayerFromName(event.getMenuTarget()); - - if (player != null) - { - hop(player.getWorld()); + if (p != null) + { + hop(p.getWorld()); + } + }) + // TODO: remove + .add(client); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 026b8980ac..772d1f8c85 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -32,7 +32,6 @@ import com.google.inject.Binder; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.temporal.ChronoUnit; -import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Objects; @@ -45,7 +44,6 @@ import net.runelite.api.Client; import net.runelite.api.Experience; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NPC; import net.runelite.api.Player; import net.runelite.api.Skill; @@ -54,7 +52,6 @@ import net.runelite.api.WorldType; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.StatChanged; import net.runelite.api.widgets.WidgetID; @@ -508,7 +505,7 @@ public class XpTrackerPlugin extends Plugin @Subscribe public void onMenuEntryAdded(final MenuEntryAdded event) { - int widgetID = event.getParam1(); + int widgetID = event.getActionParam1(); if (TO_GROUP(widgetID) != WidgetID.SKILLS_GROUP_ID || !event.getOption().startsWith("View") @@ -521,48 +518,23 @@ public class XpTrackerPlugin extends Plugin final String skillText = event.getOption().split(" ")[1]; final Skill skill = Skill.valueOf(Text.removeTags(skillText).toUpperCase()); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(skillText); - menuEntry.setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() - || TO_GROUP(event.getParam1()) != WidgetID.SKILLS_GROUP_ID) - { - return; - } - - final Skill skill; - try - { - skill = Skill.valueOf(Text.removeTags(event.getMenuTarget()).toUpperCase()); - } - catch (IllegalArgumentException ex) - { - log.debug(null, ex); - return; - } - - switch (event.getMenuOption()) - { - case MENUOP_ADD_CANVAS_TRACKER: - addOverlay(skill); - break; - case MENUOP_REMOVE_CANVAS_TRACKER: - removeOverlay(skill); - break; - } + client.createMenuEntry(-1) + .setTarget(skillText) + .setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (hasOverlay(skill)) + { + removeOverlay(skill); + } + else + { + addOverlay(skill); + } + }) + // TODO: remove + .add(client); } XpStateSingle getSkillState(Skill skill) diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index aca456df93..7b9d3f6091 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -78,7 +78,7 @@ import okhttp3.Response; public class ClientLoader implements Supplier { private static final String INJECTED_CLIENT_NAME = "/injected-client.oprs"; - private static final int NUM_ATTEMPTS = 6; + private static final int NUM_ATTEMPTS = 0; private static File LOCK_FILE = new File(RuneLite.CACHE_DIR, "cache.lock"); private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache"); private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache"); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java index bea3f9d280..31d428ceed 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java @@ -40,17 +40,13 @@ import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; -import net.runelite.api.MenuAction; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PluginChanged; /** @@ -108,14 +104,12 @@ public class OverlayManager private ArrayListMultimap overlayMap = ArrayListMultimap.create(); private final ConfigManager configManager; - private final EventBus eventBus; private final RuneLiteConfig runeLiteConfig; @Inject - private OverlayManager(final ConfigManager configManager, final EventBus eventBus, final RuneLiteConfig runeLiteConfig) + private OverlayManager(final ConfigManager configManager, final RuneLiteConfig runeLiteConfig) { this.configManager = configManager; - this.eventBus = eventBus; this.runeLiteConfig = runeLiteConfig; } @@ -137,32 +131,6 @@ public class OverlayManager rebuildOverlayLayers(); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - MenuAction menuAction = event.getMenuAction(); - if (menuAction != MenuAction.RUNELITE_OVERLAY && menuAction != MenuAction.RUNELITE_OVERLAY_CONFIG) - { - return; - } - - event.consume(); - - Overlay overlay = overlays.get(event.getId()); - if (overlay != null) - { - List menuEntries = overlay.getMenuEntries(); - OverlayMenuEntry overlayMenuEntry = menuEntries.stream() - .filter(me -> me.getOption().equals(event.getMenuOption())) - .findAny() - .orElse(null); - if (overlayMenuEntry != null) - { - eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay)); - } - } - } - /** * Gets all of the overlays on a layer sorted by priority and position * diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index c658c6944a..535587d409 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -49,7 +49,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; -import net.runelite.api.MenuEntry; import net.runelite.api.Varbits; import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ClientTick; @@ -60,6 +59,7 @@ import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseAdapter; @@ -93,6 +93,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private final TooltipManager tooltipManager; private final RuneLiteConfig runeLiteConfig; private final ClientUI clientUI; + private final EventBus eventBus; // Overlay movement variables private final Point overlayOffset = new Point(); @@ -104,7 +105,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private boolean inOverlayResizingMode; private boolean inOverlayDraggingMode; private boolean startedMovingOverlay; - private MenuEntry[] menuEntries; + private Overlay hoveredOverlay; // for building menu entries // Overlay state validation private Rectangle viewportBounds; @@ -133,6 +134,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener this.runeLiteConfig = runeLiteConfig; this.clientUI = clientUI; this.tooltipManager = tooltipManager; + this.eventBus = eventBus; keyManager.registerKeyListener(this); mouseManager.registerMouseListener(this); eventBus.register(this); @@ -149,14 +151,15 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener resetOverlayManagementMode(); } - menuEntries = null; + hoveredOverlay = null; } } @Subscribe protected void onClientTick(ClientTick t) { - if (menuEntries == null) + final Overlay overlay = hoveredOverlay; + if (overlay == null || client.isMenuOpen()) { return; } @@ -167,24 +170,31 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener return; } - if (client.isMenuOpen()) + List menuEntries = overlay.getMenuEntries(); + if (menuEntries.isEmpty()) { return; } - MenuEntry[] clientMenuEntries = client.getMenuEntries(); - MenuEntry[] newEntries = new MenuEntry[clientMenuEntries.length + menuEntries.length]; + // Add in reverse order so they display correctly in the right-click menu + for (int i = menuEntries.size() - 1; i >= 0; --i) + { + OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - newEntries[0] = clientMenuEntries[0]; // Keep cancel at 0 - System.arraycopy(menuEntries, 0, newEntries, 1, menuEntries.length); // Add overlay menu entries - System.arraycopy(clientMenuEntries, 1, newEntries, menuEntries.length + 1, clientMenuEntries.length - 1); // Add remaining menu entries - client.setMenuEntries(newEntries); + client.createMenuEntry(-1) + .setOption(overlayMenuEntry.getOption()) + .setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)) + .setType(overlayMenuEntry.getMenuAction()) + .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))) + // TODO: remove + .add(client); + } } @Subscribe public void onBeforeRender(BeforeRender event) { - menuEntries = null; + hoveredOverlay = null; if (focusedOverlay == null && prevFocusedOverlay != null) { @@ -366,10 +376,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener if (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse)) { - if (menuEntries == null) - { - menuEntries = createRightClickMenuEntries(overlay); - } + hoveredOverlay = overlay; if (inOverlayManagingMode) { @@ -940,33 +947,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE)); } - private MenuEntry[] createRightClickMenuEntries(Overlay overlay) - { - List menuEntries = overlay.getMenuEntries(); - if (menuEntries.isEmpty()) - { - return null; - } - - final MenuEntry[] entries = new MenuEntry[menuEntries.size()]; - - // Add in reverse order so they display correctly in the right-click menu - for (int i = menuEntries.size() - 1; i >= 0; --i) - { - OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - - final MenuEntry entry = new MenuEntry(); - entry.setOption(overlayMenuEntry.getOption()); - entry.setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)); - entry.setType(overlayMenuEntry.getMenuAction().getId()); - entry.setIdentifier(overlayManager.getOverlays().indexOf(overlay)); // overlay id - - entries[i] = entry; - } - - return entries; - } - /** * Adjust the given overlay position to be within its parent's bounds. * diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java index e3528433cb..3047086dda 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java @@ -564,11 +564,11 @@ public class ModelOutlineRenderer */ private void simulateModelRasterizationForOutline(Model model) { - final int triangleCount = model.getTrianglesCount(); - final int[] indices1 = model.getTrianglesX(); - final int[] indices2 = model.getTrianglesY(); - final int[] indices3 = model.getTrianglesZ(); - final byte[] triangleTransparencies = model.getTriangleTransparencies(); + final int triangleCount = model.getFaceCount(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); + final byte[] triangleTransparencies = model.getFaceTransparencies(); for (int i = 0; i < triangleCount; i++) { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 2f2beb0c62..4ec9d466f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -24,6 +24,7 @@ */ package net.runelite.client.ui.overlay.worldmap; +import com.google.common.base.MoreObjects; import com.google.common.base.Splitter; import com.google.common.base.Strings; import java.awt.Dimension; @@ -32,23 +33,18 @@ import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Point; import net.runelite.api.RenderOverview; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.overlay.Overlay; @@ -73,7 +69,7 @@ public class WorldMapOverlay extends Overlay private final WorldMapPointManager worldMapPointManager; private final Client client; - private final List mapMenuEntries = new ArrayList<>(); + private WorldMapPoint hoveredPoint; @Inject private WorldMapOverlay( @@ -107,19 +103,20 @@ public class WorldMapOverlay extends Overlay bottomBar.setOnTimerListener((JavaScriptCallback) ev -> { - if (client.isMenuOpen() || mapMenuEntries.isEmpty()) + WorldMapPoint worldPoint = hoveredPoint; + if (client.isMenuOpen() || worldPoint == null) { return; } - MenuEntry[] entries = client.getMenuEntries(); - int end = entries.length; - entries = Arrays.copyOf(entries, end + mapMenuEntries.size()); - for (int i = 0; i < mapMenuEntries.size(); i++) - { - entries[end + i] = mapMenuEntries.get(i); - } - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)) + .setOption(FOCUS_ON) + .setType(MenuAction.RUNELITE) + .onClick(m -> client.getRenderOverview().setWorldMapPositionTarget( + MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))) + // TODO: remove + .add(client); }); bottomBar.setHasListener(true); @@ -135,7 +132,7 @@ public class WorldMapOverlay extends Overlay mousePos = null; } - mapMenuEntries.clear(); + hoveredPoint = null; WorldMapPoint tooltipPoint = null; @@ -227,19 +224,7 @@ public class WorldMapOverlay extends Overlay if (worldPoint.isJumpOnClick()) { assert worldPoint.getName() != null; - - WorldPoint target = worldPoint.getTarget(); - if (target == null) - { - target = worldPoint.getWorldPoint(); - } - - MenuEntry entry = new MenuEntry(); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setOption(FOCUS_ON); - entry.setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)); - entry.setIdentifier(target.getPlane() << 28 | target.getX() << 14 | target.getY()); - mapMenuEntries.add(entry); + hoveredPoint = worldPoint; } } } @@ -259,21 +244,6 @@ public class WorldMapOverlay extends Overlay return null; } - @Subscribe - private void onMenuOptionClicked(MenuOptionClicked ev) - { - if (ev.getMenuAction() == MenuAction.RUNELITE && FOCUS_ON.equals(ev.getMenuOption())) - { - int pxy = ev.getId(); - WorldPoint wp = new WorldPoint( - pxy >> 14 & 0x3fff, - pxy & 0x3fff, - pxy >> 28); - - client.getRenderOverview().setWorldMapPositionTarget(wp); - } - } - /** * Get the screen coordinates for a WorldPoint on the world map * diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png new file mode 100644 index 0000000000..62bb05ace9 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png new file mode 100644 index 0000000000..eaaa147d0f Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png differ diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.hash b/runelite-client/src/main/scripts/GeExamineInfoText.hash new file mode 100644 index 0000000000..162121bd78 --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.hash @@ -0,0 +1 @@ +157D0FE4248A0C0CAC825733A8DE7B0FA5A93451A9FCE3A4B1D8BFD54038B970 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm new file mode 100644 index 0000000000..20c53ea902 --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm @@ -0,0 +1,167 @@ +; script used to position the ge buy offer "Convenience fee" info icon as well as set the +; examine text +; component0 = text component for the examine text +; component1 = parent of the info icon +; string0 = item examine +; string1 = Convenience fee text +.id 5730 +.int_stack_count 2 +.string_stack_count 2 +.int_var_count 5 +.string_var_count 3 + sconst "" + sstore 2 + iconst 0 + istore 2 + iconst 0 + istore 3 + iconst 0 + istore 4 + sload 1 + string_length + iconst 0 + if_icmpgt LABEL13 + jump LABEL118 +LABEL13: + sload 0 + sconst "
" + sconst "
" + sload 1 + join_string 4 + iload 0 + if_getwidth + istore 2 + sstore 2 + + sload 0 ; examine + sload 1 ; Convenience fee + sload 2 ; "<$string0>

<$string1>" + sconst "geExamineText" + runelite_callback + sstore 2 ; final text + pop_string ; Convenience fee + pop_string ; examine + + iload 0 + if_getx + sload 1 + iload 2 + iconst 494 + parawidth + add + iconst 5 + add + iload 0 + if_gety + sload 2 + iload 2 + iconst 494 + paraheight + iconst 15 + multiply + add + iconst 2 + add + istore 4 + istore 3 + iload 3 + iload 1 + if_getwidth + iconst 15 + sub + iconst 2 + div + sub + iload 4 + iconst 11 + iload 1 + if_getheight + iconst 2 + div + add + sub + istore 4 + istore 3 + iload 3 + iload 4 + iconst 0 + iconst 0 + iload 1 + if_setposition + iconst 0 + iload 1 + if_sethide + iload 1 + cc_deleteall + iload 1 + iconst 5 + iconst 0 + cc_create + iconst 15 + iconst 15 + iconst 0 + iconst 0 + cc_setsize + iconst 0 + iconst 0 + iconst 1 + iconst 1 + cc_setposition + iconst 1094 + cc_setgraphic + iconst 50 + cc_settrans + iconst 244 + iconst -2147483645 + cc_getid + iconst 0 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouserepeat + iconst 244 + iconst -2147483645 + cc_getid + iconst 50 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouseleave + iconst 489 + iconst -2147483644 + iconst 2 + sconst "ii" + iload 1 + if_setonop + iconst 1 + sconst "Info" + iload 1 + if_setop + jump LABEL139 +LABEL118: + sload 0 + sstore 2 + iconst 1 + iload 1 + if_sethide + iload 1 + cc_deleteall + iconst -1 + sconst "" + iload 1 + if_setonmouserepeat + iconst -1 + sconst "" + iload 1 + if_setonmouseleave + iconst -1 + sconst "" + iload 1 + if_setonop + iload 1 + if_clearops +LABEL139: + sload 2 + iload 0 + if_settext + return diff --git a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java index 30ca3dfeda..cd33ded89b 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java @@ -24,9 +24,12 @@ */ package net.runelite.client.menus; +import com.google.common.collect.Lists; import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; @@ -38,24 +41,18 @@ import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.util.Text; import static org.junit.Assert.assertArrayEquals; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatchers; +import static org.mockito.ArgumentMatchers.anyInt; import org.mockito.Mock; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.class) public class MenuManagerTest { - private static final MenuEntry CANCEL = new MenuEntry(); - @Inject private MenuManager menuManager; @@ -63,14 +60,18 @@ public class MenuManagerTest @Bind private Client client; - private MenuEntry[] clientMenuEntries = {CANCEL}; + private final MenuEntry CANCEL = createMenuEntry("Cancel", "", MenuAction.CANCEL, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - @BeforeClass - public static void beforeClass() + private final List createdMenuEntries = new ArrayList<>(); + + private static MenuEntry createMenuEntry(String option, String target, MenuAction type, int param1) { - CANCEL.setOption("Cancel"); - CANCEL.setType(MenuAction.CANCEL.getId()); - CANCEL.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + MenuEntry menuEntry = new TestMenuEntry(); + menuEntry.setOption(option); + menuEntry.setTarget(target); + menuEntry.setType(type); + menuEntry.setParam1(param1); + return menuEntry; } @Before @@ -78,35 +79,25 @@ public class MenuManagerTest { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); - doAnswer((Answer) invocationOnMock -> - { - clientMenuEntries = invocationOnMock.getArgument(0, MenuEntry[].class); - return null; - }).when(client).setMenuEntries(ArgumentMatchers.any(MenuEntry[].class)); - when(client.getMenuEntries()).thenAnswer((Answer) invocationMock -> clientMenuEntries); + when(client.createMenuEntry(anyInt())) + .thenAnswer(a -> + { + MenuEntry e = new TestMenuEntry(); + createdMenuEntries.add(e); + return e; + }); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{CANCEL}); } @Test public void testManagedMenuOrder() { - final MenuEntry first = new MenuEntry(); - final MenuEntry second = new MenuEntry(); - final MenuEntry third = new MenuEntry(); - first.setOption("Test"); - first.setTarget("First Entry"); - first.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - first.setType(RUNELITE.getId()); - second.setOption("Test"); - second.setTarget("Second Entry"); - second.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - second.setType(RUNELITE.getId()); - third.setOption("Test"); - third.setTarget("Third Entry"); - third.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - third.setType(RUNELITE.getId()); - menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); + final MenuEntry first = createMenuEntry("Test", "First Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry second = createMenuEntry("Test", "Second Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry third = createMenuEntry("Test", "Third Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); menuManager.onMenuEntryAdded(new MenuEntryAdded( CANCEL.getOption(), @@ -116,12 +107,10 @@ public class MenuManagerTest CANCEL.getParam0(), CANCEL.getParam1())); - ArgumentCaptor captor = ArgumentCaptor.forClass(MenuEntry[].class); - verify(client, atLeastOnce()).setMenuEntries(captor.capture()); + verify(client, times(3)).createMenuEntry(anyInt()); - final MenuEntry[] resultMenuEntries = captor.getValue(); // Strip color tags from menu options before array comparison - for (MenuEntry resultEntry : resultMenuEntries) + for (MenuEntry resultEntry : createdMenuEntries) { final String resultTarget = resultEntry.getTarget(); if (resultTarget != null) @@ -130,6 +119,7 @@ public class MenuManagerTest } } - assertArrayEquals(new MenuEntry[]{CANCEL, third, second, first}, resultMenuEntries); + assertArrayEquals(new MenuEntry[]{third, second, first}, + Lists.reverse(createdMenuEntries).toArray(new MenuEntry[0])); } } diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java new file mode 100644 index 0000000000..6665f40ec3 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.menus; + +import java.util.function.Consumer; +import lombok.EqualsAndHashCode; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; + +@EqualsAndHashCode(callSuper = false) +public class TestMenuEntry extends MenuEntry +{ + private String option; + private String target; + private int identifier; + private int type; + private int param0; + private int param1; + private boolean forceLeftClick; + + @Override + public String getOption() + { + return option; + } + + @Override + public MenuEntry setOption(String option) + { + this.option = option; + return this; + } + + @Override + public String getTarget() + { + return target; + } + + @Override + public MenuEntry setTarget(String target) + { + this.target = target; + return this; + } + + @Override + public int getIdentifier() + { + return this.identifier; + } + + @Override + public MenuEntry setIdentifier(int identifier) + { + this.identifier = identifier; + return this; + } + + @Override + public MenuAction getType() + { + return MenuAction.of(this.type); + } + + @Override + public MenuEntry setType(MenuAction type) + { + this.type = type.getId(); + return this; + } + + @Override + public int getParam0() + { + return this.param0; + } + + @Override + public MenuEntry setParam0(int param0) + { + this.param0 = param0; + return this; + } + + @Override + public int getParam1() + { + return this.param1; + } + + @Override + public MenuEntry setParam1(int param1) + { + this.param1 = param1; + return this; + } + + @Override + public boolean isForceLeftClick() + { + return this.forceLeftClick; + } + + @Override + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + this.forceLeftClick = forceLeftClick; + return this; + } + + @Override + public boolean isDeprioritized() + { + return type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + + @Override + public MenuEntry setDeprioritized(boolean deprioritized) + { + if (deprioritized) + { + if (type < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + else + { + if (type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + + return this; + } + + @Override + public MenuEntry onClick(Consumer callback) + { + return this; + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java index 4b3fd12f32..ee8b485b6a 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java @@ -31,9 +31,11 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Friend; +import net.runelite.api.FriendContainer; import net.runelite.api.MessageNode; -import net.runelite.api.NameableContainer; import net.runelite.api.events.ChatMessage; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.config.ConfigManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +56,14 @@ public class FriendListPluginTest @Bind private FriendListConfig config; + @Mock + @Bind + private ConfigManager configManager; + + @Mock + @Bind + private ChatMessageManager chatMessageManager; + @Inject private FriendListPlugin friendListPlugin; @@ -78,7 +88,7 @@ public class FriendListPluginTest Friend friend = mock(Friend.class); when(friend.getWorld()).thenReturn(311); - NameableContainer friendContainer = mock(NameableContainer.class); + FriendContainer friendContainer = mock(FriendContainer.class); when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend); when(client.getFriendContainer()).thenReturn(friendContainer); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java new file mode 100644 index 0000000000..4fa03023a1 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.menuentryswapper; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.Arrays; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.KeyCode; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.menus.TestMenuEntry; +import static org.junit.Assert.assertArrayEquals; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import static org.mockito.ArgumentMatchers.any; +import org.mockito.Mock; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; + +@RunWith(MockitoJUnitRunner.class) +public class MenuEntrySwapperPluginTest +{ + @Mock + @Bind + Client client; + + @Mock + @Bind + ConfigManager configManager; + + @Mock + @Bind + ItemManager itemManager; + + @Mock + @Bind + MenuEntrySwapperConfig config; + + @Inject + MenuEntrySwapperPlugin menuEntrySwapperPlugin; + + private MenuEntry[] entries; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getGameState()).thenReturn(GameState.LOGGED_IN); + + when(client.getMenuEntries()).thenAnswer((Answer) invocationOnMock -> + { + // The menu implementation returns a copy of the array, which causes swap() to not + // modify the same array being iterated in onClientTick + return Arrays.copyOf(entries, entries.length); + }); + doAnswer((Answer) invocationOnMock -> + { + Object argument = invocationOnMock.getArguments()[0]; + entries = (MenuEntry[]) argument; + return null; + }).when(client).setMenuEntries(any(MenuEntry[].class)); + + menuEntrySwapperPlugin.setupSwaps(); + } + + private static MenuEntry menu(String option, String target, MenuAction menuAction) + { + return menu(option, target, menuAction, 0); + } + + private static MenuEntry menu(String option, String target, MenuAction menuAction, int identifier) + { + MenuEntry menuEntry = new TestMenuEntry(); + menuEntry.setOption(option); + menuEntry.setTarget(target); + menuEntry.setType(menuAction); + menuEntry.setIdentifier(identifier); + return menuEntry; + } + + @Test + public void testSlayerMaster() + { + lenient().when(config.swapTrade()).thenReturn(true); + when(config.swapAssignment()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Rewards", "Duradel", MenuAction.NPC_FIFTH_OPTION), + menu("Trade", "Duradel", MenuAction.NPC_FOURTH_OPTION), + menu("Assignment", "Duradel", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Duradel", MenuAction.NPC_FIRST_OPTION), + }; + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + // check the assignment swap is hit first instead of trade + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Rewards", "Duradel", MenuAction.NPC_FIFTH_OPTION), + menu("Trade", "Duradel", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Duradel", MenuAction.NPC_FIRST_OPTION), + menu("Assignment", "Duradel", MenuAction.NPC_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testBankers() + { + when(config.swapBank()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + // Banker 2 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + + // Banker 1 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client, times(2)).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + // Banker 2 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + + // Banker 1 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testContains() + { + when(config.swapPay()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Kragen", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + menu("Pay (south)", "Kragen", MenuAction.NPC_FOURTH_OPTION), + menu("Pay (north)", "Kragen", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Kragen", MenuAction.NPC_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Kragen", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + menu("Pay (south)", "Kragen", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Kragen", MenuAction.NPC_FIRST_OPTION), + menu("Pay (north)", "Kragen", MenuAction.NPC_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testTeleport() + { + when(config.swapTeleportSpell()).thenReturn(true); + when(client.isKeyPressed(KeyCode.KC_SHIFT)).thenReturn(true); + + // Cast -> Grand Exchange + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + }, argumentCaptor.getValue()); + + clearInvocations(client); + + // Grand Exchange -> Cast + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testTobDoor() + { + when(config.swapQuick()).thenReturn(true); + + //Quick-enter, Enter + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Formidable Passage", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Quick-Enter", "Formidable Passage", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Enter", "Formidable Passage", MenuAction.GAME_OBJECT_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Formidable Passage", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Enter", "Formidable Passage", MenuAction.GAME_OBJECT_FIRST_OPTION), + menu("Quick-Enter", "Formidable Passage", MenuAction.GAME_OBJECT_SECOND_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testShiftWithdraw() + { + when(config.bankDepositShiftClick()).thenReturn(ShiftDepositMode.EXTRA_OP); + when(client.isKeyPressed(KeyCode.KC_SHIFT)).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Wield", "Abyssal whip", MenuAction.CC_OP_LOW_PRIORITY, 9), + menu("Deposit-1", "Abyssal whip", MenuAction.CC_OP, 2), + }; + + menuEntrySwapperPlugin.onMenuEntryAdded(new MenuEntryAdded( + "Deposit-1", + "Abyssal whip", + MenuAction.CC_OP.getId(), + 2, + -1, + -1 + )); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Deposit-1", "Abyssal whip", MenuAction.CC_OP, 2), + menu("Wield", "Abyssal whip", MenuAction.CC_OP, 9), + }, argumentCaptor.getValue()); + } + + @Test + public void testShiftDeposit() + { + when(config.bankDepositShiftClick()).thenReturn(ShiftDepositMode.DEPOSIT_ALL); + when(client.isKeyPressed(KeyCode.KC_SHIFT)).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Wield", "Rune arrow", MenuAction.CC_OP_LOW_PRIORITY, 9), + menu("Deposit-All", "Rune arrow", MenuAction.CC_OP_LOW_PRIORITY, 8), + menu("Deposit-1", "Rune arrow", MenuAction.CC_OP, 2), + }; + + menuEntrySwapperPlugin.onMenuEntryAdded(new MenuEntryAdded( + "Deposit-1", + "Rune arrow", + MenuAction.CC_OP.getId(), + 2, + -1, + -1 + )); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Wield", "Rune arrow", MenuAction.CC_OP_LOW_PRIORITY, 9), + menu("Deposit-1", "Rune arrow", MenuAction.CC_OP, 2), + menu("Deposit-All", "Rune arrow", MenuAction.CC_OP, 8), + }, argumentCaptor.getValue()); + } + + @Test + public void testBirdhouse() + { + when(config.swapBirdhouseEmpty()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Redwood birdhouse", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Empty", "Redwood birdhouse", MenuAction.GAME_OBJECT_THIRD_OPTION), + menu("Seeds", "Redwood birdhouse", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Interact", "Redwood birdhouse", MenuAction.GAME_OBJECT_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Redwood birdhouse", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Interact", "Redwood birdhouse", MenuAction.GAME_OBJECT_FIRST_OPTION), + menu("Seeds", "Redwood birdhouse", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Empty", "Redwood birdhouse", MenuAction.GAME_OBJECT_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testZanarisFairyRing() + { + when(config.swapFairyRing()).thenReturn(FairyRingMode.ZANARIS); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Fairy ring", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Last-destination (AIQ)", "Fairy ring", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Configure", "Fairy ring", MenuAction.GAME_OBJECT_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Fairy ring", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Configure", "Fairy ring", MenuAction.GAME_OBJECT_FIRST_OPTION), + menu("Last-destination (AIQ)", "Fairy ring", MenuAction.GAME_OBJECT_SECOND_OPTION), + }, argumentCaptor.getValue()); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java index 13c42671f7..1179f3e48c 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java @@ -39,6 +39,7 @@ import net.runelite.api.NPC; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcSpawned; +import net.runelite.client.menus.TestMenuEntry; import net.runelite.client.ui.overlay.OverlayManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -49,7 +50,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -111,13 +111,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // red - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // red } @Test @@ -136,13 +135,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // blue - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // blue } @Test