Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-12-15 05:39:29 +01:00
80 changed files with 3322 additions and 1734 deletions

View File

@@ -12,45 +12,40 @@ public class ModelDefinition
public int id; public int id;
public int vertexCount = 0; public int vertexCount = 0;
public int[] vertexPositionsX; public int[] vertexX;
public int[] vertexPositionsY; public int[] vertexY;
public int[] vertexPositionsZ; public int[] vertexZ;
public transient VertexNormal[] vertexNormals; public transient VertexNormal[] vertexNormals;
public int faceCount; public int faceCount;
public int[] faceVertexIndices1; public int[] faceIndices1;
public int[] faceVertexIndices2; public int[] faceIndices2;
public int[] faceVertexIndices3; public int[] faceIndices3;
public byte[] faceAlphas; public byte[] faceTransparencies;
public short[] faceColors; public short[] faceColors;
public byte[] faceRenderPriorities; public byte[] faceRenderPriorities;
public byte[] faceRenderTypes; public byte[] faceRenderTypes;
public transient FaceNormal[] faceNormals; public transient FaceNormal[] faceNormals;
public int textureTriangleCount; public int numTextureFaces;
public short[] textureTriangleVertexIndices1; public short[] texIndices1;
public short[] textureTriangleVertexIndices2; public short[] texIndices2;
public short[] textureTriangleVertexIndices3; public short[] texIndices3;
public transient float[][] faceTextureUCoordinates; public transient float[][] faceTextureUCoordinates;
public transient float[][] faceTextureVCoordinates; public transient float[][] faceTextureVCoordinates;
public short[] texturePrimaryColors; public short[] texturePrimaryColors;
public short[] faceTextures; public short[] faceTextures;
public byte[] textureCoordinates; public byte[] textureCoords;
public byte[] textureRenderTypes; public byte[] textureRenderTypes;
public int[] vertexSkins; public int[] packedVertexGroups;
public int[] faceSkins; public int[] packedTransparencyVertexGroups;
public byte priority; 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; private transient int[][] vertexGroups;
public int[][] animayaGroups;
public int[][] animayaScales;
private transient int[] origVX; private transient int[] origVX;
private transient int[] origVY; private transient int[] origVY;
@@ -77,17 +72,17 @@ public class ModelDefinition
for (var1 = 0; var1 < this.faceCount; ++var1) for (var1 = 0; var1 < this.faceCount; ++var1)
{ {
int vertexA = this.faceVertexIndices1[var1]; int vertexA = this.faceIndices1[var1];
int vertexB = this.faceVertexIndices2[var1]; int vertexB = this.faceIndices2[var1];
int vertexC = this.faceVertexIndices3[var1]; int vertexC = this.faceIndices3[var1];
int xA = this.vertexPositionsX[vertexB] - this.vertexPositionsX[vertexA]; int xA = this.vertexX[vertexB] - this.vertexX[vertexA];
int yA = this.vertexPositionsY[vertexB] - this.vertexPositionsY[vertexA]; int yA = this.vertexY[vertexB] - this.vertexY[vertexA];
int zA = this.vertexPositionsZ[vertexB] - this.vertexPositionsZ[vertexA]; int zA = this.vertexZ[vertexB] - this.vertexZ[vertexA];
int xB = this.vertexPositionsX[vertexC] - this.vertexPositionsX[vertexA]; int xB = this.vertexX[vertexC] - this.vertexX[vertexA];
int yB = this.vertexPositionsY[vertexC] - this.vertexPositionsY[vertexA]; int yB = this.vertexY[vertexC] - this.vertexY[vertexA];
int zB = this.vertexPositionsZ[vertexC] - this.vertexPositionsZ[vertexA]; int zB = this.vertexZ[vertexC] - this.vertexZ[vertexA];
// Compute cross product // Compute cross product
int var11 = yA * zB - yB * zA; int var11 = yA * zB - yB * zA;
@@ -168,13 +163,13 @@ public class ModelDefinition
for (int i = 0; i < faceCount; i++) for (int i = 0; i < faceCount; i++)
{ {
int textureCoordinate; int textureCoordinate;
if (textureCoordinates == null) if (textureCoords == null)
{ {
textureCoordinate = -1; textureCoordinate = -1;
} }
else else
{ {
textureCoordinate = textureCoordinates[i]; textureCoordinate = textureCoords[i];
} }
int textureIdx; int textureIdx;
@@ -215,33 +210,33 @@ public class ModelDefinition
if (textureRenderType == 0) if (textureRenderType == 0)
{ {
int faceVertexIdx1 = faceVertexIndices1[i]; int faceVertexIdx1 = faceIndices1[i];
int faceVertexIdx2 = faceVertexIndices2[i]; int faceVertexIdx2 = faceIndices2[i];
int faceVertexIdx3 = faceVertexIndices3[i]; int faceVertexIdx3 = faceIndices3[i];
short triangleVertexIdx1 = textureTriangleVertexIndices1[textureCoordinate]; short triangleVertexIdx1 = texIndices1[textureCoordinate];
short triangleVertexIdx2 = textureTriangleVertexIndices2[textureCoordinate]; short triangleVertexIdx2 = texIndices2[textureCoordinate];
short triangleVertexIdx3 = textureTriangleVertexIndices3[textureCoordinate]; short triangleVertexIdx3 = texIndices3[textureCoordinate];
float triangleX = (float) vertexPositionsX[triangleVertexIdx1]; float triangleX = (float) vertexX[triangleVertexIdx1];
float triangleY = (float) vertexPositionsY[triangleVertexIdx1]; float triangleY = (float) vertexY[triangleVertexIdx1];
float triangleZ = (float) vertexPositionsZ[triangleVertexIdx1]; float triangleZ = (float) vertexZ[triangleVertexIdx1];
float f_882_ = (float) vertexPositionsX[triangleVertexIdx2] - triangleX; float f_882_ = (float) vertexX[triangleVertexIdx2] - triangleX;
float f_883_ = (float) vertexPositionsY[triangleVertexIdx2] - triangleY; float f_883_ = (float) vertexY[triangleVertexIdx2] - triangleY;
float f_884_ = (float) vertexPositionsZ[triangleVertexIdx2] - triangleZ; float f_884_ = (float) vertexZ[triangleVertexIdx2] - triangleZ;
float f_885_ = (float) vertexPositionsX[triangleVertexIdx3] - triangleX; float f_885_ = (float) vertexX[triangleVertexIdx3] - triangleX;
float f_886_ = (float) vertexPositionsY[triangleVertexIdx3] - triangleY; float f_886_ = (float) vertexY[triangleVertexIdx3] - triangleY;
float f_887_ = (float) vertexPositionsZ[triangleVertexIdx3] - triangleZ; float f_887_ = (float) vertexZ[triangleVertexIdx3] - triangleZ;
float f_888_ = (float) vertexPositionsX[faceVertexIdx1] - triangleX; float f_888_ = (float) vertexX[faceVertexIdx1] - triangleX;
float f_889_ = (float) vertexPositionsY[faceVertexIdx1] - triangleY; float f_889_ = (float) vertexY[faceVertexIdx1] - triangleY;
float f_890_ = (float) vertexPositionsZ[faceVertexIdx1] - triangleZ; float f_890_ = (float) vertexZ[faceVertexIdx1] - triangleZ;
float f_891_ = (float) vertexPositionsX[faceVertexIdx2] - triangleX; float f_891_ = (float) vertexX[faceVertexIdx2] - triangleX;
float f_892_ = (float) vertexPositionsY[faceVertexIdx2] - triangleY; float f_892_ = (float) vertexY[faceVertexIdx2] - triangleY;
float f_893_ = (float) vertexPositionsZ[faceVertexIdx2] - triangleZ; float f_893_ = (float) vertexZ[faceVertexIdx2] - triangleZ;
float f_894_ = (float) vertexPositionsX[faceVertexIdx3] - triangleX; float f_894_ = (float) vertexX[faceVertexIdx3] - triangleX;
float f_895_ = (float) vertexPositionsY[faceVertexIdx3] - triangleY; float f_895_ = (float) vertexY[faceVertexIdx3] - triangleY;
float f_896_ = (float) vertexPositionsZ[faceVertexIdx3] - triangleZ; float f_896_ = (float) vertexZ[faceVertexIdx3] - triangleZ;
float f_897_ = f_883_ * f_887_ - f_884_ * f_886_; float f_897_ = f_883_ * f_887_ - f_884_ * f_886_;
float f_898_ = f_884_ * f_885_ - f_882_ * f_887_; float f_898_ = f_884_ * f_885_ - f_882_ * f_887_;
@@ -274,7 +269,7 @@ public class ModelDefinition
public void computeAnimationTables() public void computeAnimationTables()
{ {
if (this.vertexSkins != null) if (this.packedVertexGroups != null)
{ {
int[] groupCounts = new int[256]; int[] groupCounts = new int[256];
int numGroups = 0; int numGroups = 0;
@@ -282,7 +277,7 @@ public class ModelDefinition
for (var3 = 0; var3 < this.vertexCount; ++var3) for (var3 = 0; var3 < this.vertexCount; ++var3)
{ {
var4 = this.vertexSkins[var3]; var4 = this.packedVertexGroups[var3];
++groupCounts[var4]; ++groupCounts[var4];
if (var4 > numGroups) if (var4 > numGroups)
{ {
@@ -300,10 +295,10 @@ public class ModelDefinition
for (var3 = 0; var3 < this.vertexCount; this.vertexGroups[var4][groupCounts[var4]++] = var3++) 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 // triangleSkinValues is here
@@ -314,13 +309,13 @@ public class ModelDefinition
int sin = CircularAngle.SINE[orientation]; int sin = CircularAngle.SINE[orientation];
int cos = CircularAngle.COSINE[orientation]; int cos = CircularAngle.COSINE[orientation];
assert vertexPositionsX.length == vertexPositionsY.length; assert vertexX.length == vertexY.length;
assert vertexPositionsY.length == vertexPositionsZ.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; vertexX[i] = vertexX[i] * cos + vertexZ[i] * sin >> 16;
vertexPositionsZ[i] = vertexPositionsZ[i] * cos - vertexPositionsX[i] * sin >> 16; vertexZ[i] = vertexZ[i] * cos - vertexX[i] * sin >> 16;
} }
reset(); reset();
@@ -333,23 +328,23 @@ public class ModelDefinition
return; return;
} }
System.arraycopy(origVX, 0, vertexPositionsX, 0, origVX.length); System.arraycopy(origVX, 0, vertexX, 0, origVX.length);
System.arraycopy(origVY, 0, vertexPositionsY, 0, origVY.length); System.arraycopy(origVY, 0, vertexY, 0, origVY.length);
System.arraycopy(origVZ, 0, vertexPositionsZ, 0, origVZ.length); System.arraycopy(origVZ, 0, vertexZ, 0, origVZ.length);
} }
public void animate(int type, int[] frameMap, int dx, int dy, int dz) public void animate(int type, int[] frameMap, int dx, int dy, int dz)
{ {
if (origVX == null) if (origVX == null)
{ {
origVX = Arrays.copyOf(vertexPositionsX, vertexPositionsX.length); origVX = Arrays.copyOf(vertexX, vertexX.length);
origVY = Arrays.copyOf(vertexPositionsY, vertexPositionsY.length); origVY = Arrays.copyOf(vertexY, vertexY.length);
origVZ = Arrays.copyOf(vertexPositionsZ, vertexPositionsZ.length); origVZ = Arrays.copyOf(vertexZ, vertexZ.length);
} }
final int[] verticesX = vertexPositionsX; final int[] verticesX = vertexX;
final int[] verticesY = vertexPositionsY; final int[] verticesY = vertexY;
final int[] verticesZ = vertexPositionsZ; final int[] verticesZ = vertexZ;
int var6 = frameMap.length; int var6 = frameMap.length;
int var7; int var7;
int var8; int var8;
@@ -512,14 +507,14 @@ public class ModelDefinition
int var1; int var1;
for (var1 = 0; var1 < this.vertexCount; ++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) for (var1 = 0; var1 < this.faceCount; ++var1)
{ {
int var2 = this.faceVertexIndices1[var1]; int var2 = this.faceIndices1[var1];
this.faceVertexIndices1[var1] = this.faceVertexIndices3[var1]; this.faceIndices1[var1] = this.faceIndices3[var1];
this.faceVertexIndices3[var1] = var2; this.faceIndices3[var1] = var2;
} }
reset(); reset();
@@ -529,9 +524,9 @@ public class ModelDefinition
{ {
for (int var1 = 0; var1 < this.vertexCount; ++var1) for (int var1 = 0; var1 < this.vertexCount; ++var1)
{ {
int var2 = this.vertexPositionsX[var1]; int var2 = this.vertexX[var1];
this.vertexPositionsX[var1] = this.vertexPositionsZ[var1]; this.vertexX[var1] = this.vertexZ[var1];
this.vertexPositionsZ[var1] = -var2; this.vertexZ[var1] = -var2;
} }
reset(); reset();
@@ -541,8 +536,8 @@ public class ModelDefinition
{ {
for (int var1 = 0; var1 < this.vertexCount; ++var1) for (int var1 = 0; var1 < this.vertexCount; ++var1)
{ {
this.vertexPositionsX[var1] = -this.vertexPositionsX[var1]; this.vertexX[var1] = -this.vertexX[var1];
this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; this.vertexZ[var1] = -this.vertexZ[var1];
} }
reset(); reset();
@@ -552,9 +547,9 @@ public class ModelDefinition
{ {
for (int var1 = 0; var1 < this.vertexCount; ++var1) for (int var1 = 0; var1 < this.vertexCount; ++var1)
{ {
int var2 = this.vertexPositionsZ[var1]; int var2 = this.vertexZ[var1];
this.vertexPositionsZ[var1] = this.vertexPositionsX[var1]; this.vertexZ[var1] = this.vertexX[var1];
this.vertexPositionsX[var1] = -var2; this.vertexX[var1] = -var2;
} }
reset(); reset();
@@ -571,9 +566,9 @@ public class ModelDefinition
{ {
for (int var4 = 0; var4 < this.vertexCount; ++var4) for (int var4 = 0; var4 < this.vertexCount; ++var4)
{ {
this.vertexPositionsX[var4] = this.vertexPositionsX[var4] * var1 / 128; this.vertexX[var4] = this.vertexX[var4] * var1 / 128;
this.vertexPositionsY[var4] = var2 * this.vertexPositionsY[var4] / 128; this.vertexY[var4] = var2 * this.vertexY[var4] / 128;
this.vertexPositionsZ[var4] = var3 * this.vertexPositionsZ[var4] / 128; this.vertexZ[var4] = var3 * this.vertexZ[var4] / 128;
} }
reset(); reset();
@@ -610,9 +605,9 @@ public class ModelDefinition
{ {
for (int i = 0; i < this.vertexCount; i++) for (int i = 0; i < this.vertexCount; i++)
{ {
this.vertexPositionsX[i] += xOffset; this.vertexX[i] += xOffset;
this.vertexPositionsY[i] += yOffset; this.vertexY[i] += yOffset;
this.vertexPositionsZ[i] += zOffset; this.vertexZ[i] += zOffset;
} }
this.reset(); this.reset();
} }

File diff suppressed because it is too large Load Diff

View File

@@ -227,22 +227,22 @@ public class ItemSpriteFactory
litModel.field1856 = new int[def.faceCount]; litModel.field1856 = new int[def.faceCount];
litModel.field1854 = new int[def.faceCount]; litModel.field1854 = new int[def.faceCount];
litModel.field1823 = 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; int var10;
for (var10 = 0; var10 < def.faceCount; ++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; 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) if (var9[var10] > 0 && def.textureRenderTypes[var10] == 0)
{ {
@@ -256,13 +256,13 @@ public class ItemSpriteFactory
var10 = 0; 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) if (var9[i] > 0 && def.textureRenderTypes[i] == 0)
{ {
litModel.field1844[var10] = def.textureTriangleVertexIndices1[i] & '\uffff'; litModel.field1844[var10] = def.texIndices1[i] & '\uffff';
litModel.field1865[var10] = def.textureTriangleVertexIndices2[i] & '\uffff'; litModel.field1865[var10] = def.texIndices2[i] & '\uffff';
litModel.field1846[var10] = def.textureTriangleVertexIndices3[i] & '\uffff'; litModel.field1846[var10] = def.texIndices3[i] & '\uffff';
var9[i] = var10++; var9[i] = var10++;
} }
else else
@@ -275,9 +275,9 @@ public class ItemSpriteFactory
for (int i = 0; i < def.faceCount; ++i) 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 else
{ {
@@ -299,13 +299,13 @@ public class ItemSpriteFactory
} }
byte faceAlpha; byte faceAlpha;
if (def.faceAlphas == null) if (def.faceTransparencies == null)
{ {
faceAlpha = 0; faceAlpha = 0;
} }
else else
{ {
faceAlpha = def.faceAlphas[faceIdx]; faceAlpha = def.faceTransparencies[faceIdx];
} }
short faceTexture; short faceTexture;
@@ -355,15 +355,15 @@ public class ItemSpriteFactory
else else
{ {
int var15 = def.faceColors[faceIdx] & '\uffff'; 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; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1856[faceIdx] = method2608(var15, tmp); 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; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1854[faceIdx] = method2608(var15, tmp); 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; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1823[faceIdx] = method2608(var15, tmp); litModel.field1823[faceIdx] = method2608(var15, tmp);
@@ -385,15 +385,15 @@ public class ItemSpriteFactory
} }
else 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; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1856[faceIdx] = bound2to126(tmp); 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; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1854[faceIdx] = bound2to126(tmp); 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; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient;
litModel.field1823[faceIdx] = bound2to126(tmp); litModel.field1823[faceIdx] = bound2to126(tmp);
@@ -401,15 +401,15 @@ public class ItemSpriteFactory
} }
litModel.verticesCount = def.vertexCount; litModel.verticesCount = def.vertexCount;
litModel.verticesX = def.vertexPositionsX; litModel.verticesX = def.vertexX;
litModel.verticesY = def.vertexPositionsY; litModel.verticesY = def.vertexY;
litModel.verticesZ = def.vertexPositionsZ; litModel.verticesZ = def.vertexZ;
litModel.indicesCount = def.faceCount; litModel.indicesCount = def.faceCount;
litModel.indices1 = def.faceVertexIndices1; litModel.indices1 = def.faceIndices1;
litModel.indices2 = def.faceVertexIndices2; litModel.indices2 = def.faceIndices2;
litModel.indices3 = def.faceVertexIndices3; litModel.indices3 = def.faceIndices3;
litModel.field1838 = def.faceRenderPriorities; litModel.field1838 = def.faceRenderPriorities;
litModel.field1882 = def.faceAlphas; litModel.field1882 = def.faceTransparencies;
litModel.field1842 = def.priority; litModel.field1842 = def.priority;
litModel.field1841 = def.faceTextures; litModel.field1841 = def.faceTextures;
return litModel; return litModel;

View File

@@ -53,9 +53,9 @@ public class ObjExporter
for (int i = 0; i < model.vertexCount; ++i) for (int i = 0; i < model.vertexCount; ++i)
{ {
objWriter.println("v " + model.vertexPositionsX[i] + " " objWriter.println("v " + model.vertexX[i] + " "
+ model.vertexPositionsY[i] * -1 + " " + model.vertexY[i] * -1 + " "
+ model.vertexPositionsZ[i] * -1); + model.vertexZ[i] * -1);
} }
if (model.faceTextures != null) if (model.faceTextures != null)
@@ -78,9 +78,9 @@ public class ObjExporter
for (int i = 0; i < model.faceCount; ++i) for (int i = 0; i < model.faceCount; ++i)
{ {
int x = model.faceVertexIndices1[i] + 1; int x = model.faceIndices1[i] + 1;
int y = model.faceVertexIndices2[i] + 1; int y = model.faceIndices2[i] + 1;
int z = model.faceVertexIndices3[i] + 1; int z = model.faceIndices3[i] + 1;
objWriter.println("usemtl m" + i); objWriter.println("usemtl m" + i);
if (model.faceTextures != null) if (model.faceTextures != null)
@@ -129,9 +129,9 @@ public class ObjExporter
int alpha = 0; int alpha = 0;
if (model.faceAlphas != null) if (model.faceTransparencies != null)
{ {
alpha = model.faceAlphas[i] & 0xFF; alpha = model.faceTransparencies[i] & 0xFF;
} }
if (alpha != 0) if (alpha != 0)

View File

@@ -93,6 +93,7 @@ public class HiscoreResult
private Skill kreearra; private Skill kreearra;
private Skill krilTsutsaroth; private Skill krilTsutsaroth;
private Skill mimic; private Skill mimic;
private Skill nex;
private Skill nightmare; private Skill nightmare;
private Skill phosanisNightmare; private Skill phosanisNightmare;
private Skill obor; private Skill obor;
@@ -244,6 +245,8 @@ public class HiscoreResult
return krilTsutsaroth; return krilTsutsaroth;
case MIMIC: case MIMIC:
return mimic; return mimic;
case NEX:
return nex;
case NIGHTMARE: case NIGHTMARE:
return nightmare; return nightmare;
case PHOSANIS_NIGHTMARE: case PHOSANIS_NIGHTMARE:

View File

@@ -118,6 +118,10 @@ class HiscoreResultBuilder
hiscoreResult.setKreearra(skills.get(index++)); hiscoreResult.setKreearra(skills.get(index++));
hiscoreResult.setKrilTsutsaroth(skills.get(index++)); hiscoreResult.setKrilTsutsaroth(skills.get(index++));
hiscoreResult.setMimic(skills.get(index++)); hiscoreResult.setMimic(skills.get(index++));
if (skills.size() > 83)
{
hiscoreResult.setNex(skills.get(index++));
}
hiscoreResult.setNightmare(skills.get(index++)); hiscoreResult.setNightmare(skills.get(index++));
hiscoreResult.setPhosanisNightmare(skills.get(index++)); hiscoreResult.setPhosanisNightmare(skills.get(index++));
hiscoreResult.setObor(skills.get(index++)); hiscoreResult.setObor(skills.get(index++));

View File

@@ -97,6 +97,7 @@ public enum HiscoreSkill
KREEARRA("Kree'Arra", BOSS), KREEARRA("Kree'Arra", BOSS),
KRIL_TSUTSAROTH("K'ril Tsutsaroth", BOSS), KRIL_TSUTSAROTH("K'ril Tsutsaroth", BOSS),
MIMIC("Mimic", BOSS), MIMIC("Mimic", BOSS),
NEX("Nex", BOSS),
NIGHTMARE("Nightmare", BOSS), NIGHTMARE("Nightmare", BOSS),
PHOSANIS_NIGHTMARE("Phosani's Nightmare", BOSS), PHOSANIS_NIGHTMARE("Phosani's Nightmare", BOSS),
OBOR("Obor", BOSS), OBOR("Obor", BOSS),

View File

@@ -636,6 +636,13 @@ public interface Client extends GameEngine
*/ */
World[] getWorldList(); 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 * Gets an array of currently open right-click menu entries that can be
* clicked and activated. * 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 * @param id the ID of the animation. Any int is allowed, but implementations in the client
* should be defined in {@link AnimationID} * should be defined in {@link AnimationID}
*/ */
Sequence loadAnimation(int id); Animation loadAnimation(int id);
/** /**
* Gets the music volume * Gets the music volume
@@ -1341,7 +1348,7 @@ public interface Client extends GameEngine
/** /**
* Retrieve the nameable container containing friends * Retrieve the nameable container containing friends
*/ */
NameableContainer<Friend> getFriendContainer(); FriendContainer getFriendContainer();
/** /**
* Retrieve the nameable container containing ignores * Retrieve the nameable container containing ignores

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Trevor <https://github.com/Trevor159> * Copyright (c) 2021, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -25,8 +25,13 @@
package net.runelite.api; package net.runelite.api;
/** /**
* Represents an animation of a renderable * A nameable container of friends
*/ */
public interface Sequence public interface FriendContainer extends NameableContainer<Friend>
{ {
/**
* Get the recent logins/logouts of friends from the last few seconds
* @return
*/
Deque<PendingLogin> getPendingLogins();
} }

View File

@@ -24,6 +24,8 @@
*/ */
package net.runelite.api; package net.runelite.api;
import java.util.Arrays;
import java.util.function.Consumer;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; 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<MenuEntry> callback)
{
return this;
}
public void setActionParam0(int i) public void setActionParam0(int i)
{ {
this.param0 = i; this.param0 = i;
@@ -104,26 +213,6 @@ public class MenuEntry implements Cloneable
return this.param0; 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) public void setActionParam1(int i)
{ {
this.param1 = i; this.param1 = i;
@@ -139,11 +228,6 @@ public class MenuEntry implements Cloneable
this.opcode = i; this.opcode = i;
} }
public int getType()
{
return this.opcode;
}
public void setId(int i) public void setId(int i)
{ {
this.identifier = i; this.identifier = i;
@@ -161,4 +245,19 @@ public class MenuEntry implements Cloneable
{ {
return MenuAction.of(getOpcode()); 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);
}
} }

View File

@@ -55,13 +55,13 @@ public interface Model extends Renderable
int[] getVerticesZ(); int[] getVerticesZ();
int getTrianglesCount(); int getFaceCount();
int[] getTrianglesX(); int[] getFaceIndices1();
int[] getTrianglesY(); int[] getFaceIndices2();
int[] getTrianglesZ(); int[] getFaceIndices3();
int[] getFaceColors1(); int[] getFaceColors1();
@@ -69,7 +69,7 @@ public interface Model extends Renderable
int[] getFaceColors3(); int[] getFaceColors3();
byte[] getTriangleTransparencies(); byte[] getFaceTransparencies();
int getSceneId(); int getSceneId();
void setSceneId(int sceneId); void setSceneId(int sceneId);
@@ -109,4 +109,9 @@ public interface Model extends Renderable
int[] getVertexNormalsX(); int[] getVertexNormalsX();
int[] getVertexNormalsY(); int[] getVertexNormalsY();
int[] getVertexNormalsZ(); int[] getVertexNormalsZ();
byte getOverrideAmount();
byte getOverrideHue();
byte getOverrideSaturation();
byte getOverrideLuminance();
} }

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2021, Adam <Adam@sigterm.info>
* 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();
}

View File

@@ -782,9 +782,9 @@ public class Perspective
final int radius = 5; final int radius = 5;
int[][] tris = new int[][]{ int[][] tris = new int[][]{
m.getTrianglesX(), m.getFaceIndices1(),
m.getTrianglesY(), m.getFaceIndices2(),
m.getTrianglesZ() m.getFaceIndices3()
}; };
int vpX1 = client.getViewportXOffset(); int vpX1 = client.getViewportXOffset();
@@ -792,10 +792,10 @@ public class Perspective
int vpX2 = vpX1 + client.getViewportWidth(); int vpX2 = vpX1 + client.getViewportWidth();
int vpY2 = vpY1 + client.getViewportHeight(); int vpY2 = vpY1 + client.getViewportHeight();
List<RectangleUnion.Rectangle> rects = new ArrayList<>(m.getTrianglesCount()); List<RectangleUnion.Rectangle> rects = new ArrayList<>(m.getFaceCount());
nextTri: nextTri:
for (int tri = 0; tri < m.getTrianglesCount(); tri++) for (int tri = 0; tri < m.getFaceCount(); tri++)
{ {
if (faceColors3[tri] == -2) if (faceColors3[tri] == -2)
{ {

View File

@@ -41,7 +41,7 @@ public interface RuneLiteObject extends GraphicsObject
* Sets the animation of the RuneLiteObject * Sets the animation of the RuneLiteObject
* If animation is null model will be static * 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. * Sets whether the animation of the RuneLiteObject should loop when the animation ends.

View File

@@ -257,6 +257,12 @@ public final class ScriptID
@ScriptArguments(integer = 15) @ScriptArguments(integer = 15)
public static final int FRIENDS_CHAT_CHANNEL_REBUILD = 1658; 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 * Builds the widget for making an offer in Grand Exchange
*/ */

View File

@@ -31,7 +31,7 @@ public class ClientTick
{ {
public static final ClientTick INSTANCE = new ClientTick(); public static final ClientTick INSTANCE = new ClientTick();
private ClientTick() public ClientTick()
{ {
// noop // noop
} }

View File

@@ -25,24 +25,50 @@
package net.runelite.api.events; package net.runelite.api.events;
import lombok.Getter; import lombok.Getter;
import net.runelite.api.MenuEntry;
/** /**
* An event when a new entry is added to a right-click menu. * 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) // Here for RuneLite compatibility (different parameter order)
public MenuEntryAdded(String option, String target, int type, int identifier, int actionParam0, int actionParam1) 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 * If this is set to true client mixin will update
* the menu entry with the modified values. * the menu entry with the modified values.

View File

@@ -91,33 +91,9 @@ public class MenuOptionClicked
{ {
this.setMenuOption(entry.getOption()); this.setMenuOption(entry.getOption());
this.setMenuTarget(entry.getTarget()); this.setMenuTarget(entry.getTarget());
this.setId(entry.getId()); this.setId(entry.getIdentifier());
this.setMenuAction(MenuAction.of(entry.getOpcode())); this.setMenuAction(entry.getType());
this.setParam0(entry.getParam0()); this.setParam0(entry.getParam0());
this.setParam1(entry.getParam1()); 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;
}
} }

View File

@@ -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. * A MenuManager widget menu was clicked. This event is fired only for MenuManager managed custom menus.
*/ */
@Data @Data
@Deprecated
public class WidgetMenuOptionClicked public class WidgetMenuOptionClicked
{ {
/** /**

View File

@@ -1352,11 +1352,15 @@ public final class WidgetID
static class Clan static class Clan
{ {
static final int LAYER = 0;
static final int HEADER = 1;
static final int MEMBERS = 6; static final int MEMBERS = 6;
} }
static class ClanGuest static class ClanGuest
{ {
static final int LAYER = 0;
static final int HEADER = 1;
static final int MEMBERS = 6; static final int MEMBERS = 6;
} }
} }

View File

@@ -554,7 +554,12 @@ public enum WidgetInfo
TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR), 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_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), CLAN_GUEST_MEMBER_LIST(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.MEMBERS),
//OpenOSRS //OpenOSRS

View File

@@ -395,7 +395,6 @@ public class RuneLite
// Add core overlays // Add core overlays
WidgetOverlay.createOverlays(overlayManager, client).forEach(overlayManager::add); WidgetOverlay.createOverlays(overlayManager, client).forEach(overlayManager::add);
overlayManager.add(worldMapOverlay.get()); overlayManager.add(worldMapOverlay.get());
eventBus.register(worldMapOverlay.get());
overlayManager.add(tooltipOverlay.get()); overlayManager.add(tooltipOverlay.get());
playerManager.get(); playerManager.get();

View File

@@ -27,10 +27,10 @@ package net.runelite.client.menus;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -67,6 +67,7 @@ public class MenuManager
{ {
this.client = client; this.client = client;
this.eventBus = eventBus; this.eventBus = eventBus;
eventBus.register(this); eventBus.register(this);
} }
@@ -74,10 +75,12 @@ public class MenuManager
* Adds a CustomMenuOption to the list of managed menu options. * Adds a CustomMenuOption to the list of managed menu options.
* *
* @param customMenuOption The custom menu to add * @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<MenuEntry> callback)
{ {
managedMenuOptions.put(customMenuOption.getWidgetId(), customMenuOption); managedMenuOptions.put(customMenuOption.getWidgetId(), customMenuOption);
customMenuOption.callback = callback;
} }
/** /**
@@ -113,7 +116,7 @@ public class MenuManager
return; return;
} }
int widgetId = event.getParam1(); int widgetId = event.getActionParam1();
Collection<WidgetMenuOption> options = managedMenuOptions.get(widgetId); Collection<WidgetMenuOption> options = managedMenuOptions.get(widgetId);
if (options.isEmpty()) if (options.isEmpty())
{ {
@@ -122,11 +125,10 @@ public class MenuManager
MenuEntry[] menuEntries = client.getMenuEntries(); 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 // 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 // managed menu entries at higher indices and work backward for newer entries so newly-added entries appear at
// the bottom // the bottom
int insertIdx = newMenuEntries.length - 1; int insertIdx = -1;
for (WidgetMenuOption currentMenu : options) for (WidgetMenuOption currentMenu : options)
{ {
// Exit if we've inserted the managed menu entries already // Exit if we've inserted the managed menu entries already
@@ -135,16 +137,44 @@ public class MenuManager
return; return;
} }
MenuEntry menuEntry = new MenuEntry(); client.createMenuEntry(insertIdx--)
menuEntry.setOption(currentMenu.getMenuOption()); .setOption(currentMenu.getMenuOption())
menuEntry.setParam1(widgetId); .setTarget(currentMenu.getMenuTarget())
menuEntry.setTarget(currentMenu.getMenuTarget()); .setType(MenuAction.RUNELITE)
menuEntry.setType(MenuAction.RUNELITE.getId()); .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<WidgetMenuOption> 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) public void addPlayerMenuItem(String menuText)
@@ -198,33 +228,6 @@ public class MenuManager
addPlayerMenuItem(newIdx, menuText); addPlayerMenuItem(newIdx, menuText);
} }
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
if (event.getMenuAction() != MenuAction.RUNELITE)
{
return;
}
int widgetId = event.getParam1();
Collection<WidgetMenuOption> 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) private void addPlayerMenuItem(int playerOptionIndex, String menuText)
{ {
client.getPlayerOptions()[playerOptionIndex] = menuText; client.getPlayerOptions()[playerOptionIndex] = menuText;

View File

@@ -25,9 +25,11 @@
package net.runelite.client.menus; package net.runelite.client.menus;
import java.awt.Color; import java.awt.Color;
import java.util.function.Consumer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.runelite.api.MenuEntry;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
@@ -65,6 +67,8 @@ public final class WidgetMenuOption
@Getter @Getter
private final int widgetId; private final int widgetId;
Consumer<MenuEntry> 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 * Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options
* *

View File

@@ -341,9 +341,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener
@Subscribe @Subscribe
public void onMenuEntryAdded(MenuEntryAdded event) public void onMenuEntryAdded(MenuEntryAdded event)
{ {
MenuEntry[] entries = client.getMenuEntries(); if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
&& event.getOption().equals("Examine")) && event.getOption().equals("Examine"))
{ {
Widget container = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER); Widget container = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER);
@@ -357,87 +355,82 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener
text += " (" + tagCount + ")"; text += " (" + tagCount + ")";
} }
MenuEntry editTags = new MenuEntry(); client.createMenuEntry(-1)
editTags.setParam0(event.getActionParam0()); .setParam0(event.getActionParam0())
editTags.setParam1(event.getParam1()); .setParam1(event.getActionParam1())
editTags.setTarget(event.getTarget()); .setTarget(event.getTarget())
editTags.setOption(text); .setOption(text)
editTags.setType(MenuAction.RUNELITE.getId()); .setType(MenuAction.RUNELITE)
editTags.setIdentifier(event.getIdentifier()); .setIdentifier(event.getIdentifier())
entries = Arrays.copyOf(entries, entries.length + 1); .onClick(this::editTags)
entries[entries.length - 1] = editTags; // TODO: remove
client.setMenuEntries(entries); .add(client);
} }
tabInterface.handleAdd(event); 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<String> 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:<br>(append " + VAR_TAG_SUFFIX + " for variation tag)")
.addCharValidator(FILTERED_CHARS)
.value(initialValue)
.onDone((Consumer<String>) (newValue) ->
clientThread.invoke(() ->
{
// Split inputted tags to vartags (ending with *) and regular tags
final Collection<String> newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase()));
final Collection<String> 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 @Subscribe
public void onMenuOptionClicked(MenuOptionClicked event) public void onMenuOptionClicked(MenuOptionClicked event)
{ {
if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() tabInterface.handleClick(event);
&& 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<String> 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:<br>(append " + VAR_TAG_SUFFIX + " for variation tag)")
.addCharValidator(FILTERED_CHARS)
.value(initialValue)
.onDone((Consumer<String>) (newValue) ->
clientThread.invoke(() ->
{
// Split inputted tags to vartags (ending with *) and regular tags
final Collection<String> newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase()));
final Collection<String> 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);
}
} }
@Subscribe @Subscribe

View File

@@ -618,38 +618,32 @@ public class TabInterface
return; return;
} }
MenuEntry[] entries = client.getMenuEntries();
if (activeTab != null if (activeTab != null
&& event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
&& event.getOption().equals("Examine")) && event.getOption().equals("Examine"))
{ {
entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries); createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget());
client.setMenuEntries(entries);
} }
else if (event.getParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId()
&& event.getOption().equals("Deposit inventory")) && event.getOption().equals("Deposit inventory"))
{ {
entries = createMenuEntry(event, TAG_INVENTORY, event.getTarget(), entries); createMenuEntry(event, TAG_INVENTORY, event.getTarget());
if (activeTab != null) 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")) && event.getOption().equals("Deposit worn items"))
{ {
entries = createMenuEntry(event, TAG_GEAR, event.getTarget(), entries); createMenuEntry(event, TAG_GEAR, event.getTarget());
if (activeTab != null) 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.setOption(TAG_SEARCH + Text.removeTags(entry.getTarget()) + (shiftDown ? VAR_TAG_SUFFIX : ""));
entry.setTarget(draggedWidget.getName()); entry.setTarget(draggedWidget.getName());
client.setMenuEntries(entries);
} }
if (entry.getOption().equals(SCROLL_UP)) if (entry.getOption().equals(SCROLL_UP))
@@ -1195,17 +1188,16 @@ public class TabInterface
searchButtonBackground.setSpriteId(SpriteID.EQUIPMENT_SLOT_TILE); 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(); client.createMenuEntry(-1)
entry.setParam0(event.getActionParam0()); .setParam0(event.getActionParam0())
entry.setParam1(event.getParam1()); .setParam1(event.getActionParam1())
entry.setTarget(target); .setTarget(target)
entry.setOption(option); .setOption(option)
entry.setType(MenuAction.RUNELITE.getId()); .setType(MenuAction.RUNELITE)
entry.setIdentifier(event.getIdentifier()); .setIdentifier(event.getIdentifier())
entries = Arrays.copyOf(entries, entries.length + 1); // TODO: remove
entries[entries.length - 1] = entry; .add(client);
return entries;
} }
} }

View File

@@ -294,7 +294,7 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
{ {
for (MenuEntry menuEntry : menuEntries) for (MenuEntry menuEntry : menuEntries)
{ {
MenuAction action = MenuAction.of(menuEntry.getType()); MenuAction action = menuEntry.getType();
switch (action) switch (action)
{ {
case CANCEL: case CANCEL:

View File

@@ -206,6 +206,18 @@ public interface ChatChannelConfig extends Config
return false; 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( @ConfigItem(
keyName = "guestClanChatShowJoinLeave", keyName = "guestClanChatShowJoinLeave",
name = "Show Join/Leave", name = "Show Join/Leave",
@@ -217,4 +229,16 @@ public interface ChatChannelConfig extends Config
{ {
return false; 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;
}
} }

View File

@@ -145,6 +145,8 @@ public class ChatChannelPlugin extends Plugin
{ {
clientThread.invoke(() -> colorIgnoredPlayers(config.showIgnoresColor())); clientThread.invoke(() -> colorIgnoredPlayers(config.showIgnoresColor()));
} }
rebuildClanTitle();
} }
@Override @Override
@@ -153,6 +155,7 @@ public class ChatChannelPlugin extends Plugin
chats = null; chats = null;
clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE)); clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE));
rebuildFriendsChat(); rebuildFriendsChat();
rebuildClanTitle();
} }
@Subscribe @Subscribe
@@ -167,6 +170,8 @@ public class ChatChannelPlugin extends Plugin
Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE; Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE;
clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor)); clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor));
rebuildClanTitle();
} }
} }
@@ -606,6 +611,18 @@ public class ChatChannelPlugin extends Plugin
chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)"); 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) private void insertRankIcon(final ChatMessage message)
@@ -740,4 +757,35 @@ public class ChatChannelPlugin extends Plugin
listWidget.setTextColor(ignoreColor.getRGB()); 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() + ")");
}
}
} }

View File

@@ -201,6 +201,9 @@ public class ChatFilterPlugin extends Plugin
case NPC_EXAMINE: case NPC_EXAMINE:
case OBJECT_EXAMINE: case OBJECT_EXAMINE:
case SPAM: case SPAM:
case CLAN_MESSAGE:
case CLAN_GUEST_MESSAGE:
case CLAN_GIM_MESSAGE:
if (config.filterGameChat()) if (config.filterGameChat())
{ {
message = censorMessage(null, message); message = censorMessage(null, message);

View File

@@ -25,7 +25,6 @@
*/ */
package net.runelite.client.plugins.chathistory; package net.runelite.client.plugins.chathistory;
import com.google.common.base.Strings;
import com.google.common.collect.EvictingQueue; import com.google.common.collect.EvictingQueue;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Toolkit; import java.awt.Toolkit;
@@ -83,8 +82,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
private Queue<MessageNode> messageQueue; private Queue<MessageNode> messageQueue;
private Deque<String> friends; private Deque<String> friends;
private String currentMessage = null;
@Inject @Inject
private Client client; private Client client;
@@ -121,7 +118,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
messageQueue = null; messageQueue = null;
friends.clear(); friends.clear();
friends = null; friends = null;
currentMessage = null;
keyManager.unregisterKeyListener(this); 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 // Use second entry as first one can be walk here with transparent chatbox
final MenuEntry entry = event.getMenuEntries()[event.getMenuEntries().length - 2]; 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; return;
} }
@@ -236,16 +232,19 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
return; return;
} }
currentMessage = messageContents.getText(); String currentMessage = messageContents.getText();
final MenuEntry menuEntry = new MenuEntry(); client.createMenuEntry(1)
menuEntry.setOption(COPY_TO_CLIPBOARD); .setOption(COPY_TO_CLIPBOARD)
menuEntry.setTarget(entry.getTarget()); .setTarget(entry.getTarget())
menuEntry.setType(MenuAction.RUNELITE.getId()); .setType(MenuAction.RUNELITE)
menuEntry.setParam0(entry.getParam0()); .onClick(e ->
menuEntry.setParam1(entry.getParam1()); {
menuEntry.setIdentifier(entry.getIdentifier()); final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage));
client.setMenuEntries(ArrayUtils.insert(1, client.getMenuEntries(), menuEntry)); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
})
// TODO: remove
.add(client);
} }
@Subscribe @Subscribe
@@ -258,11 +257,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
{ {
clearChatboxHistory(ChatboxTab.of(event.getParam1())); 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 @Subscribe
@@ -279,10 +273,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
return; return;
} }
final MenuEntry clearEntry = new MenuEntry(); final MenuEntry clearEntry = client.createMenuEntry(-2)
clearEntry.setTarget(""); .setType(MenuAction.RUNELITE_HIGH_PRIORITY);
clearEntry.setType(MenuAction.RUNELITE_HIGH_PRIORITY.getId());
clearEntry.setParam0(entry.getActionParam0());
clearEntry.setParam1(entry.getActionParam1()); clearEntry.setParam1(entry.getActionParam1());
final StringBuilder optionBuilder = new StringBuilder(); final StringBuilder optionBuilder = new StringBuilder();
@@ -298,10 +290,9 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
} }
optionBuilder.append(CLEAR_HISTORY); optionBuilder.append(CLEAR_HISTORY);
clearEntry.setOption(optionBuilder.toString()); clearEntry.setOption(optionBuilder.toString())
// TODO: remove
final MenuEntry[] menuEntries = client.getMenuEntries(); .add(client);
client.setMenuEntries(ArrayUtils.insert(menuEntries.length - 1, menuEntries, clearEntry));
} }
private void clearMessageQueue(ChatboxTab tab) private void clearMessageQueue(ChatboxTab tab)

View File

@@ -490,7 +490,6 @@ public class DevToolsPlugin extends Plugin
} }
entry.setTarget(entry.getTarget() + " " + ColorUtil.prependColorTag("(" + info + ")", JagexColors.MENU_TARGET)); entry.setTarget(entry.getTarget() + " " + ColorUtil.prependColorTag("(" + info + ")", JagexColors.MENU_TARGET));
client.setMenuEntries(entries);
} }
} }
} }

View File

@@ -48,16 +48,16 @@ public class WidgetInfoTableModel extends AbstractTableModel
private static final int COL_FIELD = 0; private static final int COL_FIELD = 0;
private static final int COL_VALUE = 1; private static final int COL_VALUE = 1;
private final List<WidgetField> fields = populateWidgetFields(); private final List<WidgetField<?>> fields = populateWidgetFields();
private Widget widget = null; private Widget widget = null;
private Map<WidgetField, Object> values = null; private Map<WidgetField<?>, Object> values = null;
public void setWidget(Widget w) public void setWidget(Widget w)
{ {
clientThread.invoke(() -> clientThread.invoke(() ->
{ {
Map<WidgetField, Object> newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( Map<WidgetField<?>, Object> newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap(
Function.identity(), Function.identity(),
i -> i.getValue(w) i -> i.getValue(w)
)); ));
@@ -137,9 +137,9 @@ public class WidgetInfoTableModel extends AbstractTableModel
}); });
} }
private List<WidgetField> populateWidgetFields() private List<WidgetField<?>> populateWidgetFields()
{ {
List<WidgetField> out = new ArrayList<>(); List<WidgetField<?>> out = new ArrayList<>();
out.add(new WidgetField<>("Id", Widget::getId)); out.add(new WidgetField<>("Id", Widget::getId));
out.add(new WidgetField<>("Type", Widget::getType, Widget::setType, Integer.class)); out.add(new WidgetField<>("Type", Widget::getType, Widget::setType, Integer.class));
@@ -209,6 +209,11 @@ public class WidgetInfoTableModel extends AbstractTableModel
} }
return null; 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; return out;
} }

