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

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -636,6 +636,13 @@ public interface Client extends GameEngine
*/
World[] getWorldList();
/**
* Create a new menu entry
* @param idx the index to create the menu entry at. Accepts negative indexes eg. -1 inserts at the end.
* @return the newly created menu entry
*/
MenuEntry createMenuEntry(int idx);
/**
* Gets an array of currently open right-click menu entries that can be
* clicked and activated.
@@ -1133,7 +1140,7 @@ public interface Client extends GameEngine
* @param id the ID of the animation. Any int is allowed, but implementations in the client
* should be defined in {@link AnimationID}
*/
Sequence loadAnimation(int id);
Animation loadAnimation(int id);
/**
* Gets the music volume
@@ -1341,7 +1348,7 @@ public interface Client extends GameEngine
/**
* Retrieve the nameable container containing friends
*/
NameableContainer<Friend> getFriendContainer();
FriendContainer getFriendContainer();
/**
* 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.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,8 +25,13 @@
package net.runelite.api;
/**
* Represents an animation of a renderable
* A nameable container of friends
*/
public interface Sequence
public interface FriendContainer extends NameableContainer<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;
import java.util.Arrays;
import java.util.function.Consumer;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -94,6 +96,113 @@ public class MenuEntry implements Cloneable
}
}
public String getOption()
{
return option;
}
public MenuEntry setOption(String option)
{
this.option = option;
return this;
}
public String getTarget()
{
return target;
}
public MenuEntry setTarget(String target)
{
this.target = target;
return this;
}
public int getIdentifier()
{
return this.identifier;
}
public MenuEntry setIdentifier(int identifier)
{
this.identifier = identifier;
return this;
}
public MenuAction getType()
{
return MenuAction.of(this.opcode);
}
public MenuEntry setType(MenuAction type)
{
this.opcode = type.getId();
return this;
}
public int getParam0()
{
return this.param0;
}
public MenuEntry setParam0(int param0)
{
this.param0 = param0;
return this;
}
public int getParam1()
{
return this.param1;
}
public MenuEntry setParam1(int param1)
{
this.param1 = param1;
return this;
}
public boolean isForceLeftClick()
{
return this.forceLeftClick;
}
public MenuEntry setForceLeftClick(boolean forceLeftClick)
{
this.forceLeftClick = forceLeftClick;
return this;
}
public boolean isDeprioritized()
{
return opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET;
}
public MenuEntry setDeprioritized(boolean deprioritized)
{
if (deprioritized)
{
if (opcode < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET)
{
opcode += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET;
}
}
else
{
if (opcode >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET)
{
opcode -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET;
}
}
return this;
}
public MenuEntry onClick(Consumer<MenuEntry> callback)
{
return this;
}
public void setActionParam0(int i)
{
this.param0 = i;
@@ -104,26 +213,6 @@ public class MenuEntry implements Cloneable
return this.param0;
}
public int getParam0()
{
return this.param0;
}
public void setParam0(int i)
{
this.param0 = i;
}
public void setParam1(int i)
{
this.param1 = i;
}
public int getParam1()
{
return this.param1;
}
public void setActionParam1(int i)
{
this.param1 = i;
@@ -139,11 +228,6 @@ public class MenuEntry implements Cloneable
this.opcode = i;
}
public int getType()
{
return this.opcode;
}
public void setId(int i)
{
this.identifier = i;
@@ -161,4 +245,19 @@ public class MenuEntry implements Cloneable
{
return MenuAction.of(getOpcode());
}
// TODO: Remove this after properly implementing the menu
public void add(Client client)
{
MenuEntry[] menuEntries = client.getMenuEntries();
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry();
menuEntry.setOption(option);
menuEntry.setTarget(target);
menuEntry.setParam0(param0);
menuEntry.setParam1(param1);
menuEntry.setIdentifier(identifier);
menuEntry.setType(MenuAction.of(getOpcode()));
client.setMenuEntries(menuEntries);
}
}

View File

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

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

View File

@@ -41,7 +41,7 @@ public interface RuneLiteObject extends GraphicsObject
* Sets the animation of the RuneLiteObject
* If animation is null model will be static
*/
void setAnimation(Sequence animation);
void setAnimation(Animation animation);
/**
* Sets whether the animation of the RuneLiteObject should loop when the animation ends.

View File

@@ -257,6 +257,12 @@ public final class ScriptID
@ScriptArguments(integer = 15)
public static final int FRIENDS_CHAT_CHANNEL_REBUILD = 1658;
/**
* Builds the widget that holds all of the players inside a clan chat
*/
@ScriptArguments(integer = 7)
public static final int CLAN_SIDEPANEL_DRAW = 4396;
/**
* Builds the widget for making an offer in Grand Exchange
*/

View File

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

View File