View File

@@ -487,7 +487,7 @@ class WidgetInspector extends DevToolsFrame
client.setSpellSelected(false); client.setSpellSelected(false);
ev.consume(); ev.consume();
Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction().getId(), ev.getParam0(), ev.getParam1()); Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction(), ev.getParam0(), ev.getParam1());
if (target == null) if (target == null)
{ {
return; return;
@@ -516,8 +516,8 @@ class WidgetInspector extends DevToolsFrame
for (int i = 0; i < menuEntries.length; i++) for (int i = 0; i < menuEntries.length; i++)
{ {
MenuEntry entry = menuEntries[i]; MenuEntry entry = menuEntries[i];
if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET.getId() if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET
&& entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId()) && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET)
{ {
continue; continue;
} }
@@ -532,8 +532,6 @@ class WidgetInspector extends DevToolsFrame
entry.setTarget(ColorUtil.wrapWithColorTag(name, color)); entry.setTarget(ColorUtil.wrapWithColorTag(name, color));
} }
client.setMenuEntries(menuEntries);
} }
Color colorForWidget(int index, int length) Color colorForWidget(int index, int length)
@@ -543,9 +541,9 @@ class WidgetInspector extends DevToolsFrame
return Color.getHSBColor(h, 1, 1); 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); Widget w = client.getWidget(param1);
if (param0 != -1) if (param0 != -1)
@@ -555,7 +553,7 @@ class WidgetInspector extends DevToolsFrame
return w; return w;
} }
else if (type == MenuAction.ITEM_USE_ON_WIDGET.getId()) else if (type == MenuAction.ITEM_USE_ON_WIDGET)
{ {
Widget w = client.getWidget(param1); Widget w = client.getWidget(param1);
return w.getWidgetItem(param0); return w.getWidgetItem(param0);

View File

@@ -93,6 +93,7 @@ enum Emoji
XD("Xd"), XD("Xd"),
SPOON("--o"), SPOON("--o"),
WEARY_FACE("Dx"), WEARY_FACE("Dx"),
ROCKETSHIP("<gt>==<gt>"), // >==>
; ;
private static final Map<String, Emoji> emojiMap; private static final Map<String, Emoji> emojiMap;

View File

@@ -28,9 +28,11 @@ import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
@ConfigGroup("friendlist") @ConfigGroup(FriendListConfig.GROUP)
public interface FriendListConfig extends Config public interface FriendListConfig extends Config
{ {
String GROUP = "friendlist";
@ConfigItem( @ConfigItem(
keyName = "showWorldOnLogin", keyName = "showWorldOnLogin",
name = "Show world on login", name = "Show world on login",

View File

@@ -26,30 +26,40 @@
package net.runelite.client.plugins.friendlist; package net.runelite.client.plugins.friendlist;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.time.temporal.ChronoUnit;
import java.util.Iterator;
import javax.inject.Inject; import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.ChatPlayer; import net.runelite.api.ChatPlayer;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Friend; import net.runelite.api.Friend;
import net.runelite.api.Ignore; import net.runelite.api.Ignore;
import net.runelite.api.MenuAction;
import net.runelite.api.MessageNode; import net.runelite.api.MessageNode;
import net.runelite.api.NameableContainer; import net.runelite.api.NameableContainer;
import net.runelite.api.PendingLogin;
import net.runelite.api.ScriptID; import net.runelite.api.ScriptID;
import net.runelite.api.VarPlayer; import net.runelite.api.VarPlayer;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.ScriptPostFired; import net.runelite.api.events.ScriptPostFired;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; 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.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.task.Schedule;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
@PluginDescriptor( @PluginDescriptor(
name = "Friend List", name = "Friend List",
description = "Add extra information to the friend and ignore lists" description = "Add extra information to the friend and ignore lists"
) )
@Slf4j
public class FriendListPlugin extends Plugin public class FriendListPlugin extends Plugin
{ {
private static final int MAX_FRIENDS_P2P = 400; 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_P2P = 400;
private static final int MAX_IGNORES_F2P = 100; 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 @Inject
private Client client; private Client client;
@Inject @Inject
private FriendListConfig config; private FriendListConfig config;
@Inject
private ConfigManager configManager;
@Inject
private ChatMessageManager chatMessageManager;
@Provides @Provides
FriendListConfig getConfig(ConfigManager configManager) 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<PendingLogin> 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) private void setFriendsListTitle(final String title)
{ {
Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE); Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE);
@@ -173,4 +234,21 @@ public class FriendListPlugin extends Plugin
return null; 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;
}
} }

View File

@@ -28,7 +28,6 @@
package net.runelite.client.plugins.friendnotes; package net.runelite.client.plugins.friendnotes;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ObjectArrays;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -43,12 +42,10 @@ import net.runelite.api.GameState;
import net.runelite.api.Ignore; import net.runelite.api.Ignore;
import net.runelite.api.IndexedSprite; import net.runelite.api.IndexedSprite;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Nameable; import net.runelite.api.Nameable;
import net.runelite.api.ScriptID; import net.runelite.api.ScriptID;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.NameableNameChanged; import net.runelite.api.events.NameableNameChanged;
import net.runelite.api.events.RemovedFriend; import net.runelite.api.events.RemovedFriend;
import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptCallbackEvent;
@@ -235,7 +232,7 @@ public class FriendNotesPlugin extends Plugin
@Subscribe @Subscribe
public void onMenuEntryAdded(MenuEntryAdded event) 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 // Look for "Message" on friends list
if ((groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) || 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()))); setHoveredFriend(Text.toJagexName(Text.removeTags(event.getTarget())));
// Build "Add Note" or "Edit Note" menu entry // Build "Add Note" or "Edit Note" menu entry
final MenuEntry addNote = new MenuEntry(); client.createMenuEntry(-1)
addNote.setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE); .setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE)
addNote.setType(MenuAction.RUNELITE.getId()); .setType(MenuAction.RUNELITE)
addNote.setTarget(event.getTarget()); //Preserve color codes here .setTarget(event.getTarget()) //Preserve color codes here
addNote.setParam0(event.getActionParam0()); .onClick(e ->
addNote.setParam1(event.getParam1()); {
//Friends have color tags
final String sanitizedTarget = Text.toJagexName(Text.removeTags(e.getTarget()));
final String note = getFriendNote(sanitizedTarget);
// Add menu entry // Open the new chatbox input dialog
final MenuEntry[] menuEntries = ObjectArrays.concat(client.getMenuEntries(), addNote); chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT))
client.setMenuEntries(menuEntries); .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) 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 @Subscribe
public void onNameableNameChanged(NameableNameChanged event) public void onNameableNameChanged(NameableNameChanged event)
{ {

View File

@@ -1608,7 +1608,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
modelY = y + client.getCameraY2(); modelY = y + client.getCameraY2();
modelZ = z + client.getCameraZ2(); modelZ = z + client.getCameraZ2();
modelOrientation = orientation; modelOrientation = orientation;
int triangleCount = model.getTrianglesCount(); int triangleCount = model.getFaceCount();
vertexBuffer.ensureCapacity(12 * triangleCount); vertexBuffer.ensureCapacity(12 * triangleCount);
uvBuffer.ensureCapacity(12 * triangleCount); uvBuffer.ensureCapacity(12 * triangleCount);
@@ -1632,7 +1632,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
model.calculateExtreme(orientation); model.calculateExtreme(orientation);
client.checkClickbox(model, orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash); 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(); int uvOffset = model.getUvBufferOffset();
GpuIntBuffer b = bufferForTriangles(tc); GpuIntBuffer b = bufferForTriangles(tc);

View File

@@ -379,7 +379,7 @@ class SceneUploader
public int pushModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) 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); vertexBuffer.ensureCapacity(triangleCount * 12);
uvBuffer.ensureCapacity(triangleCount * 12); uvBuffer.ensureCapacity(triangleCount * 12);
@@ -388,20 +388,25 @@ class SceneUploader
final int[] vertexY = model.getVerticesY(); final int[] vertexY = model.getVerticesY();
final int[] vertexZ = model.getVerticesZ(); final int[] vertexZ = model.getVerticesZ();
final int[] trianglesX = model.getTrianglesX(); final int[] indices1 = model.getFaceIndices1();
final int[] trianglesY = model.getTrianglesY(); final int[] indices2 = model.getFaceIndices2();
final int[] trianglesZ = model.getTrianglesZ(); final int[] indices3 = model.getFaceIndices3();
final int[] color1s = model.getFaceColors1(); final int[] color1s = model.getFaceColors1();
final int[] color2s = model.getFaceColors2(); final int[] color2s = model.getFaceColors2();
final int[] color3s = model.getFaceColors3(); final int[] color3s = model.getFaceColors3();
final byte[] transparencies = model.getTriangleTransparencies(); final byte[] transparencies = model.getFaceTransparencies();
final short[] faceTextures = model.getFaceTextures(); final short[] faceTextures = model.getFaceTextures();
final byte[] facePriorities = model.getFaceRenderPriorities(); final byte[] facePriorities = model.getFaceRenderPriorities();
float[] uv = model.getFaceTextureUVCoordinates(); 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; int len = 0;
for (int face = 0; face < triangleCount; ++face) for (int face = 0; face < triangleCount; ++face)
{ {
@@ -429,12 +434,22 @@ class SceneUploader
len += 3; len += 3;
continue; 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 packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face);
int triangleA = trianglesX[face]; int triangleA = indices1[face];
int triangleB = trianglesY[face]; int triangleB = indices2[face];
int triangleC = trianglesZ[face]; int triangleC = indices3[face];
vertexBuffer.put(vertexX[triangleA], vertexY[triangleA], vertexZ[triangleA], packAlphaPriority | color1); vertexBuffer.put(vertexX[triangleA], vertexY[triangleA], vertexZ[triangleA], packAlphaPriority | color1);
vertexBuffer.put(vertexX[triangleB], vertexY[triangleB], vertexZ[triangleB], packAlphaPriority | color2); vertexBuffer.put(vertexX[triangleB], vertexY[triangleB], vertexZ[triangleB], packAlphaPriority | color2);
@@ -458,26 +473,31 @@ class SceneUploader
final int[] vertexY = model.getVerticesY(); final int[] vertexY = model.getVerticesY();
final int[] vertexZ = model.getVerticesZ(); final int[] vertexZ = model.getVerticesZ();
final int[] trianglesX = model.getTrianglesX(); final int[] indices1 = model.getFaceIndices1();
final int[] trianglesY = model.getTrianglesY(); final int[] indices2 = model.getFaceIndices2();
final int[] trianglesZ = model.getTrianglesZ(); final int[] indices3 = model.getFaceIndices3();
final int[] color1s = model.getFaceColors1(); final int[] color1s = model.getFaceColors1();
final int[] color2s = model.getFaceColors2(); final int[] color2s = model.getFaceColors2();
final int[] color3s = model.getFaceColors3(); final int[] color3s = model.getFaceColors3();
final byte[] transparencies = model.getTriangleTransparencies(); final byte[] transparencies = model.getFaceTransparencies();
final short[] faceTextures = model.getFaceTextures(); final short[] faceTextures = model.getFaceTextures();
final byte[] facePriorities = model.getFaceRenderPriorities(); final byte[] facePriorities = model.getFaceRenderPriorities();
int triangleA = trianglesX[face]; final int triangleA = indices1[face];
int triangleB = trianglesY[face]; final int triangleB = indices2[face];
int triangleC = trianglesZ[face]; final int triangleC = indices3[face];
int color1 = color1s[face]; int color1 = color1s[face];
int color2 = color2s[face]; int color2 = color2s[face];
int color3 = color3s[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 packedAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face);
int sin = 0, cos = 0; int sin = 0, cos = 0;
@@ -505,6 +525,16 @@ class SceneUploader
} }
return 3; 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; int a, b, c;
@@ -605,4 +635,28 @@ class SceneUploader
uvBuffer.put(0, 0, 0, 0); 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;
}
} }

View File

@@ -66,6 +66,7 @@ import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry; import net.runelite.api.MenuEntry;
import net.runelite.api.ScriptID; import net.runelite.api.ScriptID;
import net.runelite.api.VarClientStr; import net.runelite.api.VarClientStr;
import net.runelite.api.VarPlayer;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
import net.runelite.api.events.GameStateChanged; 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.MenuEntryAdded;
import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.ScriptPostFired; import net.runelite.api.events.ScriptPostFired;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
@@ -120,10 +120,9 @@ public class GrandExchangePlugin extends Plugin
@VisibleForTesting @VisibleForTesting
static final int GE_SLOTS = 8; static final int GE_SLOTS = 8;
private static final int GE_LOGIN_BURST_WINDOW = 2; // ticks private static final int GE_LOGIN_BURST_WINDOW = 2; // ticks
private static final int OFFER_CONTAINER_ITEM = 21; private static final int GE_MAX_EXAMINE_LEN = 100;
private static final int OFFER_DEFAULT_ITEM_ID = 6512;
private static final String BUY_LIMIT_GE_TEXT = "<br>Buy limit: "; private static final String BUY_LIMIT_GE_TEXT = "Buy limit: ";
private static final String BUY_LIMIT_KEY = "buylimit"; private static final String BUY_LIMIT_KEY = "buylimit";
private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4); private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4);
@@ -182,9 +181,6 @@ public class GrandExchangePlugin extends Plugin
@Inject @Inject
private RuneLiteConfig runeLiteConfig; private RuneLiteConfig runeLiteConfig;
private Widget grandExchangeText;
private String grandExchangeExamine;
@Inject @Inject
private GrandExchangeClient grandExchangeClient; private GrandExchangeClient grandExchangeClient;
private int lastLoginTick; private int lastLoginTick;
@@ -317,7 +313,6 @@ public class GrandExchangePlugin extends Plugin
clientToolbar.removeNavigation(button); clientToolbar.removeNavigation(button);
mouseManager.unregisterMouseListener(inputListener); mouseManager.unregisterMouseListener(inputListener);
keyManager.unregisterKeyListener(inputListener); keyManager.unregisterKeyListener(inputListener);
grandExchangeText = null;
lastUsername = machineUuid = null; lastUsername = machineUuid = null;
tradeSeq = 0; tradeSeq = 0;
} }
@@ -574,8 +569,7 @@ public class GrandExchangePlugin extends Plugin
case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID: case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID:
case WidgetID.SHOP_INVENTORY_GROUP_ID: case WidgetID.SHOP_INVENTORY_GROUP_ID:
menuEntry.setOption(SEARCH_GRAND_EXCHANGE); menuEntry.setOption(SEARCH_GRAND_EXCHANGE);
menuEntry.setType(MenuAction.RUNELITE.getId()); menuEntry.setType(MenuAction.RUNELITE);
client.setMenuEntries(entries);
} }
} }
@@ -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 @Subscribe
public void onScriptPostFired(ScriptPostFired event) public void onScriptPostFired(ScriptPostFired event)
{ {
// GE offers setup init if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch())
if (event.getScriptId() == ScriptID.GE_OFFERS_SETUP_BUILD)
{
rebuildGeText();
}
else if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch())
{ {
highlightSearchMatches(); highlightSearchMatches();
} }
@@ -739,7 +712,30 @@ public class GrandExchangePlugin extends Plugin
@Subscribe @Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent event) 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; return;
} }
@@ -818,39 +814,10 @@ public class GrandExchangePlugin extends Plugin
} }
} }
private void rebuildGeText() private String setExamineText(String examine, String fee)
{ {
if (grandExchangeText == null) final int itemId = client.getVar(VarPlayer.CURRENT_GE_ITEM);
{ StringBuilder sb = new StringBuilder();
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();
if (config.enableGELimits()) if (config.enableGELimits())
{ {
@@ -859,7 +826,7 @@ public class GrandExchangePlugin extends Plugin
// If we have item buy limit, append it // If we have item buy limit, append it
if (itemStats != null && itemStats.getGeLimit() > 0) 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) if (resetTime != null)
{ {
Duration remaining = Duration.between(Instant.now(), resetTime); 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); final int price = itemManager.getItemPriceWithSource(itemId, true);
if (price > 0) if (price > 0)
{ {
text += "<br>Actively traded price: " + QuantityFormatter.formatNumber(price); if (sb.length() > 0)
{
sb.append(" / ");
}
sb.append("Actively traded price: ").append(QuantityFormatter.formatNumber(price));
} }
} }
grandExchangeExamine = text; if (sb.length() == 0)
geText.setText(text); {
return null;
}
return shortenExamine(examine) + "<br>" + sb + "<br>" + 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) void openGeLink(String name, int itemId)

View File

@@ -115,14 +115,6 @@ public class GroundItemsPlugin extends Plugin
static final int MAX_QUANTITY = 65535; static final int MAX_QUANTITY = 65535;
// ItemID for coins // ItemID for coins
private static final int COINS = ItemID.COINS_995; 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); 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]; MenuEntry menuEntry = menuEntries[i];
int menuType = menuEntry.getType(); MenuAction menuType = menuEntry.getType();
if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION if (menuType == MenuAction.GROUND_ITEM_FIRST_OPTION || menuType == MenuAction.GROUND_ITEM_SECOND_OPTION
|| menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM) || 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) for (MenuEntryWithCount entryWCount : newEntries)
{ {
@@ -490,15 +483,15 @@ public class GroundItemsPlugin extends Plugin
{ {
if (config.itemHighlightMode() == ItemHighlightMode.MENU || config.itemHighlightMode() == ItemHighlightMode.BOTH) 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; 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() == THIRD_OPTION) && !telegrabEntry) if (!(event.getOption().equals("Take") && event.getType() == MenuAction.GROUND_ITEM_THIRD_OPTION.getId()) && !telegrabEntry)
{ {
return; return;
} }
final int itemId = event.getIdentifier(); final int itemId = event.getIdentifier();
final int sceneX = event.getActionParam0(); final int sceneX = event.getActionParam0();
final int sceneY = event.getParam1(); final int sceneY = event.getActionParam1();
MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
@@ -548,8 +541,6 @@ public class GroundItemsPlugin extends Plugin
{ {
lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")"); lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")");
} }
client.setMenuEntries(menuEntries);
} }
} }