@@ -25,24 +25,50 @@
package net.runelite.api.events;
import lombok.Getter;
import net.runelite.api.MenuEntry;
/**
* An event when a new entry is added to a right-click menu.
*/
public class MenuEntryAdded extends MenuEntry
public class MenuEntryAdded
{
// Here for RuneLite compatibility (different parameter order)
public MenuEntryAdded(String option, String target, int type, int identifier, int actionParam0, int actionParam1)
{
super(option, target, identifier, type, actionParam0, actionParam1, false);
this(option, target, identifier, type, actionParam0, actionParam1, false);
}
public MenuEntryAdded(String option, String target, int identifier, int opcode, int param0, int param1, boolean forceLeftClick)
public MenuEntryAdded(String option, String target, int identifier, int type, int param0, int param1, boolean forceLeftClick)
{
super(option, target, identifier, opcode, param0, param1, forceLeftClick);
this.option = option;
this.target = target;
this.identifier = identifier;
this.type = type;
this.actionParam0 = param0;
this.actionParam1 = param1;
this.forceLeftClick = forceLeftClick;
}
@Getter
private final String option;
@Getter
private final String target;
@Getter
private final int type;
@Getter
private final int identifier;
@Getter
private final int actionParam0;
@Getter
private final int actionParam1;
@Getter
private final boolean forceLeftClick;
/**
* If this is set to true client mixin will update
* the menu entry with the modified values.

View File

@@ -91,33 +91,9 @@ public class MenuOptionClicked
{
this.setMenuOption(entry.getOption());
this.setMenuTarget(entry.getTarget());
this.setId(entry.getId());
this.setMenuAction(MenuAction.of(entry.getOpcode()));
this.setId(entry.getIdentifier());
this.setMenuAction(entry.getType());
this.setParam0(entry.getParam0());
this.setParam1(entry.getParam1());
}
@Deprecated
public int getActionParam()
{
return param0;
}
@Deprecated
public void setActionParam(int i)
{
param0 = i;
}
@Deprecated
public int getWidgetId()
{
return param1;
}
@Deprecated
public void setWidgetId(int i)
{
param1 = i;
}
}

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.
*/
@Data
@Deprecated
public class WidgetMenuOptionClicked
{
/**

View File

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

View File

@@ -554,7 +554,12 @@ public enum WidgetInfo
TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR),
CLAN_LAYER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.LAYER),
CLAN_HEADER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.HEADER),
CLAN_MEMBER_LIST(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.MEMBERS),
CLAN_GUEST_LAYER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.LAYER),
CLAN_GUEST_HEADER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.HEADER),
CLAN_GUEST_MEMBER_LIST(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.MEMBERS),
//OpenOSRS

View File

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

View File

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

View File

@@ -25,9 +25,11 @@
package net.runelite.client.menus;
import java.awt.Color;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.MenuEntry;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
@@ -65,6 +67,8 @@ public final class WidgetMenuOption
@Getter
private final int widgetId;
Consumer<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
*

View File

@@ -341,9 +341,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded event)
{
MenuEntry[] entries = client.getMenuEntries();
if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
&& event.getOption().equals("Examine"))
{
Widget container = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER);
@@ -357,30 +355,24 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener
text += " (" + tagCount + ")";
}
MenuEntry editTags = new MenuEntry();
editTags.setParam0(event.getActionParam0());
editTags.setParam1(event.getParam1());
editTags.setTarget(event.getTarget());
editTags.setOption(text);
editTags.setType(MenuAction.RUNELITE.getId());
editTags.setIdentifier(event.getIdentifier());
entries = Arrays.copyOf(entries, entries.length + 1);
entries[entries.length - 1] = editTags;
client.setMenuEntries(entries);
client.createMenuEntry(-1)
.setParam0(event.getActionParam0())
.setParam1(event.getActionParam1())
.setTarget(event.getTarget())
.setOption(text)
.setType(MenuAction.RUNELITE)
.setIdentifier(event.getIdentifier())
.onClick(this::editTags)
// TODO: remove
.add(client);
}
tabInterface.handleAdd(event);
}
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
private void editTags(MenuEntry entry)
{
if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
&& event.getMenuAction() == MenuAction.RUNELITE
&& event.getMenuOption().startsWith(EDIT_TAGS_MENU_OPTION))
{
event.consume();
int inventoryIndex = event.getParam0();
int inventoryIndex = entry.getParam0();
ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK);
if (bankContainer == null)
{
@@ -434,11 +426,12 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener
}))
.build();
}
else
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
tabInterface.handleClick(event);
}
}
@Subscribe
public void onConfigChanged(ConfigChanged configChanged)

View File

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

View File

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

View File

@@ -206,6 +206,18 @@ public interface ChatChannelConfig extends Config
return false;
}
@ConfigItem(
keyName = "clanChatShowOnlineMemberCount",
name = "Show Online Member Count",
description = "Shows the number of online clan members at the end of the clan's name.",
position = 1,
section = clanChatSection
)
default boolean clanChatShowOnlineMemberCount()
{
return false;
}
@ConfigItem(
keyName = "guestClanChatShowJoinLeave",
name = "Show Join/Leave",
@@ -217,4 +229,16 @@ public interface ChatChannelConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "guestClanChatShowOnlineMemberCount",
name = "Show Online Member Count",
description = "Shows the number of online guest clan members at the end of the clan's name.",
position = 1,
section = guestClanChatSection
)
default boolean guestClanChatShowOnlineMemberCount()
{
return false;
}
}

View File

@@ -145,6 +145,8 @@ public class ChatChannelPlugin extends Plugin
{
clientThread.invoke(() -> colorIgnoredPlayers(config.showIgnoresColor()));
}
rebuildClanTitle();
}
@Override
@@ -153,6 +155,7 @@ public class ChatChannelPlugin extends Plugin
chats = null;
clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE));
rebuildFriendsChat();
rebuildClanTitle();
}
@Subscribe
@@ -167,6 +170,8 @@ public class ChatChannelPlugin extends Plugin
Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE;
clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor));
rebuildClanTitle();
}
}
@@ -606,6 +611,18 @@ public class ChatChannelPlugin extends Plugin
chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)");
}
}
else if (event.getScriptId() == ScriptID.CLAN_SIDEPANEL_DRAW)
{
if (config.clanChatShowOnlineMemberCount())
{
updateClanTitle(WidgetInfo.CLAN_HEADER, client.getClanChannel());
}
if (config.guestClanChatShowOnlineMemberCount())
{
updateClanTitle(WidgetInfo.CLAN_GUEST_HEADER, client.getGuestClanChannel());
}
}
}
private void insertRankIcon(final ChatMessage message)
@@ -740,4 +757,35 @@ public class ChatChannelPlugin extends Plugin
listWidget.setTextColor(ignoreColor.getRGB());
}
}
private void rebuildClanTitle()
{
clientThread.invokeLater(() ->
{
Widget w = client.getWidget(WidgetInfo.CLAN_LAYER);
if (w != null)
{
client.runScript(w.getOnVarTransmitListener());
}
});
clientThread.invokeLater(() ->
{
Widget w = client.getWidget(WidgetInfo.CLAN_GUEST_LAYER);
if (w != null)
{
client.runScript(w.getOnVarTransmitListener());
}
});
}
private void updateClanTitle(WidgetInfo widget, ClanChannel channel)
{
Widget header = client.getWidget(widget);
if (header != null && channel != null)
{
Widget title = header.getChild(0);
title.setText(title.getText() + " (" + channel.getMembers().size() + ")");
}
}
}

View File

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

View File

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

View File

@@ -490,7 +490,6 @@ public class DevToolsPlugin extends Plugin
}
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_VALUE = 1;
private final List<WidgetField> fields = populateWidgetFields();
private final List<WidgetField<?>> fields = populateWidgetFields();
private Widget widget = null;
private Map<WidgetField, Object> values = null;
private Map<WidgetField<?>, Object> values = null;
public void setWidget(Widget w)
{
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(),
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<>("Type", Widget::getType, Widget::setType, Integer.class));
@@ -209,6 +209,11 @@ public class WidgetInfoTableModel extends AbstractTableModel
}
return null;
}));
out.add(new WidgetField<>("OnOpListener", Widget::getOnOpListener));
out.add(new WidgetField<>("OnKeyListener", Widget::getOnKeyListener));
out.add(new WidgetField<>("OnLoadListener", Widget::getOnLoadListener));
out.add(new WidgetField<>("OnInvTransmitListener", Widget::getOnInvTransmitListener));
out.add(new WidgetField<>("OnVarTransmitListener", Widget::getOnVarTransmitListener));
return out;
}

View File

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

View File

@@ -93,6 +93,7 @@ enum Emoji
XD("Xd"),
SPOON("--o"),
WEARY_FACE("Dx"),
ROCKETSHIP("<gt>==<gt>"), // >==>
;
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.ConfigItem;
@ConfigGroup("friendlist")
@ConfigGroup(FriendListConfig.GROUP)
public interface FriendListConfig extends Config
{
String GROUP = "friendlist";
@ConfigItem(
keyName = "showWorldOnLogin",
name = "Show world on login",

View File

@@ -26,30 +26,40 @@
package net.runelite.client.plugins.friendlist;
import com.google.inject.Provides;
import java.time.temporal.ChronoUnit;
import java.util.Iterator;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.ChatPlayer;
import net.runelite.api.Client;
import net.runelite.api.Friend;
import net.runelite.api.Ignore;
import net.runelite.api.MenuAction;
import net.runelite.api.MessageNode;
import net.runelite.api.NameableContainer;
import net.runelite.api.PendingLogin;
import net.runelite.api.ScriptID;
import net.runelite.api.VarPlayer;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.ScriptPostFired;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.task.Schedule;
import net.runelite.client.util.Text;
@PluginDescriptor(
name = "Friend List",
description = "Add extra information to the friend and ignore lists"
)
@Slf4j
public class FriendListPlugin extends Plugin
{
private static final int MAX_FRIENDS_P2P = 400;
@@ -58,12 +68,21 @@ public class FriendListPlugin extends Plugin
private static final int MAX_IGNORES_P2P = 400;
private static final int MAX_IGNORES_F2P = 100;
private static final String HIDE_NOTIFICATIONS = "Hide notifications";
private static final String SHOW_NOTIFICATIONS = "Show notifications";
@Inject
private Client client;
@Inject
private FriendListConfig config;
@Inject
private ConfigManager configManager;
@Inject
private ChatMessageManager chatMessageManager;
@Provides
FriendListConfig getConfig(ConfigManager configManager)
{
@@ -144,6 +163,48 @@ public class FriendListPlugin extends Plugin
}
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded event)
{
final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1());
// Look for "Message" on friends list
if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message"))
{
String friend = Text.toJagexName(Text.removeTags(event.getTarget()));
client.createMenuEntry(-1)
.setOption(isHideNotification(friend) ? SHOW_NOTIFICATIONS : HIDE_NOTIFICATIONS)
.setType(MenuAction.RUNELITE)
.setTarget(event.getTarget()) //Preserve color codes here
.onClick(e ->
{
boolean hidden = isHideNotification(friend);
setHideNotifications(friend, !hidden);
chatMessageManager.queue(QueuedMessage.builder()
.type(ChatMessageType.CONSOLE)
.value("Login notifications for " + friend + " are now " + (hidden ? "shown." : "hidden."))
.build());
})
// TODO: remove
.add(client);
}
}
@Schedule(period = 5, unit = ChronoUnit.SECONDS)
public void setHideNotifications()
{
for (Iterator<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)
{
Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE);
@@ -173,4 +234,21 @@ public class FriendListPlugin extends Plugin
return null;
}
private void setHideNotifications(String friend, boolean hide)
{
if (hide)
{
configManager.setConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, true);
}
else
{
configManager.unsetConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend);
}
}
private boolean isHideNotification(String friend)
{
return configManager.getConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, Boolean.class) == Boolean.TRUE;
}
}

View File

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

View File

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

View File

@@ -379,7 +379,7 @@ class SceneUploader
public int pushModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer)
{
final int triangleCount = Math.min(model.getTrianglesCount(), GpuPlugin.MAX_TRIANGLE);
final int triangleCount = Math.min(model.getFaceCount(), GpuPlugin.MAX_TRIANGLE);
vertexBuffer.ensureCapacity(triangleCount * 12);
uvBuffer.ensureCapacity(triangleCount * 12);
@@ -388,20 +388,25 @@ class SceneUploader
final int[] vertexY = model.getVerticesY();
final int[] vertexZ = model.getVerticesZ();
final int[] trianglesX = model.getTrianglesX();
final int[] trianglesY = model.getTrianglesY();
final int[] trianglesZ = model.getTrianglesZ();
final int[] indices1 = model.getFaceIndices1();
final int[] indices2 = model.getFaceIndices2();
final int[] indices3 = model.getFaceIndices3();
final int[] color1s = model.getFaceColors1();
final int[] color2s = model.getFaceColors2();
final int[] color3s = model.getFaceColors3();
final byte[] transparencies = model.getTriangleTransparencies();
final byte[] transparencies = model.getFaceTransparencies();
final short[] faceTextures = model.getFaceTextures();
final byte[] facePriorities = model.getFaceRenderPriorities();
float[] uv = model.getFaceTextureUVCoordinates();
final byte overrideAmount = model.getOverrideAmount();
final byte overrideHue = model.getOverrideHue();
final byte overrideSat = model.getOverrideSaturation();
final byte overrideLum = model.getOverrideLuminance();
int len = 0;
for (int face = 0; face < triangleCount; ++face)
{
@@ -429,12 +434,22 @@ class SceneUploader
len += 3;
continue;
}
// HSL override is not applied to flat shade faces or to textured faces
else if (faceTextures == null || faceTextures[face] == -1)
{
if (overrideAmount > 0)
{
color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount);
color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount);
color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount);
}
}
int packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face);
int triangleA = trianglesX[face];
int triangleB = trianglesY[face];
int triangleC = trianglesZ[face];
int triangleA = indices1[face];
int triangleB = indices2[face];
int triangleC = indices3[face];
vertexBuffer.put(vertexX[triangleA], vertexY[triangleA], vertexZ[triangleA], packAlphaPriority | color1);
vertexBuffer.put(vertexX[triangleB], vertexY[triangleB], vertexZ[triangleB], packAlphaPriority | color2);
@@ -458,26 +473,31 @@ class SceneUploader
final int[] vertexY = model.getVerticesY();
final int[] vertexZ = model.getVerticesZ();
final int[] trianglesX = model.getTrianglesX();
final int[] trianglesY = model.getTrianglesY();
final int[] trianglesZ = model.getTrianglesZ();
final int[] indices1 = model.getFaceIndices1();
final int[] indices2 = model.getFaceIndices2();
final int[] indices3 = model.getFaceIndices3();
final int[] color1s = model.getFaceColors1();
final int[] color2s = model.getFaceColors2();
final int[] color3s = model.getFaceColors3();
final byte[] transparencies = model.getTriangleTransparencies();
final byte[] transparencies = model.getFaceTransparencies();
final short[] faceTextures = model.getFaceTextures();
final byte[] facePriorities = model.getFaceRenderPriorities();
int triangleA = trianglesX[face];
int triangleB = trianglesY[face];
int triangleC = trianglesZ[face];
final int triangleA = indices1[face];
final int triangleB = indices2[face];
final int triangleC = indices3[face];
int color1 = color1s[face];
int color2 = color2s[face];
int color3 = color3s[face];
final byte overrideAmount = model.getOverrideAmount();
final byte overrideHue = model.getOverrideHue();
final byte overrideSat = model.getOverrideSaturation();
final byte overrideLum = model.getOverrideLuminance();
int packedAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face);
int sin = 0, cos = 0;
@@ -505,6 +525,16 @@ class SceneUploader
}
return 3;
}
// HSL override is not applied to flat shade faces or to textured faces
else if (faceTextures == null || faceTextures[face] == -1)
{
if (overrideAmount > 0)
{
color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount);
color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount);
color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount);
}
}
int a, b, c;
@@ -605,4 +635,28 @@ class SceneUploader
uvBuffer.put(0, 0, 0, 0);
}
}
private static int interpolateHSL(int hsl, byte hue2, byte sat2, byte lum2, byte lerp)
{
int hue = hsl >> 10 & 63;
int sat = hsl >> 7 & 7;
int lum = hsl & 127;
int var9 = lerp & 255;
if (hue2 != -1)
{
hue += var9 * (hue2 - hue) >> 7;
}
if (sat2 != -1)
{
sat += var9 * (sat2 - sat) >> 7;
}
if (lum2 != -1)
{
lum += var9 * (lum2 - lum) >> 7;
}
return (hue << 10 | sat << 7 | lum) & 65535;
}
}

View File

@@ -66,6 +66,7 @@ import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.ScriptID;
import net.runelite.api.VarClientStr;
import net.runelite.api.VarPlayer;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.FocusChanged;
import net.runelite.api.events.GameStateChanged;
@@ -74,7 +75,6 @@ import net.runelite.api.events.GrandExchangeSearched;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.ScriptPostFired;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
@@ -120,10 +120,9 @@ public class GrandExchangePlugin extends Plugin
@VisibleForTesting
static final int GE_SLOTS = 8;
private static final int GE_LOGIN_BURST_WINDOW = 2; // ticks
private static final int OFFER_CONTAINER_ITEM = 21;
private static final int OFFER_DEFAULT_ITEM_ID = 6512;
private static final int GE_MAX_EXAMINE_LEN = 100;
private static final String BUY_LIMIT_GE_TEXT = "<br>Buy limit: ";
private static final String BUY_LIMIT_GE_TEXT = "Buy limit: ";
private static final String BUY_LIMIT_KEY = "buylimit";
private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4);
@@ -182,9 +181,6 @@ public class GrandExchangePlugin extends Plugin
@Inject
private RuneLiteConfig runeLiteConfig;
private Widget grandExchangeText;
private String grandExchangeExamine;
@Inject
private GrandExchangeClient grandExchangeClient;
private int lastLoginTick;
@@ -317,7 +313,6 @@ public class GrandExchangePlugin extends Plugin
clientToolbar.removeNavigation(button);
mouseManager.unregisterMouseListener(inputListener);
keyManager.unregisterKeyListener(inputListener);
grandExchangeText = null;
lastUsername = machineUuid = null;
tradeSeq = 0;
}
@@ -574,8 +569,7 @@ public class GrandExchangePlugin extends Plugin
case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID:
case WidgetID.SHOP_INVENTORY_GROUP_ID:
menuEntry.setOption(SEARCH_GRAND_EXCHANGE);
menuEntry.setType(MenuAction.RUNELITE.getId());
client.setMenuEntries(entries);
menuEntry.setType(MenuAction.RUNELITE);
}
}
@@ -588,31 +582,10 @@ public class GrandExchangePlugin extends Plugin
}
}
@Subscribe
public void onWidgetLoaded(WidgetLoaded event)
{
switch (event.getGroupId())
{
// Grand exchange was opened.
case WidgetID.GRAND_EXCHANGE_GROUP_ID:
grandExchangeText = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_TEXT);
break;
// Grand exchange was closed (if it was open before).
case WidgetID.INVENTORY_GROUP_ID:
grandExchangeText = null;
break;
}
}
@Subscribe
public void onScriptPostFired(ScriptPostFired event)
{
// GE offers setup init
if (event.getScriptId() == ScriptID.GE_OFFERS_SETUP_BUILD)
{
rebuildGeText();
}
else if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch())
if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch())
{
highlightSearchMatches();
}
@@ -739,7 +712,30 @@ public class GrandExchangePlugin extends Plugin
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent event)
{
if (!event.getEventName().equals("setGETitle") || !config.showTotal())
switch (event.getEventName())
{
case "setGETitle":
setGeTitle();
break;
case "geExamineText":
{
String[] stack = client.getStringStack();
int sz = client.getStringStackSize();
String fee = stack[sz - 2];
String examine = stack[sz - 3];
String text = setExamineText(examine, fee);
if (text != null)
{
stack[sz - 1] = text;
}
break;
}
}
}
private void setGeTitle()
{
if (!config.showTotal())
{
return;
}
@@ -818,39 +814,10 @@ public class GrandExchangePlugin extends Plugin
}
}
private void rebuildGeText()
private String setExamineText(String examine, String fee)
{
if (grandExchangeText == null)
{
return;
}
Widget grandExchangeOffer = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER);
if (grandExchangeOffer == null)
{
return;
}
Widget grandExchangeItem = grandExchangeOffer.getChild(OFFER_CONTAINER_ITEM);
if (grandExchangeItem == null || grandExchangeItem.isHidden())
{
return;
}
final Widget geText = grandExchangeText;
final int itemId = grandExchangeItem.getItemId();
if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1)
{
// This item is invalid/nothing has been searched for
return;
}
if (geText.getText() == grandExchangeExamine)
{
// if we've already set the text, don't set it again
return;
}
String text = geText.getText();
final int itemId = client.getVar(VarPlayer.CURRENT_GE_ITEM);
StringBuilder sb = new StringBuilder();
if (config.enableGELimits())
{
@@ -859,7 +826,7 @@ public class GrandExchangePlugin extends Plugin
// If we have item buy limit, append it
if (itemStats != null && itemStats.getGeLimit() > 0)
{
text += BUY_LIMIT_GE_TEXT + QuantityFormatter.formatNumber(itemStats.getGeLimit());
sb.append(BUY_LIMIT_GE_TEXT).append(QuantityFormatter.formatNumber(itemStats.getGeLimit()));
}
}
@@ -869,7 +836,7 @@ public class GrandExchangePlugin extends Plugin
if (resetTime != null)
{
Duration remaining = Duration.between(Instant.now(), resetTime);
text += " (" + DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm") + ")";
sb.append(" (").append(DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm")).append(")");
}
}
@@ -878,12 +845,41 @@ public class GrandExchangePlugin extends Plugin
final int price = itemManager.getItemPriceWithSource(itemId, true);
if (price > 0)
{
text += "<br>Actively traded price: " + QuantityFormatter.formatNumber(price);
if (sb.length() > 0)
{
sb.append(" / ");
}
sb.append("Actively traded price: ").append(QuantityFormatter.formatNumber(price));
}
}
grandExchangeExamine = text;
geText.setText(text);
if (sb.length() == 0)
{
return null;
}
return shortenExamine(examine) + "<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)

View File

@@ -115,14 +115,6 @@ public class GroundItemsPlugin extends Plugin
static final int MAX_QUANTITY = 65535;
// ItemID for coins
private static final int COINS = ItemID.COINS_995;
// Ground item menu options
private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId();
private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId();
private static final int THIRD_OPTION = MenuAction.GROUND_ITEM_THIRD_OPTION.getId(); // this is Take
private static final int FOURTH_OPTION = MenuAction.GROUND_ITEM_FOURTH_OPTION.getId();
private static final int FIFTH_OPTION = MenuAction.GROUND_ITEM_FIFTH_OPTION.getId();
private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId();
private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId();
private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE);
@@ -344,9 +336,10 @@ public class GroundItemsPlugin extends Plugin
{
MenuEntry menuEntry = menuEntries[i];
int menuType = menuEntry.getType();
if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION
|| menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM)
MenuAction menuType = menuEntry.getType();
if (menuType == MenuAction.GROUND_ITEM_FIRST_OPTION || menuType == MenuAction.GROUND_ITEM_SECOND_OPTION
|| menuType == MenuAction.GROUND_ITEM_THIRD_OPTION || menuType == MenuAction.GROUND_ITEM_FOURTH_OPTION
|| menuType == MenuAction.GROUND_ITEM_FIFTH_OPTION || menuType == MenuAction.SPELL_CAST_ON_GROUND_ITEM)
{
for (MenuEntryWithCount entryWCount : newEntries)
{
@@ -490,15 +483,15 @@ public class GroundItemsPlugin extends Plugin
{
if (config.itemHighlightMode() == ItemHighlightMode.MENU || config.itemHighlightMode() == ItemHighlightMode.BOTH)
{
final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == CAST_ON_ITEM;
if (!(event.getOption().equals("Take") && event.getType() == THIRD_OPTION) && !telegrabEntry)
final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId();
if (!(event.getOption().equals("Take") && event.getType() == MenuAction.GROUND_ITEM_THIRD_OPTION.getId()) && !telegrabEntry)
{
return;
}
final int itemId = event.getIdentifier();
final int sceneX = event.getActionParam0();
final int sceneY = event.getParam1();
final int sceneY = event.getActionParam1();
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
@@ -548,8 +541,6 @@ public class GroundItemsPlugin extends Plugin
{
lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")");
}
client.setMenuEntries(menuEntries);
}
}

View File

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

View File

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

View File

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

View File

@@ -24,7 +24,6 @@
*/
package net.runelite.client.plugins.hiscore;
import com.google.common.collect.ObjectArrays;
import com.google.inject.Provides;
import java.awt.image.BufferedImage;
import java.util.EnumSet;
@@ -39,7 +38,6 @@ import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.IconID;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Player;
import net.runelite.api.WorldType;
import net.runelite.api.events.ChatMessage;
@@ -59,7 +57,6 @@ import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text;
import net.runelite.http.api.hiscore.HiscoreEndpoint;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor(
name = "HiScore",
@@ -169,27 +166,28 @@ public class HiscorePlugin extends Plugin
|| groupId == WidgetID.GROUP_IRON_GROUP_ID && (option.equals("Add friend") || option.equals("Remove friend") || option.equals("Remove ignore"))
)
{
final MenuEntry lookup = new MenuEntry();
lookup.setOption(LOOKUP);
lookup.setTarget(event.getTarget());
lookup.setType(MenuAction.RUNELITE.getId());
lookup.setParam0(event.getActionParam0());
lookup.setParam1(event.getActionParam1());
lookup.setIdentifier(event.getIdentifier());
insertMenuEntry(lookup, client.getMenuEntries());
client.createMenuEntry(-2)
.setOption(LOOKUP)
.setTarget(event.getTarget())
.setType(MenuAction.RUNELITE)
.setIdentifier(event.getIdentifier())
.onClick(e ->
{
// Determine proper endpoint from player name.
// TODO: look at target's world and determine if tournament/dmm endpoint should be used instead.
HiscoreEndpoint endpoint = findHiscoreEndpointFromPlayerName(e.getTarget());
String target = Text.removeTags(e.getTarget());
lookupPlayer(target, endpoint);
})
// TODO: remove
.add(client);
}
}
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER)
&& event.getMenuOption().equals(LOOKUP))
{
final String target;
HiscoreEndpoint endpoint;
if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER)
if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER && event.getMenuOption().equals(LOOKUP))
{
// The player id is included in the event, so we can use that to get the player name,
// which avoids having to parse out the combat level and any icons preceding the name.
@@ -199,16 +197,8 @@ public class HiscorePlugin extends Plugin
return;
}
endpoint = getWorldEndpoint();
target = player.getName();
}
else
{
// Determine proper endpoint from player name.
// TODO: look at target's world and determine if tournament/dmm endpoint should be used instead.
endpoint = findHiscoreEndpointFromPlayerName(event.getMenuTarget());
target = Text.removeTags(event.getMenuTarget());
}
String target = player.getName();
HiscoreEndpoint endpoint = getWorldEndpoint();
lookupPlayer(target, endpoint);
}
@@ -236,14 +226,6 @@ public class HiscorePlugin extends Plugin
localHiscoreEndpoint = findHiscoreEndpointFromLocalPlayer();
}
private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries)
{
MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry);
int menuEntryCount = newMenu.length;
ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2);
client.setMenuEntries(newMenu);
}
private void lookupPlayer(String playerName, HiscoreEndpoint endpoint)
{
SwingUtilities.invokeLater(() ->

View File

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

View File

@@ -27,7 +27,6 @@ package net.runelite.client.plugins.instancemap;
import com.google.inject.Binder;
import javax.inject.Inject;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.WidgetMenuOptionClicked;
import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyManager;
@@ -72,7 +71,17 @@ public class InstanceMapPlugin extends Plugin
private void addCustomOptions()
{
menuManager.addManagedCustomMenu(openMapOption);
menuManager.addManagedCustomMenu(openMapOption, entry ->
{
if (overlay.isMapShown())
{
closeMap();
}
else
{
showMap();
}
});
}
private void removeCustomOptions()
@@ -107,32 +116,6 @@ public class InstanceMapPlugin extends Plugin
overlay.onGameStateChange(event);
}
private boolean clickedOptionEquals(WidgetMenuOptionClicked event, WidgetMenuOption widgetMenuOption)
{
return event.getMenuOption().equals(widgetMenuOption.getMenuOption()) && event.getMenuTarget().equals(widgetMenuOption.getMenuTarget());
}
@Subscribe
public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event)
{
if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS)
{
return;
}
if (clickedOptionEquals(event, openMapOption))
{
if (overlay.isMapShown())
{
closeMap();
}
else
{
showMap();
}
}
}
public void showMap()
{
overlay.setShowMap(true);

View File

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

View File

@@ -28,14 +28,13 @@ import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.inject.Provides;
import java.awt.Color;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.events.MenuOpened;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.WidgetMenuOptionClicked;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
@@ -46,7 +45,6 @@ import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.Text;
@PluginDescriptor(
name = "Inventory Tags",
@@ -157,44 +155,11 @@ public class InventoryTagsPlugin extends Plugin
}
}
@Subscribe
public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event)
{
if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB
|| event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB
|| event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB)
{
editorMode = event.getMenuOption().equals(CONFIGURE) && Text.removeTags(event.getMenuTarget()).equals(MENU_TARGET);
refreshInventoryMenuOptions();
}
}
@Subscribe
public void onMenuOptionClicked(final MenuOptionClicked event)
{
if (event.getMenuAction() != MenuAction.RUNELITE)
{
return;
}
final String selectedMenu = Text.removeTags(event.getMenuTarget());
if (event.getMenuOption().equals(MENU_SET))
{
setTag(event.getId(), selectedMenu);
}
else if (event.getMenuOption().equals(MENU_REMOVE))
{
unsetTag(event.getId());
}
}
@Subscribe
public void onMenuOpened(final MenuOpened event)
{
final MenuEntry firstEntry = event.getFirstEntry();
if (firstEntry == null)
if (firstEntry == null || !editorMode)
{
return;
}
@@ -202,7 +167,7 @@ public class InventoryTagsPlugin extends Plugin
final int widgetId = firstEntry.getParam1();
// Inventory item menu
if (widgetId == WidgetInfo.INVENTORY.getId() && editorMode)
if (widgetId == WidgetInfo.INVENTORY.getId())
{
int itemId = firstEntry.getIdentifier();
@@ -211,26 +176,32 @@ public class InventoryTagsPlugin extends Plugin
return;
}
MenuEntry[] menuList = new MenuEntry[GROUPS.size() + 1];
int num = 0;
// preserve the 'Cancel' option as the client will reuse the first entry for Cancel and only resets option/action
menuList[num++] = event.getMenuEntries()[0];
// Set menu to only be Cancel
client.setMenuEntries(Arrays.copyOf(client.getMenuEntries(), 1));
for (final String groupName : GROUPS)
{
final String group = getTag(itemId);
final MenuEntry newMenu = new MenuEntry();
final Color color = getGroupNameColor(groupName);
newMenu.setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET);
newMenu.setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE)));
newMenu.setIdentifier(itemId);
newMenu.setParam1(widgetId);
newMenu.setType(MenuAction.RUNELITE.getId());
menuList[num++] = newMenu;
}
client.setMenuEntries(menuList);
client.createMenuEntry(-1)
.setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET)
.setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE)))
.setType(MenuAction.RUNELITE)
.onClick(e ->
{
if (e.getOption().equals(MENU_SET))
{
setTag(itemId, groupName);
}
else
{
unsetTag(itemId);
}
})
// TODO: remove
.add(client);
}
}
}
@@ -270,15 +241,27 @@ public class InventoryTagsPlugin extends Plugin
removeInventoryMenuOptions();
if (editorMode)
{
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE);
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE, this::save);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE, this::save);
}
else
{
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE);
menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE, this::configure);
menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE, this::configure);
}
}
private void save(MenuEntry menuEntry)
{
editorMode = false;
refreshInventoryMenuOptions();
}
private void configure(MenuEntry menuEntry)
{
editorMode = true;
refreshInventoryMenuOptions();
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -33,6 +33,7 @@ import lombok.Getter;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Varbits;
import net.runelite.api.events.BeforeRender;
import net.runelite.api.events.ChatMessage;
import net.runelite.client.events.ConfigChanged;
import net.runelite.api.events.GameTick;
@@ -121,6 +122,21 @@ public class NightmareZonePlugin extends Plugin
return configManager.getConfig(NightmareZoneConfig.class);
}
@Subscribe
public void onBeforeRender(BeforeRender beforeRender)
{
if (!isInNightmareZone() || !config.moveOverlay())
{
return;
}
Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE);
if (nmzWidget != null)
{
nmzWidget.setHidden(true);
}
}
@Subscribe
public void onGameTick(GameTick event)
{

View File

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

View File

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

View File

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

View File

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

View File

@@ -26,6 +26,12 @@ package net.runelite.client.plugins.party;
import com.google.inject.Inject;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -55,6 +61,9 @@ class PartyPanel extends PluginPanel
private final Map<UUID, PartyMemberBox> memberBoxes = new HashMap<>();
private final JButton startButton = new JButton();
private final JButton joinPartyButton = new JButton();
private final JButton rejoinPartyButton = new JButton();
private final JButton copyPartyIdButton = new JButton();
private final PluginErrorPanel noPartyPanel = new PluginErrorPanel();
private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel();
@@ -79,10 +88,29 @@ class PartyPanel extends PluginPanel
final JPanel topPanel = new JPanel();
topPanel.setBorder(new EmptyBorder(0, 0, 10, 0));
topPanel.setLayout(new BorderLayout());
topPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
topPanel.setLayout(new GridBagLayout());
topPanel.add(startButton, BorderLayout.CENTER);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(0, 2, 4, 2);
c.gridx = 0;
c.gridy = 0;
topPanel.add(startButton, c);
c.gridx = 1;
c.gridy = 0;
topPanel.add(joinPartyButton, c);
c.gridx = 1;
c.gridy = 0;
topPanel.add(copyPartyIdButton, c);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 2;
topPanel.add(rejoinPartyButton, c);
layoutPanel.add(topPanel);
layoutPanel.add(requestBoxPanel);
@@ -91,7 +119,14 @@ class PartyPanel extends PluginPanel
startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT);
startButton.setFocusable(false);
topPanel.add(startButton);
joinPartyButton.setText("Join party");
joinPartyButton.setFocusable(false);
rejoinPartyButton.setText("Join previous party");
rejoinPartyButton.setFocusable(false);
copyPartyIdButton.setText("Copy party id");
copyPartyIdButton.setFocusable(false);
startButton.addActionListener(e ->
{
@@ -115,6 +150,63 @@ class PartyPanel extends PluginPanel
}
});
joinPartyButton.addActionListener(e ->
{
if (!party.isInParty())
{
String s = (String) JOptionPane.showInputDialog(
joinPartyButton,
"Please enter the party id:",
"Party Id",
JOptionPane.PLAIN_MESSAGE,
null,
null,
"");
if (s == null)
{
return;
}
try
{
party.changeParty(UUID.fromString(s));
}
catch (IllegalArgumentException ex)
{
JOptionPane.showMessageDialog(joinPartyButton, "You have entered an invalid party id.", "Invalid Party Id",
JOptionPane.ERROR_MESSAGE);
}
}
});
rejoinPartyButton.addActionListener(e ->
{
if (!party.isInParty())
{
try
{
party.changeParty(UUID.fromString(config.previousPartyId()));
}
catch (IllegalArgumentException ex)
{
JOptionPane.showMessageDialog(rejoinPartyButton,
"Failed to join your previous party, create a new party or join a new one.",
"Failed to Join Party",
JOptionPane.ERROR_MESSAGE);
}
}
});
copyPartyIdButton.addActionListener(e ->
{
if (party.isInParty())
{
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(String.valueOf(party.getPartyId())), null);
}
});
noPartyPanel.setContent("Not in a party", "Create a party to begin.");
partyEmptyPanel.setContent("Party created", "You can now invite friends!");
@@ -127,6 +219,9 @@ class PartyPanel extends PluginPanel
remove(partyEmptyPanel);
startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT);
joinPartyButton.setVisible(!party.isInParty());
rejoinPartyButton.setVisible(!party.isInParty());
copyPartyIdButton.setVisible(party.isInParty());
if (!party.isInParty())
{

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

@@ -40,17 +40,13 @@ import javax.inject.Singleton;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.MenuAction;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.events.PluginChanged;
/**
@@ -108,14 +104,12 @@ public class OverlayManager
private ArrayListMultimap<Object, Overlay> overlayMap = ArrayListMultimap.create();
private final ConfigManager configManager;
private final EventBus eventBus;
private final RuneLiteConfig runeLiteConfig;
@Inject
private OverlayManager(final ConfigManager configManager, final EventBus eventBus, final RuneLiteConfig runeLiteConfig)
private OverlayManager(final ConfigManager configManager, final RuneLiteConfig runeLiteConfig)
{
this.configManager = configManager;
this.eventBus = eventBus;
this.runeLiteConfig = runeLiteConfig;
}
@@ -137,32 +131,6 @@ public class OverlayManager
rebuildOverlayLayers();
}
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
MenuAction menuAction = event.getMenuAction();
if (menuAction != MenuAction.RUNELITE_OVERLAY && menuAction != MenuAction.RUNELITE_OVERLAY_CONFIG)
{
return;
}
event.consume();
Overlay overlay = overlays.get(event.getId());
if (overlay != null)
{
List<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
*

View File

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

View File

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

View File

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

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

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.Client;
import net.runelite.api.Friend;
import net.runelite.api.FriendContainer;
import net.runelite.api.MessageNode;
import net.runelite.api.NameableContainer;
import net.runelite.api.events.ChatMessage;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -54,6 +56,14 @@ public class FriendListPluginTest
@Bind
private FriendListConfig config;
@Mock
@Bind
private ConfigManager configManager;
@Mock
@Bind
private ChatMessageManager chatMessageManager;
@Inject
private FriendListPlugin friendListPlugin;
@@ -78,7 +88,7 @@ public class FriendListPluginTest
Friend friend = mock(Friend.class);
when(friend.getWorld()).thenReturn(311);
NameableContainer<Friend> friendContainer = mock(NameableContainer.class);
FriendContainer friendContainer = mock(FriendContainer.class);
when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend);
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.NpcChanged;
import net.runelite.api.events.NpcSpawned;
import net.runelite.client.menus.TestMenuEntry;
import net.runelite.client.ui.overlay.OverlayManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -49,7 +50,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@@ -111,13 +111,12 @@ public class NpcIndicatorsPluginTest
when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0
when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()});
MenuEntry entry = new TestMenuEntry();
when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry});
MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1);
npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded);
MenuEntry target = new MenuEntry();
target.setTarget("<col=ff0000>Goblin"); // red
verify(client).setMenuEntries(new MenuEntry[]{target});
assertEquals("<col=ff0000>Goblin", entry.getTarget()); // red
}
@Test
@@ -136,13 +135,12 @@ public class NpcIndicatorsPluginTest
when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0
when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()});
MenuEntry entry = new TestMenuEntry();
when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry});
MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1);
npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded);
MenuEntry target = new MenuEntry();
target.setTarget("<col=0000ff>Goblin"); // blue
verify(client).setMenuEntries(new MenuEntry[]{target});
assertEquals("<col=0000ff>Goblin", entry.getTarget()); // blue
}
@Test