View File

@@ -30,7 +30,6 @@ import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -44,13 +43,11 @@ import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.KeyCode; import net.runelite.api.KeyCode;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe; 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 GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getRegionX(), worldPoint.getRegionY(), client.getPlane(), null, null);
final boolean exists = getPoints(regionId).contains(point); final boolean exists = getPoints(regionId).contains(point);
MenuEntry[] menuEntries = client.getMenuEntries(); client.createMenuEntry(-1)
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + (exists ? 2 : 1)); .setOption(exists ? UNMARK : MARK)
.setTarget(event.getTarget())
MenuEntry mark = menuEntries[menuEntries.length - 1] = new MenuEntry(); .setType(MenuAction.RUNELITE)
mark.setOption(exists ? UNMARK : MARK); .onClick(e ->
mark.setTarget(event.getTarget()); {
mark.setType(MenuAction.RUNELITE.getId()); Tile target = client.getSelectedSceneTile();
if (target != null)
{
markTile(target.getLocalLocation());
}
})
// TODO: remove
.add(client);
if (exists) if (exists)
{ {
MenuEntry label = menuEntries[menuEntries.length - 2] = new MenuEntry(); client.createMenuEntry(-2)
label.setOption(LABEL); .setOption(LABEL)
label.setTarget(event.getTarget()); .setTarget(event.getTarget())
label.setType(MenuAction.RUNELITE.getId()); .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);
} }
} }

View File

@@ -45,11 +45,10 @@ import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; 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 static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS;
import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage; import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.MenuManager;
import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.menus.WidgetMenuOption;
@@ -82,13 +81,13 @@ class GroundMarkerSharingManager
void addImportExportMenuOptions() void addImportExportMenuOptions()
{ {
menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION); menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION, this::exportGroundMarkers);
menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION); menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION, this::promptForImport);
} }
void addClearMenuOption() void addClearMenuOption()
{ {
menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION); menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION, this::promptForClear);
} }
void removeMenuOptions() void removeMenuOptions()
@@ -98,36 +97,7 @@ class GroundMarkerSharingManager
menuManager.removeManagedCustomMenu(CLEAR_MARKERS_OPTION); menuManager.removeManagedCustomMenu(CLEAR_MARKERS_OPTION);
} }
private boolean widgetMenuClickedEquals(final WidgetMenuOptionClicked event, final WidgetMenuOption target) private void exportGroundMarkers(MenuEntry menuEntry)
{
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()
{ {
int[] regions = client.getMapRegions(); int[] regions = client.getMapRegions();
if (regions == null) if (regions == null)
@@ -156,7 +126,7 @@ class GroundMarkerSharingManager
sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard."); sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard.");
} }
private void promptForImport() private void promptForImport(MenuEntry menuEntry)
{ {
final String clipboardText; final String clipboardText;
try try
@@ -244,7 +214,7 @@ class GroundMarkerSharingManager
sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard."); sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard.");
} }
private void promptForClear() private void promptForClear(MenuEntry entry)
{ {
int[] regions = client.getMapRegions(); int[] regions = client.getMapRegions();
if (regions == null) if (regions == null)

View File

@@ -105,13 +105,13 @@ public class HiscorePanel extends PluginPanel
GIANT_MOLE, GROTESQUE_GUARDIANS, HESPORI, GIANT_MOLE, GROTESQUE_GUARDIANS, HESPORI,
KALPHITE_QUEEN, KING_BLACK_DRAGON, KRAKEN, KALPHITE_QUEEN, KING_BLACK_DRAGON, KRAKEN,
KREEARRA, KRIL_TSUTSAROTH, MIMIC, KREEARRA, KRIL_TSUTSAROTH, MIMIC,
NIGHTMARE, PHOSANIS_NIGHTMARE, OBOR, SARACHNIS, NEX, NIGHTMARE, PHOSANIS_NIGHTMARE,
SCORPIA, SKOTIZO, TEMPOROSS, OBOR, SARACHNIS, SCORPIA,
THE_GAUNTLET, THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, SKOTIZO, TEMPOROSS, THE_GAUNTLET,
THEATRE_OF_BLOOD_HARD_MODE, THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, THEATRE_OF_BLOOD_HARD_MODE,
TZTOK_JAD, VENENATIS, VETION, THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, TZTOK_JAD,
VORKATH, WINTERTODT, ZALCANO, VENENATIS, VETION, VORKATH,
ZULRAH WINTERTODT, ZALCANO, ZULRAH
); );
private static final HiscoreEndpoint[] ENDPOINTS = { private static final HiscoreEndpoint[] ENDPOINTS = {

View File

@@ -24,7 +24,6 @@
*/ */
package net.runelite.client.plugins.hiscore; package net.runelite.client.plugins.hiscore;
import com.google.common.collect.ObjectArrays;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.EnumSet; import java.util.EnumSet;
@@ -39,7 +38,6 @@ import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.IconID; import net.runelite.api.IconID;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.WorldType; import net.runelite.api.WorldType;
import net.runelite.api.events.ChatMessage; 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.ImageUtil;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.http.api.hiscore.HiscoreEndpoint; import net.runelite.http.api.hiscore.HiscoreEndpoint;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor( @PluginDescriptor(
name = "HiScore", 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")) || groupId == WidgetID.GROUP_IRON_GROUP_ID && (option.equals("Add friend") || option.equals("Remove friend") || option.equals("Remove ignore"))
) )
{ {
final MenuEntry lookup = new MenuEntry(); client.createMenuEntry(-2)
lookup.setOption(LOOKUP); .setOption(LOOKUP)
lookup.setTarget(event.getTarget()); .setTarget(event.getTarget())
lookup.setType(MenuAction.RUNELITE.getId()); .setType(MenuAction.RUNELITE)
lookup.setParam0(event.getActionParam0()); .setIdentifier(event.getIdentifier())
lookup.setParam1(event.getActionParam1()); .onClick(e ->
lookup.setIdentifier(event.getIdentifier()); {
// Determine proper endpoint from player name.
insertMenuEntry(lookup, client.getMenuEntries()); // 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 @Subscribe
public void onMenuOptionClicked(MenuOptionClicked event) public void onMenuOptionClicked(MenuOptionClicked event)
{ {
if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER) if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER && event.getMenuOption().equals(LOOKUP))
&& event.getMenuOption().equals(LOOKUP))
{ {
final String target; // The player id is included in the event, so we can use that to get the player name,
HiscoreEndpoint endpoint; // which avoids having to parse out the combat level and any icons preceding the name.
if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER) 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, return;
// 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;
}
endpoint = getWorldEndpoint(); String target = player.getName();
target = player.getName(); HiscoreEndpoint endpoint = getWorldEndpoint();
}
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());
}
lookupPlayer(target, endpoint); lookupPlayer(target, endpoint);
} }
@@ -236,14 +226,6 @@ public class HiscorePlugin extends Plugin
localHiscoreEndpoint = findHiscoreEndpointFromLocalPlayer(); 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) private void lookupPlayer(String playerName, HiscoreEndpoint endpoint)
{ {
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(() ->

View File

@@ -242,6 +242,7 @@ class NameAutocompleter implements KeyListener
autocompleteName = Arrays.stream(cachedPlayers) autocompleteName = Arrays.stream(cachedPlayers)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.map(Player::getName) .map(Player::getName)
.filter(Objects::nonNull)
.filter(n -> pattern.matcher(n).matches()) .filter(n -> pattern.matcher(n).matches())
.findFirst(); .findFirst();
} }

View File

@@ -27,7 +27,6 @@ package net.runelite.client.plugins.instancemap;
import com.google.inject.Binder; import com.google.inject.Binder;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.WidgetMenuOptionClicked;
import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
@@ -72,7 +71,17 @@ public class InstanceMapPlugin extends Plugin
private void addCustomOptions() private void addCustomOptions()
{ {
menuManager.addManagedCustomMenu(openMapOption); menuManager.addManagedCustomMenu(openMapOption, entry ->
{
if (overlay.isMapShown())
{
closeMap();
}
else
{
showMap();
}
});
} }
private void removeCustomOptions() private void removeCustomOptions()
@@ -107,32 +116,6 @@ public class InstanceMapPlugin extends Plugin
overlay.onGameStateChange(event); 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() public void showMap()
{ {
overlay.setShowMap(true); overlay.setShowMap(true);

View File

@@ -79,7 +79,7 @@ class InteractHighlightOverlay extends Overlay
} }
MenuEntry top = menuEntries[menuEntries.length - 1]; MenuEntry top = menuEntries[menuEntries.length - 1];
MenuAction menuAction = MenuAction.of(top.getType()); MenuAction menuAction = top.getType();
switch (menuAction) switch (menuAction)
{ {

View File

@@ -28,14 +28,13 @@ import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry; import net.runelite.api.MenuEntry;
import net.runelite.api.events.MenuOpened; 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.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; 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.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.Text;
@PluginDescriptor( @PluginDescriptor(
name = "Inventory Tags", 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 @Subscribe
public void onMenuOpened(final MenuOpened event) public void onMenuOpened(final MenuOpened event)
{ {
final MenuEntry firstEntry = event.getFirstEntry(); final MenuEntry firstEntry = event.getFirstEntry();
if (firstEntry == null || !editorMode)
if (firstEntry == null)
{ {
return; return;
} }
@@ -202,7 +167,7 @@ public class InventoryTagsPlugin extends Plugin
final int widgetId = firstEntry.getParam1(); final int widgetId = firstEntry.getParam1();
// Inventory item menu // Inventory item menu
if (widgetId == WidgetInfo.INVENTORY.getId() && editorMode) if (widgetId == WidgetInfo.INVENTORY.getId())
{ {
int itemId = firstEntry.getIdentifier(); int itemId = firstEntry.getIdentifier();
@@ -211,26 +176,32 @@ public class InventoryTagsPlugin extends Plugin
return; return;
} }
MenuEntry[] menuList = new MenuEntry[GROUPS.size() + 1]; // Set menu to only be Cancel
int num = 0; client.setMenuEntries(Arrays.copyOf(client.getMenuEntries(), 1));
// preserve the 'Cancel' option as the client will reuse the first entry for Cancel and only resets option/action
menuList[num++] = event.getMenuEntries()[0];
for (final String groupName : GROUPS) for (final String groupName : GROUPS)
{ {
final String group = getTag(itemId); final String group = getTag(itemId);
final MenuEntry newMenu = new MenuEntry();
final Color color = getGroupNameColor(groupName); 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(); removeInventoryMenuOptions();
if (editorMode) if (editorMode)
{ {
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE); menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE); menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE); menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE, this::save);
} }
else else
{ {
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE); menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE); menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_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();
}
} }

View File

@@ -90,7 +90,7 @@ class ItemPricesOverlay extends Overlay
} }
final MenuEntry menuEntry = menuEntries[last]; final MenuEntry menuEntry = menuEntries[last];
final MenuAction action = MenuAction.of(menuEntry.getType()); final MenuAction action = menuEntry.getType();
final int widgetId = menuEntry.getParam1(); final int widgetId = menuEntry.getParam1();
final int groupId = WidgetInfo.TO_GROUP(widgetId); final int groupId = WidgetInfo.TO_GROUP(widgetId);
final boolean isAlching = menuEntry.getOption().equals("Cast") && menuEntry.getTarget().contains("High Level Alchemy"); final boolean isAlching = menuEntry.getOption().equals("Cast") && menuEntry.getTarget().contains("High Level Alchemy");

View File

@@ -56,7 +56,6 @@ import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOpened;
import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.PostItemComposition; import net.runelite.api.events.PostItemComposition;
import net.runelite.api.events.WidgetMenuOptionClicked;
import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread; 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.MorytaniaLegsMode;
import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.RadasBlessingMode; import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.RadasBlessingMode;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Menu Entry Swapper", name = "Menu Entry Swapper",
@@ -516,24 +514,6 @@ public class MenuEntrySwapperPlugin extends Plugin
clientThread.invoke(this::resetItemCompositionCache); 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 @Subscribe
public void onMenuOpened(MenuOpened event) public void onMenuOpened(MenuOpened event)
{ {
@@ -601,11 +581,11 @@ public class MenuEntrySwapperPlugin extends Plugin
for (MenuEntry entry : entries) 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) if (ITEM_MENU_TYPES.contains(menuAction) && entry.getIdentifier() == itemId)
{ {
entry.setType(MenuAction.RUNELITE.getId()); entry.setType(MenuAction.RUNELITE);
if (activeAction == menuAction) if (activeAction == menuAction)
{ {
@@ -614,13 +594,13 @@ public class MenuEntrySwapperPlugin extends Plugin
} }
} }
final MenuEntry resetShiftClickEntry = new MenuEntry(); client.createMenuEntry(-1)
resetShiftClickEntry.setOption(RESET); .setOption(RESET)
resetShiftClickEntry.setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET); .setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET)
resetShiftClickEntry.setIdentifier(itemId); .setType(MenuAction.RUNELITE)
resetShiftClickEntry.setParam1(widgetId); .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId))
resetShiftClickEntry.setType(MenuAction.RUNELITE.getId()); // TODO: remove
client.setMenuEntries(ArrayUtils.addAll(entries, resetShiftClickEntry)); .add(client);
} }
@Subscribe @Subscribe
@@ -646,8 +626,8 @@ public class MenuEntrySwapperPlugin extends Plugin
final int opId = isDepositBoxPlayerInventory ? shiftDepositMode.getIdentifierDepositBox() final int opId = isDepositBoxPlayerInventory ? shiftDepositMode.getIdentifierDepositBox()
: isChambersOfXericStorageUnitPlayerInventory ? shiftDepositMode.getIdentifierChambersStorageUnit() : isChambersOfXericStorageUnitPlayerInventory ? shiftDepositMode.getIdentifierChambersStorageUnit()
: shiftDepositMode.getIdentifier(); : shiftDepositMode.getIdentifier();
final int actionId = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY.getId() : MenuAction.CC_OP.getId(); final MenuAction action = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY : MenuAction.CC_OP;
bankModeSwap(actionId, opId); bankModeSwap(action, opId);
} }
// Swap to shift-click withdraw behavior // Swap to shift-click withdraw behavior
@@ -657,22 +637,23 @@ public class MenuEntrySwapperPlugin extends Plugin
&& menuEntryAdded.getOption().startsWith("Withdraw")) && menuEntryAdded.getOption().startsWith("Withdraw"))
{ {
ShiftWithdrawMode shiftWithdrawMode = config.bankWithdrawShiftClick(); 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) 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(); opId = shiftWithdrawMode.getIdentifierChambersStorageUnit();
} }
else else
{ {
actionId = shiftWithdrawMode.getMenuAction().getId(); action = shiftWithdrawMode.getMenuAction();
opId = shiftWithdrawMode.getIdentifier(); 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(); MenuEntry[] menuEntries = client.getMenuEntries();
@@ -680,10 +661,10 @@ public class MenuEntrySwapperPlugin extends Plugin
{ {
MenuEntry entry = menuEntries[i]; 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 // 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[i] = menuEntries[menuEntries.length - 1];
menuEntries[menuEntries.length - 1] = entry; menuEntries[menuEntries.length - 1] = entry;
@@ -713,17 +694,6 @@ public class MenuEntrySwapperPlugin extends Plugin
String target = event.getMenuTarget(); String target = event.getMenuTarget();
ItemComposition itemComposition = itemManager.getItemComposition(itemId); 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))) if (!itemComposition.getName().equals(Text.removeTags(target)))
{ {
return; return;
@@ -751,7 +721,7 @@ public class MenuEntrySwapperPlugin extends Plugin
private void swapMenuEntry(MenuEntry[] menuEntries, int index, MenuEntry menuEntry) private void swapMenuEntry(MenuEntry[] menuEntries, int index, MenuEntry menuEntry)
{ {
final int eventId = menuEntry.getIdentifier(); 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 option = Text.removeTags(menuEntry.getOption()).toLowerCase();
final String target = Text.removeTags(menuEntry.getTarget()).toLowerCase(); final String target = Text.removeTags(menuEntry.getTarget()).toLowerCase();
final NPC hintArrowNpc = client.getHintArrowNpc(); final NPC hintArrowNpc = client.getHintArrowNpc();
@@ -978,31 +948,31 @@ public class MenuEntrySwapperPlugin extends Plugin
removeCusomizationMenus(); removeCusomizationMenus();
if (configuringLeftClick) if (configuringLeftClick)
{ {
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC); menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC); menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC); menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC, this::save);
} }
else if (configuringShiftClick) else if (configuringShiftClick)
{ {
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC); menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC); menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC); menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC, this::save);
} }
else else
{ {
// Left click // Left click
if (config.leftClickCustomization()) if (config.leftClickCustomization())
{ {
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC); menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC); menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC); menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC, this::configure);
} }
// Shift click // Shift click
if (config.shiftClickCustomization()) if (config.shiftClickCustomization())
{ {
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC); menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC); menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC); menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC, this::configure);
} }
} }
} }
@@ -1011,4 +981,18 @@ public class MenuEntrySwapperPlugin extends Plugin
{ {
return client.isKeyPressed(KeyCode.KC_SHIFT); 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();
}
} }

View File

@@ -108,7 +108,7 @@ class MouseHighlightOverlay extends Overlay
MenuEntry menuEntry = menuEntries[last]; MenuEntry menuEntry = menuEntries[last];
String target = menuEntry.getTarget(); String target = menuEntry.getTarget();
String option = menuEntry.getOption(); 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) if (type == MenuAction.RUNELITE_OVERLAY || type == MenuAction.CC_OP_LOW_PRIORITY)
{ {

View File

@@ -91,13 +91,6 @@ class NightmareZoneOverlay extends OverlayPanel
return null; return null;
} }
Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE);
if (nmzWidget != null)
{
nmzWidget.setHidden(true);
}
renderAbsorptionCounter(); renderAbsorptionCounter();
final int currentPoints = client.getVar(Varbits.NMZ_POINTS); final int currentPoints = client.getVar(Varbits.NMZ_POINTS);

View File

@@ -33,6 +33,7 @@ import lombok.Getter;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.events.BeforeRender;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;
@@ -121,6 +122,21 @@ public class NightmareZonePlugin extends Plugin
return configManager.getConfig(NightmareZoneConfig.class); 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 @Subscribe
public void onGameTick(GameTick event) public void onGameTick(GameTick event)
{ {

View File

@@ -31,7 +31,6 @@ import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; 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.GameTick;
import net.runelite.api.events.GraphicsObjectCreated; import net.runelite.api.events.GraphicsObjectCreated;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcChanged;
import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.NpcSpawned;
@@ -271,7 +269,6 @@ public class NpcIndicatorsPlugin extends Plugin
final MenuEntry menuEntry = menuEntries[menuEntries.length - 1]; final MenuEntry menuEntry = menuEntries[menuEntries.length - 1];
final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color); final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color);
menuEntry.setTarget(target); menuEntry.setTarget(target);
client.setMenuEntries(menuEntries);
} }
} }
else if (menuAction == MenuAction.EXAMINE_NPC && client.isKeyPressed(KeyCode.KC_SHIFT)) 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)) .filter(highlight -> !highlight.equalsIgnoreCase(npcName))
.anyMatch(highlight -> WildcardMatcher.matches(highlight, 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 // Only add Untag-All option to npcs not highlighted by a wildcard entry, because untag-all will not remove wildcards
if (!matchesList) if (!matchesList)
{ {
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 2); client.createMenuEntry(-1)
final MenuEntry tagAllEntry = menuEntries[menuEntries.length - 2] = new MenuEntry(); .setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL)
tagAllEntry.setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL); .setTarget(event.getTarget())
tagAllEntry.setTarget(event.getTarget()); .setIdentifier(event.getIdentifier())
tagAllEntry.setParam0(event.getActionParam0()); .setType(MenuAction.RUNELITE)
tagAllEntry.setParam1(event.getParam1()); .onClick(this::tag)
tagAllEntry.setIdentifier(event.getIdentifier()); // TODO: remove
tagAllEntry.setType(MenuAction.RUNELITE.getId()); .add(client);
}
else
{
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
} }
final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); client.createMenuEntry(-1)
tagEntry.setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG); .setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG)
tagEntry.setTarget(event.getTarget()); .setTarget(event.getTarget())
tagEntry.setParam0(event.getActionParam0()); .setIdentifier(event.getIdentifier())
tagEntry.setParam1(event.getParam1()); .setType(MenuAction.RUNELITE)
tagEntry.setIdentifier(event.getIdentifier()); .onClick(this::tag)
tagEntry.setType(MenuAction.RUNELITE.getId()); // TODO: remove
.add(client);
client.setMenuEntries(menuEntries);
} }
} }
@Subscribe private void tag(MenuEntry entry)
public void onMenuOptionClicked(MenuOptionClicked click)
{ {
if (click.getMenuAction() != MenuAction.RUNELITE || final int id = entry.getIdentifier();
!(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 NPC[] cachedNPCs = client.getCachedNPCs(); final NPC[] cachedNPCs = client.getCachedNPCs();
final NPC npc = cachedNPCs[id]; final NPC npc = cachedNPCs[id];
@@ -341,7 +323,7 @@ public class NpcIndicatorsPlugin extends Plugin
return; 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); 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 // this trips a config change which triggers the overlay rebuild
updateNpcsToHighlight(name); updateNpcsToHighlight(name);
} }
click.consume();
} }
@Subscribe @Subscribe

View File

@@ -31,7 +31,6 @@ import com.google.gson.reflect.TypeToken;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; 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.GroundObjectDespawned;
import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.GroundObjectSpawned;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectChanged;
import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectDespawned;
import net.runelite.api.events.WallObjectSpawned; import net.runelite.api.events.WallObjectSpawned;
@@ -222,7 +220,7 @@ public class ObjectIndicatorsPlugin extends Plugin
return; 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()); final TileObject tileObject = findTileObject(tile, event.getIdentifier());
if (tileObject == null) if (tileObject == null)
@@ -230,35 +228,28 @@ public class ObjectIndicatorsPlugin extends Plugin
return; return;
} }
MenuEntry[] menuEntries = client.getMenuEntries(); client.createMenuEntry(-1)
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); .setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK)
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); .setTarget(event.getTarget())
menuEntry.setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK); .setParam0(event.getActionParam0())
menuEntry.setTarget(event.getTarget()); .setParam1(event.getActionParam1())
menuEntry.setParam0(event.getActionParam0()); .setIdentifier(event.getIdentifier())
menuEntry.setParam1(event.getParam1()); .setType(MenuAction.RUNELITE)
menuEntry.setIdentifier(event.getIdentifier()); .onClick(this::markObject)
menuEntry.setType(MenuAction.RUNELITE.getId()); // TODO: remove
client.setMenuEntries(menuEntries); .add(client);
} }
@Subscribe private void markObject(MenuEntry entry)
public void onMenuOptionClicked(MenuOptionClicked event)
{ {
if (event.getMenuAction() != MenuAction.RUNELITE
|| !(event.getMenuOption().equals(MARK) || event.getMenuOption().equals(UNMARK)))
{
return;
}
Scene scene = client.getScene(); Scene scene = client.getScene();
Tile[][][] tiles = scene.getTiles(); Tile[][][] tiles = scene.getTiles();
final int x = event.getParam0(); final int x = entry.getParam0();
final int y = event.getParam1(); final int y = entry.getParam1();
final int z = client.getPlane(); final int z = client.getPlane();
final Tile tile = tiles[z][x][y]; final Tile tile = tiles[z][x][y];
TileObject object = findTileObject(tile, event.getId()); TileObject object = findTileObject(tile, entry.getIdentifier());
if (object == null) if (object == null)
{ {
return; return;

View File

@@ -184,7 +184,6 @@ public class OpponentInfoPlugin extends Plugin
{ {
MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry[] menuEntries = client.getMenuEntries();
menuEntries[menuEntries.length - 1].setTarget("*" + menuEntries[menuEntries.length - 1].getTarget()); menuEntries[menuEntries.length - 1].setTarget("*" + menuEntries[menuEntries.length - 1].getTarget());
client.setMenuEntries(menuEntries);
} }
} }
} }

View File

@@ -99,4 +99,23 @@ public interface PartyConfig extends Config
{ {
return false; return false;
} }
@ConfigItem(
keyName = "previousPartyId",
name = "",
description = "",
hidden = true
)
default String previousPartyId()
{
return "";
}
@ConfigItem(
keyName = "previousPartyId",
name = "",
description = "",
hidden = true
)
void setPreviousPartyId(String id);
} }

View File

@@ -26,6 +26,12 @@ package net.runelite.client.plugins.party;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.awt.BorderLayout; 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.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@@ -55,6 +61,9 @@ class PartyPanel extends PluginPanel
private final Map<UUID, PartyMemberBox> memberBoxes = new HashMap<>(); private final Map<UUID, PartyMemberBox> memberBoxes = new HashMap<>();
private final JButton startButton = new JButton(); 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 noPartyPanel = new PluginErrorPanel();
private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel(); private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel();
@@ -79,10 +88,29 @@ class PartyPanel extends PluginPanel
final JPanel topPanel = new JPanel(); final JPanel topPanel = new JPanel();
topPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); topPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
topPanel.setLayout(new BorderLayout()); 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(topPanel);
layoutPanel.add(requestBoxPanel); layoutPanel.add(requestBoxPanel);
@@ -91,7 +119,14 @@ class PartyPanel extends PluginPanel
startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT);
startButton.setFocusable(false); 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 -> 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."); noPartyPanel.setContent("Not in a party", "Create a party to begin.");
partyEmptyPanel.setContent("Party created", "You can now invite friends!"); partyEmptyPanel.setContent("Party created", "You can now invite friends!");
@@ -127,6 +219,9 @@ class PartyPanel extends PluginPanel
remove(partyEmptyPanel); remove(partyEmptyPanel);
startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); 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()) if (!party.isInParty())
{ {

View File

@@ -66,8 +66,8 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.discord.DiscordService; import net.runelite.client.discord.DiscordService;
import net.runelite.client.discord.events.DiscordJoinRequest; import net.runelite.client.discord.events.DiscordJoinRequest;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyChanged;
import net.runelite.client.events.PartyMemberAvatar; import net.runelite.client.events.PartyMemberAvatar;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
@@ -585,6 +585,11 @@ public class PartyPlugin extends Plugin
pendingTilePings.clear(); pendingTilePings.clear();
worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance);
if (event.getPartyId() != null)
{
config.setPreviousPartyId(String.valueOf(event.getPartyId()));
}
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(() ->
{ {
panel.removeAllMembers(); panel.removeAllMembers();

View File

@@ -31,8 +31,8 @@ import lombok.Value;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.FriendsChatRank; import net.runelite.api.FriendsChatRank;
import static net.runelite.api.FriendsChatRank.UNRANKED; 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.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_EIGTH_OPTION;
import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION;
import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION;
@@ -118,29 +118,23 @@ public class PlayerIndicatorsPlugin extends Plugin
} }
MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry[] menuEntries = client.getMenuEntries();
boolean modified = false;
for (MenuEntry entry : menuEntries) for (MenuEntry entry : menuEntries)
{ {
int type = entry.getType(); MenuAction type = entry.getType();
if (type >= MENU_ACTION_DEPRIORITIZE_OFFSET) if (type == WALK
{ || type == SPELL_CAST_ON_PLAYER
type -= MENU_ACTION_DEPRIORITIZE_OFFSET; || type == ITEM_USE_ON_PLAYER
} || type == PLAYER_FIRST_OPTION
|| type == PLAYER_SECOND_OPTION
if (type == WALK.getId() || type == PLAYER_THIRD_OPTION
|| type == SPELL_CAST_ON_PLAYER.getId() || type == PLAYER_FOURTH_OPTION
|| type == ITEM_USE_ON_PLAYER.getId() || type == PLAYER_FIFTH_OPTION
|| type == PLAYER_FIRST_OPTION.getId() || type == PLAYER_SIXTH_OPTION
|| type == PLAYER_SECOND_OPTION.getId() || type == PLAYER_SEVENTH_OPTION
|| type == PLAYER_THIRD_OPTION.getId() || type == PLAYER_EIGTH_OPTION
|| type == PLAYER_FOURTH_OPTION.getId() || type == RUNELITE_PLAYER)
|| type == PLAYER_FIFTH_OPTION.getId()
|| type == PLAYER_SIXTH_OPTION.getId()
|| type == PLAYER_SEVENTH_OPTION.getId()
|| type == PLAYER_EIGTH_OPTION.getId()
|| type == RUNELITE_PLAYER.getId())
{ {
Player[] players = client.getCachedPlayers(); Player[] players = client.getCachedPlayers();
Player player = null; Player player = null;
@@ -149,7 +143,7 @@ public class PlayerIndicatorsPlugin extends Plugin
// 'Walk here' identifiers are offset by 1 because the default // 'Walk here' identifiers are offset by 1 because the default
// identifier for this option is 0, which is also a player index. // identifier for this option is 0, which is also a player index.
if (type == WALK.getId()) if (type == WALK)
{ {
identifier--; identifier--;
} }
@@ -175,14 +169,8 @@ public class PlayerIndicatorsPlugin extends Plugin
String newTarget = decorateTarget(oldTarget, decorations); String newTarget = decorateTarget(oldTarget, decorations);
entry.setTarget(newTarget); entry.setTarget(newTarget);
modified = true;
} }
} }
if (modified)
{
client.setMenuEntries(menuEntries);
}
} }
private Decorations getDecorations(Player player) private Decorations getDecorations(Player player)

View File

@@ -70,7 +70,7 @@ import okhttp3.HttpUrl;
) )
public class WikiPlugin extends Plugin 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 HttpUrl WIKI_API = WIKI_BASE.newBuilder().addPathSegments("api.php").build();
static final String UTM_SORUCE_KEY = "utm_source"; static final String UTM_SORUCE_KEY = "utm_source";
static final String UTM_SORUCE_VALUE = "runelite"; static final String UTM_SORUCE_VALUE = "runelite";
@@ -335,20 +335,6 @@ public class WikiPlugin extends Plugin
LinkBrowser.browse(url.toString()); LinkBrowser.browse(url.toString());
return; 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() private void openSearchInput()
@@ -371,18 +357,18 @@ public class WikiPlugin extends Plugin
public void onMenuEntryAdded(MenuEntryAdded event) public void onMenuEntryAdded(MenuEntryAdded event)
{ {
int widgetIndex = event.getActionParam0(); int widgetIndex = event.getActionParam0();
int widgetID = event.getParam1(); int widgetID = event.getActionParam1();
MenuEntry[] menuEntries = client.getMenuEntries();
if (wikiSelected && event.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) if (wikiSelected && event.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId())
{ {
MenuEntry[] menuEntries = client.getMenuEntries();
Widget w = getWidget(widgetID, widgetIndex); Widget w = getWidget(widgetID, widgetIndex);
if (w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1) if (w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1)
{ {
for (int ourEntry = menuEntries.length - 1;ourEntry >= 0; ourEntry--) for (int ourEntry = menuEntries.length - 1;ourEntry >= 0; ourEntry--)
{ {
MenuEntry entry = menuEntries[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()); int id = itemManager.canonicalize(w.getItemId());
String name = itemManager.getItemComposition(id).getName(); String name = itemManager.getItemComposition(id).getName();
@@ -390,7 +376,6 @@ public class WikiPlugin extends Plugin
break; break;
} }
} }
client.setMenuEntries(menuEntries);
} }
else else
{ {
@@ -400,7 +385,7 @@ public class WikiPlugin extends Plugin
MenuEntry[] oldEntries = menuEntries; MenuEntry[] oldEntries = menuEntries;
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length - 1); menuEntries = Arrays.copyOf(menuEntries, menuEntries.length - 1);
for (int ourEntry = oldEntries.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--) ourEntry--)
{ {
menuEntries[ourEntry - 1] = oldEntries[ourEntry]; menuEntries[ourEntry - 1] = oldEntries[ourEntry];
@@ -425,16 +410,17 @@ public class WikiPlugin extends Plugin
return; return;
} }
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); client.createMenuEntry(-1)
.setTarget(action.replace("View ", "").replace(" guide", ""))
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); .setOption(MENUOP_WIKI)
menuEntry.setTarget(action.replace("View ", "").replace(" guide", "")); .setType(MenuAction.RUNELITE)
menuEntry.setOption(MENUOP_WIKI); .onClick(ev -> LinkBrowser.browse(WIKI_BASE.newBuilder()
menuEntry.setParam0(widgetIndex); .addPathSegment("w")
menuEntry.setParam1(widgetID); .addPathSegment(Text.removeTags(ev.getTarget()))
menuEntry.setType(MenuAction.RUNELITE.getId()); .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE)
.build().toString()))
client.setMenuEntries(menuEntries); // TODO: remove
.add(client);
} }
} }
} }

View File

@@ -53,26 +53,27 @@ import static net.runelite.api.ObjectID.WILLOW_10833;
import static net.runelite.api.ObjectID.YEW; import static net.runelite.api.ObjectID.YEW;
import static net.runelite.api.NullObjectID.NULL_10823; import static net.runelite.api.NullObjectID.NULL_10823;
import static net.runelite.api.ObjectID.YEW_36683; import static net.runelite.api.ObjectID.YEW_36683;
import static net.runelite.client.util.RSTimeUnit.GAME_TICKS;
@Getter @Getter
enum Tree enum Tree
{ {
REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280), REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280),
OAK_TREE(Duration.ofMillis(8500), OAK_TREE_4540, OAK_10820), OAK_TREE(Duration.of(14, GAME_TICKS), OAK_TREE_4540, OAK_10820),
WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), WILLOW_TREE(Duration.of(14, GAME_TICKS), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833),
MAPLE_TREE(Duration.ofSeconds(35), MAPLE_TREE_10832, MAPLE_TREE_36681) MAPLE_TREE(Duration.of(59, GAME_TICKS), MAPLE_TREE_10832, MAPLE_TREE_36681)
{ {
@Override @Override
Duration getRespawnTime(int region) 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), TEAK_TREE(Duration.of(15, GAME_TICKS), TEAK, TEAK_36686),
MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688), MAHOGANY_TREE(Duration.of(14, GAME_TICKS), MAHOGANY, MAHOGANY_36688),
YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683), YEW_TREE(Duration.of(99, GAME_TICKS), YEW, NULL_10823, YEW_36683),
MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835), MAGIC_TREE(Duration.of(199, GAME_TICKS), MAGIC_TREE_10834, NULL_10835),
REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670); REDWOOD(Duration.of(199, GAME_TICKS), ObjectID.REDWOOD, REDWOOD_29670);
@Nullable @Nullable
private final Duration respawnTime; private final Duration respawnTime;

View File

@@ -28,7 +28,6 @@ package net.runelite.client.plugins.worldhopper;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ObjectArrays;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.time.Instant; import java.time.Instant;
@@ -53,7 +52,6 @@ import net.runelite.api.FriendsChatManager;
import net.runelite.api.FriendsChatMember; import net.runelite.api.FriendsChatMember;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.NameableContainer; import net.runelite.api.NameableContainer;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.clan.ClanChannel; 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.GameStateChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.WorldListLoad; import net.runelite.api.events.WorldListLoad;
import net.runelite.api.widgets.WidgetInfo; 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.World;
import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldResult;
import net.runelite.http.api.worlds.WorldType; import net.runelite.http.api.worlds.WorldType;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor( @PluginDescriptor(
name = "World Hopper", name = "World Hopper",
@@ -355,7 +351,7 @@ public class WorldHopperPlugin extends Plugin
return; return;
} }
final int componentId = event.getParam1(); final int componentId = event.getActionParam1();
int groupId = WidgetInfo.TO_GROUP(componentId); int groupId = WidgetInfo.TO_GROUP(componentId);
String option = event.getOption(); String option = event.getOption();
@@ -396,43 +392,21 @@ public class WorldHopperPlugin extends Plugin
return; return;
} }
final MenuEntry hopTo = new MenuEntry(); client.createMenuEntry(after ? -2 : -1)
hopTo.setOption(HOP_TO); .setOption(HOP_TO)
hopTo.setTarget(event.getTarget()); .setTarget(event.getTarget())
hopTo.setType(MenuAction.RUNELITE.getId()); .setType(MenuAction.RUNELITE)
hopTo.setParam0(event.getActionParam0()); .onClick(e ->
hopTo.setParam1(event.getParam1()); {
ChatPlayer p = getChatPlayerFromName(e.getTarget());
insertMenuEntry(hopTo, client.getMenuEntries(), after); if (p != null)
} {
} hop(p.getWorld());
}
private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries, boolean after) })
{ // TODO: remove
MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); .add(client);
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());
} }
} }

View File

@@ -32,7 +32,6 @@ import com.google.inject.Binder;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -45,7 +44,6 @@ import net.runelite.api.Client;
import net.runelite.api.Experience; import net.runelite.api.Experience;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Skill; 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.GameStateChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.StatChanged; import net.runelite.api.events.StatChanged;
import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetID;
@@ -508,7 +505,7 @@ public class XpTrackerPlugin extends Plugin
@Subscribe @Subscribe
public void onMenuEntryAdded(final MenuEntryAdded event) public void onMenuEntryAdded(final MenuEntryAdded event)
{ {
int widgetID = event.getParam1(); int widgetID = event.getActionParam1();
if (TO_GROUP(widgetID) != WidgetID.SKILLS_GROUP_ID if (TO_GROUP(widgetID) != WidgetID.SKILLS_GROUP_ID
|| !event.getOption().startsWith("View") || !event.getOption().startsWith("View")
@@ -521,48 +518,23 @@ public class XpTrackerPlugin extends Plugin
final String skillText = event.getOption().split(" ")[1]; final String skillText = event.getOption().split(" ")[1];
final Skill skill = Skill.valueOf(Text.removeTags(skillText).toUpperCase()); final Skill skill = Skill.valueOf(Text.removeTags(skillText).toUpperCase());
MenuEntry[] menuEntries = client.getMenuEntries(); client.createMenuEntry(-1)
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); .setTarget(skillText)
.setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER)
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); .setType(MenuAction.RUNELITE)
menuEntry.setTarget(skillText); .onClick(e ->
menuEntry.setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER); {
menuEntry.setParam0(event.getActionParam0()); if (hasOverlay(skill))
menuEntry.setParam1(widgetID); {
menuEntry.setType(MenuAction.RUNELITE.getId()); removeOverlay(skill);
}
client.setMenuEntries(menuEntries); else
} {
addOverlay(skill);
@Subscribe }
public void onMenuOptionClicked(MenuOptionClicked event) })
{ // TODO: remove
if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() .add(client);
|| 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;
}
} }
XpStateSingle getSkillState(Skill skill) XpStateSingle getSkillState(Skill skill)

View File

@@ -78,7 +78,7 @@ import okhttp3.Response;
public class ClientLoader implements Supplier<Applet> public class ClientLoader implements Supplier<Applet>
{ {
private static final String INJECTED_CLIENT_NAME = "/injected-client.oprs"; 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 LOCK_FILE = new File(RuneLite.CACHE_DIR, "cache.lock");
private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache"); private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache");
private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache"); private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache");

View File

@@ -40,17 +40,13 @@ import javax.inject.Singleton;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; 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.WidgetID;
import net.runelite.api.widgets.WidgetItem; import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.events.PluginChanged; import net.runelite.client.events.PluginChanged;
/** /**
@@ -108,14 +104,12 @@ public class OverlayManager
private ArrayListMultimap<Object, Overlay> overlayMap = ArrayListMultimap.create(); private ArrayListMultimap<Object, Overlay> overlayMap = ArrayListMultimap.create();
private final ConfigManager configManager; private final ConfigManager configManager;
private final EventBus eventBus;
private final RuneLiteConfig runeLiteConfig; private final RuneLiteConfig runeLiteConfig;
@Inject @Inject
private OverlayManager(final ConfigManager configManager, final EventBus eventBus, final RuneLiteConfig runeLiteConfig) private OverlayManager(final ConfigManager configManager, final RuneLiteConfig runeLiteConfig)
{ {
this.configManager = configManager; this.configManager = configManager;
this.eventBus = eventBus;
this.runeLiteConfig = runeLiteConfig; this.runeLiteConfig = runeLiteConfig;
} }
@@ -137,32 +131,6 @@ public class OverlayManager
rebuildOverlayLayers(); 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<OverlayMenuEntry> 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 * Gets all of the overlays on a layer sorted by priority and position
* *

View File

@@ -49,7 +49,6 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.KeyCode; import net.runelite.api.KeyCode;
import net.runelite.api.MenuEntry;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.events.BeforeRender; import net.runelite.api.events.BeforeRender;
import net.runelite.api.events.ClientTick; 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.config.RuneLiteConfig;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseAdapter; import net.runelite.client.input.MouseAdapter;
@@ -93,6 +93,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
private final TooltipManager tooltipManager; private final TooltipManager tooltipManager;
private final RuneLiteConfig runeLiteConfig; private final RuneLiteConfig runeLiteConfig;
private final ClientUI clientUI; private final ClientUI clientUI;
private final EventBus eventBus;
// Overlay movement variables // Overlay movement variables
private final Point overlayOffset = new Point(); private final Point overlayOffset = new Point();
@@ -104,7 +105,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
private boolean inOverlayResizingMode; private boolean inOverlayResizingMode;
private boolean inOverlayDraggingMode; private boolean inOverlayDraggingMode;
private boolean startedMovingOverlay; private boolean startedMovingOverlay;
private MenuEntry[] menuEntries; private Overlay hoveredOverlay; // for building menu entries
// Overlay state validation // Overlay state validation
private Rectangle viewportBounds; private Rectangle viewportBounds;
@@ -133,6 +134,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
this.runeLiteConfig = runeLiteConfig; this.runeLiteConfig = runeLiteConfig;
this.clientUI = clientUI; this.clientUI = clientUI;
this.tooltipManager = tooltipManager; this.tooltipManager = tooltipManager;
this.eventBus = eventBus;
keyManager.registerKeyListener(this); keyManager.registerKeyListener(this);
mouseManager.registerMouseListener(this); mouseManager.registerMouseListener(this);
eventBus.register(this); eventBus.register(this);
@@ -149,14 +151,15 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
resetOverlayManagementMode(); resetOverlayManagementMode();
} }
menuEntries = null; hoveredOverlay = null;
} }
} }
@Subscribe @Subscribe
protected void onClientTick(ClientTick t) protected void onClientTick(ClientTick t)
{ {
if (menuEntries == null) final Overlay overlay = hoveredOverlay;
if (overlay == null || client.isMenuOpen())
{ {
return; return;
} }
@@ -167,24 +170,31 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
return; return;
} }
if (client.isMenuOpen()) List<OverlayMenuEntry> menuEntries = overlay.getMenuEntries();
if (menuEntries.isEmpty())
{ {
return; return;
} }
MenuEntry[] clientMenuEntries = client.getMenuEntries(); // Add in reverse order so they display correctly in the right-click menu
MenuEntry[] newEntries = new MenuEntry[clientMenuEntries.length + menuEntries.length]; for (int i = menuEntries.size() - 1; i >= 0; --i)
{
OverlayMenuEntry overlayMenuEntry = menuEntries.get(i);
newEntries[0] = clientMenuEntries[0]; // Keep cancel at 0 client.createMenuEntry(-1)
System.arraycopy(menuEntries, 0, newEntries, 1, menuEntries.length); // Add overlay menu entries .setOption(overlayMenuEntry.getOption())
System.arraycopy(clientMenuEntries, 1, newEntries, menuEntries.length + 1, clientMenuEntries.length - 1); // Add remaining menu entries .setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET))
client.setMenuEntries(newEntries); .setType(overlayMenuEntry.getMenuAction())
.onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay)))
// TODO: remove
.add(client);
}
} }
@Subscribe @Subscribe
public void onBeforeRender(BeforeRender event) public void onBeforeRender(BeforeRender event)
{ {
menuEntries = null; hoveredOverlay = null;
if (focusedOverlay == null && prevFocusedOverlay != 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 (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse))
{ {
if (menuEntries == null) hoveredOverlay = overlay;
{
menuEntries = createRightClickMenuEntries(overlay);
}
if (inOverlayManagingMode) if (inOverlayManagingMode)
{ {
@@ -940,33 +947,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE)); new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE));
} }
private MenuEntry[] createRightClickMenuEntries(Overlay overlay)
{
List<OverlayMenuEntry> 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. * Adjust the given overlay position to be within its parent's bounds.
* *

View File

@@ -564,11 +564,11 @@ public class ModelOutlineRenderer
*/ */
private void simulateModelRasterizationForOutline(Model model) private void simulateModelRasterizationForOutline(Model model)
{ {
final int triangleCount = model.getTrianglesCount(); final int triangleCount = model.getFaceCount();
final int[] indices1 = model.getTrianglesX(); final int[] indices1 = model.getFaceIndices1();
final int[] indices2 = model.getTrianglesY(); final int[] indices2 = model.getFaceIndices2();
final int[] indices3 = model.getTrianglesZ(); final int[] indices3 = model.getFaceIndices3();
final byte[] triangleTransparencies = model.getTriangleTransparencies(); final byte[] triangleTransparencies = model.getFaceTransparencies();
for (int i = 0; i < triangleCount; i++) for (int i = 0; i < triangleCount; i++)
{ {

View File

@@ -24,6 +24,7 @@
*/ */
package net.runelite.client.ui.overlay.worldmap; package net.runelite.client.ui.overlay.worldmap;
import com.google.common.base.MoreObjects;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import java.awt.Dimension; import java.awt.Dimension;
@@ -32,23 +33,18 @@ import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.RenderOverview; import net.runelite.api.RenderOverview;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.ui.FontManager; import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.JagexColors;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
@@ -73,7 +69,7 @@ public class WorldMapOverlay extends Overlay
private final WorldMapPointManager worldMapPointManager; private final WorldMapPointManager worldMapPointManager;
private final Client client; private final Client client;
private final List<MenuEntry> mapMenuEntries = new ArrayList<>(); private WorldMapPoint hoveredPoint;
@Inject @Inject
private WorldMapOverlay( private WorldMapOverlay(
@@ -107,19 +103,20 @@ public class WorldMapOverlay extends Overlay
bottomBar.setOnTimerListener((JavaScriptCallback) ev -> bottomBar.setOnTimerListener((JavaScriptCallback) ev ->
{ {
if (client.isMenuOpen() || mapMenuEntries.isEmpty()) WorldMapPoint worldPoint = hoveredPoint;
if (client.isMenuOpen() || worldPoint == null)
{ {
return; return;
} }
MenuEntry[] entries = client.getMenuEntries(); client.createMenuEntry(-1)
int end = entries.length; .setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET))
entries = Arrays.copyOf(entries, end + mapMenuEntries.size()); .setOption(FOCUS_ON)
for (int i = 0; i < mapMenuEntries.size(); i++) .setType(MenuAction.RUNELITE)
{ .onClick(m -> client.getRenderOverview().setWorldMapPositionTarget(
entries[end + i] = mapMenuEntries.get(i); MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint())))
} // TODO: remove
client.setMenuEntries(entries); .add(client);
}); });
bottomBar.setHasListener(true); bottomBar.setHasListener(true);
@@ -135,7 +132,7 @@ public class WorldMapOverlay extends Overlay
mousePos = null; mousePos = null;
} }
mapMenuEntries.clear(); hoveredPoint = null;
WorldMapPoint tooltipPoint = null; WorldMapPoint tooltipPoint = null;
@@ -227,19 +224,7 @@ public class WorldMapOverlay extends Overlay
if (worldPoint.isJumpOnClick()) if (worldPoint.isJumpOnClick())
{ {
assert worldPoint.getName() != null; assert worldPoint.getName() != null;
hoveredPoint = worldPoint;
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);
} }
} }
} }
@@ -259,21 +244,6 @@ public class WorldMapOverlay extends Overlay
return null; 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 * Get the screen coordinates for a WorldPoint on the world map
* *

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

View File

@@ -0,0 +1 @@
157D0FE4248A0C0CAC825733A8DE7B0FA5A93451A9FCE3A4B1D8BFD54038B970

View File

@@ -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 "<br>"
sconst "<br>"
sload 1
join_string 4
iload 0
if_getwidth
istore 2
sstore 2
sload 0 ; examine
sload 1 ; Convenience fee
sload 2 ; "<$string0><br><br><$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

View File

@@ -24,9 +24,12 @@
*/ */
package net.runelite.client.menus; package net.runelite.client.menus;
import com.google.common.collect.Lists;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule; import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.MenuAction; 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 net.runelite.client.util.Text;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import static org.mockito.ArgumentMatchers.anyInt;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock; import org.mockito.Mock;
import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class MenuManagerTest public class MenuManagerTest
{ {
private static final MenuEntry CANCEL = new MenuEntry();
@Inject @Inject
private MenuManager menuManager; private MenuManager menuManager;
@@ -63,14 +60,18 @@ public class MenuManagerTest
@Bind @Bind
private Client client; private Client client;
private MenuEntry[] clientMenuEntries = {CANCEL}; private final MenuEntry CANCEL = createMenuEntry("Cancel", "", MenuAction.CANCEL, MINIMAP_WORLDMAP_OPTIONS.getPackedId());
@BeforeClass private final List<MenuEntry> createdMenuEntries = new ArrayList<>();
public static void beforeClass()
private static MenuEntry createMenuEntry(String option, String target, MenuAction type, int param1)
{ {
CANCEL.setOption("Cancel"); MenuEntry menuEntry = new TestMenuEntry();
CANCEL.setType(MenuAction.CANCEL.getId()); menuEntry.setOption(option);
CANCEL.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); menuEntry.setTarget(target);
menuEntry.setType(type);
menuEntry.setParam1(param1);
return menuEntry;
} }
@Before @Before
@@ -78,35 +79,25 @@ public class MenuManagerTest
{ {
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
doAnswer((Answer<Void>) invocationOnMock -> when(client.createMenuEntry(anyInt()))
{ .thenAnswer(a ->
clientMenuEntries = invocationOnMock.getArgument(0, MenuEntry[].class); {
return null; MenuEntry e = new TestMenuEntry();
}).when(client).setMenuEntries(ArgumentMatchers.any(MenuEntry[].class)); createdMenuEntries.add(e);
when(client.getMenuEntries()).thenAnswer((Answer<MenuEntry[]>) invocationMock -> clientMenuEntries); return e;
});
when(client.getMenuEntries()).thenReturn(new MenuEntry[]{CANCEL});
} }
@Test @Test
public void testManagedMenuOrder() public void testManagedMenuOrder()
{ {
final MenuEntry first = new MenuEntry(); final MenuEntry first = createMenuEntry("Test", "First Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId());
final MenuEntry second = new MenuEntry(); final MenuEntry second = createMenuEntry("Test", "Second Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId());
final MenuEntry third = new MenuEntry(); final MenuEntry third = createMenuEntry("Test", "Third Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId());
first.setOption("Test"); menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null);
first.setTarget("First Entry"); menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null);
first.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null);
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));
menuManager.onMenuEntryAdded(new MenuEntryAdded( menuManager.onMenuEntryAdded(new MenuEntryAdded(
CANCEL.getOption(), CANCEL.getOption(),
@@ -116,12 +107,10 @@ public class MenuManagerTest
CANCEL.getParam0(), CANCEL.getParam0(),
CANCEL.getParam1())); CANCEL.getParam1()));
ArgumentCaptor<MenuEntry[]> captor = ArgumentCaptor.forClass(MenuEntry[].class); verify(client, times(3)).createMenuEntry(anyInt());
verify(client, atLeastOnce()).setMenuEntries(captor.capture());
final MenuEntry[] resultMenuEntries = captor.getValue();
// Strip color tags from menu options before array comparison // Strip color tags from menu options before array comparison
for (MenuEntry resultEntry : resultMenuEntries) for (MenuEntry resultEntry : createdMenuEntries)
{ {
final String resultTarget = resultEntry.getTarget(); final String resultTarget = resultEntry.getTarget();
if (resultTarget != null) 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]));
} }
} }

View File

@@ -0,0 +1,166 @@
/*
* Copyright (c) 2021, Adam <Adam@sigterm.info>
* 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<MenuEntry> callback)
{
return this;
}
}

View File

@@ -31,9 +31,11 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Friend; import net.runelite.api.Friend;
import net.runelite.api.FriendContainer;
import net.runelite.api.MessageNode; import net.runelite.api.MessageNode;
import net.runelite.api.NameableContainer;
import net.runelite.api.events.ChatMessage; 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.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -54,6 +56,14 @@ public class FriendListPluginTest
@Bind @Bind
private FriendListConfig config; private FriendListConfig config;
@Mock
@Bind
private ConfigManager configManager;
@Mock
@Bind
private ChatMessageManager chatMessageManager;
@Inject @Inject
private FriendListPlugin friendListPlugin; private FriendListPlugin friendListPlugin;
@@ -78,7 +88,7 @@ public class FriendListPluginTest
Friend friend = mock(Friend.class); Friend friend = mock(Friend.class);
when(friend.getWorld()).thenReturn(311); when(friend.getWorld()).thenReturn(311);
NameableContainer<Friend> friendContainer = mock(NameableContainer.class); FriendContainer friendContainer = mock(FriendContainer.class);
when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend); when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend);
when(client.getFriendContainer()).thenReturn(friendContainer); when(client.getFriendContainer()).thenReturn(friendContainer);

View File

@@ -0,0 +1,430 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* 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<MenuEntry[]>) 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<Void>) 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<MenuEntry[]> 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<MenuEntry[]> 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<MenuEntry[]> 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<MenuEntry[]> 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<MenuEntry[]> 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<MenuEntry[]> 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<MenuEntry[]> 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<MenuEntry[]> 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<MenuEntry[]> 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());
}
}

View File

@@ -39,6 +39,7 @@ import net.runelite.api.NPC;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcChanged;
import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.NpcSpawned;
import net.runelite.client.menus.TestMenuEntry;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@@ -49,7 +50,6 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
@@ -111,13 +111,12 @@ public class NpcIndicatorsPluginTest
when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 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); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1);
npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded);
MenuEntry target = new MenuEntry(); assertEquals("<col=ff0000>Goblin", entry.getTarget()); // red
target.setTarget("<col=ff0000>Goblin"); // red
verify(client).setMenuEntries(new MenuEntry[]{target});
} }
@Test @Test
@@ -136,13 +135,12 @@ public class NpcIndicatorsPluginTest
when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 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); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1);
npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded);
MenuEntry target = new MenuEntry(); assertEquals("<col=0000ff>Goblin", entry.getTarget()); // blue
target.setTarget("<col=0000ff>Goblin"); // blue
verify(client).setMenuEntries(new MenuEntry[]{target});
} }
@Test @Test