project: Merge upstream
This commit is contained in:
@@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
object ProjectVersions {
|
object ProjectVersions {
|
||||||
const val launcherVersion = "2.2.0"
|
const val launcherVersion = "2.2.0"
|
||||||
const val rlVersion = "1.6.26"
|
const val rlVersion = "1.6.28"
|
||||||
|
|
||||||
const val openosrsVersion = "3.4.5"
|
const val openosrsVersion = "3.5.0"
|
||||||
|
|
||||||
const val rsversion = 191
|
const val rsversion = 191
|
||||||
const val cacheversion = 165
|
const val cacheversion = 165
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.cache.script.disassembler;
|
package net.runelite.cache.script.disassembler;
|
||||||
|
|
||||||
|
import com.google.common.escape.Escaper;
|
||||||
|
import com.google.common.escape.Escapers;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -37,6 +39,10 @@ import org.slf4j.LoggerFactory;
|
|||||||
public class Disassembler
|
public class Disassembler
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Disassembler.class);
|
private static final Logger logger = LoggerFactory.getLogger(Disassembler.class);
|
||||||
|
private static final Escaper ESCAPER = Escapers.builder()
|
||||||
|
.addEscape('"', "\\\"")
|
||||||
|
.addEscape('\\', "\\\\")
|
||||||
|
.build();
|
||||||
|
|
||||||
private final Instructions instructions = new Instructions();
|
private final Instructions instructions = new Instructions();
|
||||||
|
|
||||||
@@ -165,7 +171,7 @@ public class Disassembler
|
|||||||
|
|
||||||
if (sop != null)
|
if (sop != null)
|
||||||
{
|
{
|
||||||
writer.append(" \"").append(sop).append("\"");
|
writer.append(" \"").append(ESCAPER.escape(sop)).append("\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode == Opcodes.SWITCH)
|
if (opcode == Opcodes.SWITCH)
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
import static net.runelite.http.api.RuneLiteAPI.JSON;
|
import static net.runelite.http.api.RuneLiteAPI.JSON;
|
||||||
@@ -48,30 +50,29 @@ import okhttp3.RequestBody;
|
|||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@AllArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class LootTrackerClient
|
public class LootTrackerClient
|
||||||
{
|
{
|
||||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||||
|
|
||||||
private final OkHttpClient client;
|
private final OkHttpClient client;
|
||||||
private final UUID uuid;
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private UUID uuid;
|
||||||
|
|
||||||
public CompletableFuture<Void> submit(Collection<LootRecord> lootRecords)
|
public CompletableFuture<Void> submit(Collection<LootRecord> lootRecords)
|
||||||
{
|
{
|
||||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||||
|
|
||||||
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
|
||||||
.addPathSegment("loottracker")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
RequestBody body = RequestBody.Companion.create(GSON.toJson(lootRecords), JSON);
|
RequestBody body = RequestBody.Companion.create(GSON.toJson(lootRecords), JSON);
|
||||||
Request request = new Request.Builder()
|
Request.Builder requestBuilder = new Request.Builder();
|
||||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
if (uuid != null)
|
||||||
.post(body)
|
{
|
||||||
.url(url)
|
requestBuilder.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString());
|
||||||
.build();
|
}
|
||||||
|
requestBuilder.post(body);
|
||||||
|
|
||||||
client.newCall(request).enqueue(new Callback()
|
client.newCall(requestBuilder.build()).enqueue(new Callback()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call call, IOException e)
|
public void onFailure(Call call, IOException e)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import net.runelite.api.widgets.WidgetInfo;
|
|||||||
*/
|
*/
|
||||||
public class Perspective
|
public class Perspective
|
||||||
{
|
{
|
||||||
private static final double UNIT = Math.PI / 1024d; // How much of the circle each unit of SINE/COSINE is
|
public static final double UNIT = Math.PI / 1024d; // How much of the circle each unit of SINE/COSINE is
|
||||||
|
|
||||||
public static final int LOCAL_COORD_BITS = 7;
|
public static final int LOCAL_COORD_BITS = 7;
|
||||||
public static final int LOCAL_TILE_SIZE = 1 << LOCAL_COORD_BITS; // 128 - size of a tile in local coordinates
|
public static final int LOCAL_TILE_SIZE = 1 << LOCAL_COORD_BITS; // 128 - size of a tile in local coordinates
|
||||||
|
|||||||
@@ -493,6 +493,7 @@ public enum Varbits
|
|||||||
FARMING_7909(7909),
|
FARMING_7909(7909),
|
||||||
FARMING_7910(7910),
|
FARMING_7910(7910),
|
||||||
FARMING_7911(7911),
|
FARMING_7911(7911),
|
||||||
|
FARMING_7912(7912),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transmog controllers for grapes
|
* Transmog controllers for grapes
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ public class Text
|
|||||||
*
|
*
|
||||||
* @return true if all search terms matches at least one keyword, or false if otherwise.
|
* @return true if all search terms matches at least one keyword, or false if otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean matchesSearchTerms(String[] searchTerms, final Collection<String> keywords)
|
public static boolean matchesSearchTerms(Iterable<String> searchTerms, final Collection<String> keywords)
|
||||||
{
|
{
|
||||||
for (String term : searchTerms)
|
for (String term : searchTerms)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -173,6 +173,9 @@ public class WidgetID
|
|||||||
public static final int GAUNTLET_MAP_GROUP_ID = 638;
|
public static final int GAUNTLET_MAP_GROUP_ID = 638;
|
||||||
public static final int HALLOWED_SEPULCHRE_TIMER_GROUP_ID = 668;
|
public static final int HALLOWED_SEPULCHRE_TIMER_GROUP_ID = 668;
|
||||||
public static final int HEALTH_OVERLAY_BAR_GROUP_ID = 303;
|
public static final int HEALTH_OVERLAY_BAR_GROUP_ID = 303;
|
||||||
|
public static final int CHAMBERS_OF_XERIC_STORAGE_UNIT_PRIVATE_GROUP_ID = 271;
|
||||||
|
public static final int CHAMBERS_OF_XERIC_STORAGE_UNIT_SHARED_GROUP_ID = 550;
|
||||||
|
public static final int CHAMBERS_OF_XERIC_STORAGE_UNIT_INVENTORY_GROUP_ID = 551;
|
||||||
|
|
||||||
static class WorldMap
|
static class WorldMap
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Brett Middle <https://github.com/bmiddle>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.api;;
|
package net.runelite.api;;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class ExperienceTest
|
public class ExperienceTest
|
||||||
@@ -36,13 +37,13 @@ public class ExperienceTest
|
|||||||
public void testGetXpForLevel()
|
public void testGetXpForLevel()
|
||||||
{
|
{
|
||||||
int xp = Experience.getXpForLevel(99);
|
int xp = Experience.getXpForLevel(99);
|
||||||
Assert.assertEquals(XP_FOR_99, xp);
|
assertEquals(XP_FOR_99, xp);
|
||||||
|
|
||||||
xp = Experience.getXpForLevel(126);
|
xp = Experience.getXpForLevel(126);
|
||||||
Assert.assertEquals(XP_FOR_126, xp);
|
assertEquals(XP_FOR_126, xp);
|
||||||
|
|
||||||
xp = Experience.getXpForLevel(1);
|
xp = Experience.getXpForLevel(1);
|
||||||
Assert.assertEquals(0, xp);
|
assertEquals(0, xp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
@@ -61,22 +62,22 @@ public class ExperienceTest
|
|||||||
public void testGetLevelForXp()
|
public void testGetLevelForXp()
|
||||||
{
|
{
|
||||||
int level = Experience.getLevelForXp(XP_FOR_99);
|
int level = Experience.getLevelForXp(XP_FOR_99);
|
||||||
Assert.assertEquals(99, level);
|
assertEquals(99, level);
|
||||||
|
|
||||||
level = Experience.getLevelForXp(XP_FOR_99 - 1);
|
level = Experience.getLevelForXp(XP_FOR_99 - 1);
|
||||||
Assert.assertEquals(98, level);
|
assertEquals(98, level);
|
||||||
|
|
||||||
level = Experience.getLevelForXp(XP_FOR_126);
|
level = Experience.getLevelForXp(XP_FOR_126);
|
||||||
Assert.assertEquals(126, level);
|
assertEquals(126, level);
|
||||||
|
|
||||||
level = Experience.getLevelForXp(XP_FOR_126 - 1);
|
level = Experience.getLevelForXp(XP_FOR_126 - 1);
|
||||||
Assert.assertEquals(125, level);
|
assertEquals(125, level);
|
||||||
|
|
||||||
level = Experience.getLevelForXp(Integer.MAX_VALUE);
|
level = Experience.getLevelForXp(Integer.MAX_VALUE);
|
||||||
Assert.assertEquals(126, level);
|
assertEquals(126, level);
|
||||||
|
|
||||||
level = Experience.getLevelForXp(0);
|
level = Experience.getLevelForXp(0);
|
||||||
Assert.assertEquals(1, level);
|
assertEquals(1, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
@@ -88,7 +89,371 @@ public class ExperienceTest
|
|||||||
@Test
|
@Test
|
||||||
public void testGetCombatLevel()
|
public void testGetCombatLevel()
|
||||||
{
|
{
|
||||||
Assert.assertEquals(126, Experience.getCombatLevel(99, 99, 99, 99, 70, 42, 98));
|
assertEquals(126, Experience.getCombatLevel(99, 99, 99, 99, 70, 42, 98));
|
||||||
Assert.assertEquals(40, Experience.getCombatLevel(27, 22, 1, 36, 64, 45, 1));
|
assertEquals(40, Experience.getCombatLevel(27, 22, 1, 36, 64, 45, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNewPlayerNextCombatLevel()
|
||||||
|
{
|
||||||
|
int attackLevel = 1;
|
||||||
|
int strengthLevel = 1;
|
||||||
|
int defenceLevel = 1;
|
||||||
|
int hitpointsLevel = 10;
|
||||||
|
int magicLevel = 1;
|
||||||
|
int rangeLevel = 1;
|
||||||
|
int prayerLevel = 1;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int meleeNeed = Experience.getNextCombatLevelMelee(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int hpDefNeed = Experience.getNextCombatLevelHpDef(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int rangeNeed = Experience.getNextCombatLevelRange(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int magicNeed = Experience.getNextCombatLevelMagic(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(3, combatLevel);
|
||||||
|
|
||||||
|
// test attack/strength
|
||||||
|
assertEquals(2, meleeNeed);
|
||||||
|
|
||||||
|
// test defence/hitpoints
|
||||||
|
assertEquals(3, hpDefNeed);
|
||||||
|
|
||||||
|
// test ranged
|
||||||
|
assertEquals(2, rangeNeed);
|
||||||
|
|
||||||
|
// test magic
|
||||||
|
assertEquals(2, magicNeed);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(5, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAll10NextCombatLevel()
|
||||||
|
{
|
||||||
|
int attackLevel = 10;
|
||||||
|
int strengthLevel = 10;
|
||||||
|
int defenceLevel = 10;
|
||||||
|
int hitpointsLevel = 10;
|
||||||
|
int magicLevel = 10;
|
||||||
|
int rangeLevel = 10;
|
||||||
|
int prayerLevel = 10;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int meleeNeed = Experience.getNextCombatLevelMelee(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int hpDefNeed = Experience.getNextCombatLevelHpDef(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int rangeNeed = Experience.getNextCombatLevelRange(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int magicNeed = Experience.getNextCombatLevelMagic(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(12, combatLevel);
|
||||||
|
|
||||||
|
// test attack/strength
|
||||||
|
assertEquals(1, meleeNeed);
|
||||||
|
|
||||||
|
// test defence/hitpoints
|
||||||
|
assertEquals(1, hpDefNeed);
|
||||||
|
|
||||||
|
// test ranged
|
||||||
|
assertEquals(4, rangeNeed);
|
||||||
|
|
||||||
|
// test magic
|
||||||
|
assertEquals(4, magicNeed);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(2, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlayerBmidNextCombatLevel()
|
||||||
|
{
|
||||||
|
// snapshot of current stats 2018-10-2
|
||||||
|
int attackLevel = 65;
|
||||||
|
int strengthLevel = 70;
|
||||||
|
int defenceLevel = 60;
|
||||||
|
int hitpointsLevel = 71;
|
||||||
|
int magicLevel = 73;
|
||||||
|
int rangeLevel = 75;
|
||||||
|
int prayerLevel = 56;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int meleeNeed = Experience.getNextCombatLevelMelee(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int hpDefNeed = Experience.getNextCombatLevelHpDef(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int rangeNeed = Experience.getNextCombatLevelRange(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int magicNeed = Experience.getNextCombatLevelMagic(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(83, combatLevel);
|
||||||
|
|
||||||
|
// test attack/strength
|
||||||
|
assertEquals(2, meleeNeed);
|
||||||
|
|
||||||
|
// test defence/hitpoints
|
||||||
|
assertEquals(2, hpDefNeed);
|
||||||
|
|
||||||
|
// test ranged
|
||||||
|
assertEquals(17, rangeNeed);
|
||||||
|
|
||||||
|
// test magic
|
||||||
|
assertEquals(19, magicNeed);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(4, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlayerRuneliteNextCombatLevel()
|
||||||
|
{
|
||||||
|
// snapshot of current stats 2018-10-2
|
||||||
|
int attackLevel = 43;
|
||||||
|
int strengthLevel = 36;
|
||||||
|
int defenceLevel = 1;
|
||||||
|
int hitpointsLevel = 42;
|
||||||
|
int magicLevel = 64;
|
||||||
|
int rangeLevel = 51;
|
||||||
|
int prayerLevel = 15;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int meleeNeed = Experience.getNextCombatLevelMelee(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int hpDefNeed = Experience.getNextCombatLevelHpDef(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int rangeNeed = Experience.getNextCombatLevelRange(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int magicNeed = Experience.getNextCombatLevelMagic(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(43, combatLevel);
|
||||||
|
|
||||||
|
// test attack/strength
|
||||||
|
assertEquals(18, meleeNeed);
|
||||||
|
|
||||||
|
// test defence/hitpoints
|
||||||
|
assertEquals(2, hpDefNeed);
|
||||||
|
|
||||||
|
// test ranged
|
||||||
|
assertEquals(14, rangeNeed);
|
||||||
|
|
||||||
|
// test magic
|
||||||
|
assertEquals(1, magicNeed);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(3, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlayerZezimaNextCombatLevel()
|
||||||
|
{
|
||||||
|
// snapshot of current stats 2018-10-3
|
||||||
|
// Zezima cannot earn a combat level from ranged/magic anymore, so it won't show as the result is too high
|
||||||
|
int attackLevel = 74;
|
||||||
|
int strengthLevel = 74;
|
||||||
|
int defenceLevel = 72;
|
||||||
|
int hitpointsLevel = 72;
|
||||||
|
int magicLevel = 60;
|
||||||
|
int rangeLevel = 44;
|
||||||
|
int prayerLevel = 52;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int meleeNeed = Experience.getNextCombatLevelMelee(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int hpDefNeed = Experience.getNextCombatLevelHpDef(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(90, combatLevel);
|
||||||
|
|
||||||
|
// test attack/strength
|
||||||
|
assertEquals(2, meleeNeed);
|
||||||
|
|
||||||
|
// test defence/hitpoints
|
||||||
|
assertEquals(2, hpDefNeed);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(4, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrayerLevelsNeeded()
|
||||||
|
{
|
||||||
|
int attackLevel = 99;
|
||||||
|
int strengthLevel = 99;
|
||||||
|
int defenceLevel = 99;
|
||||||
|
int hitpointsLevel = 99;
|
||||||
|
int magicLevel = 99;
|
||||||
|
int rangeLevel = 99;
|
||||||
|
int prayerLevel = 89;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(124, combatLevel);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(1, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvenPrayerLevelsNeededWhenNearNextCombatLevel()
|
||||||
|
{
|
||||||
|
int attackLevel = 74;
|
||||||
|
int strengthLevel = 75;
|
||||||
|
int defenceLevel = 72;
|
||||||
|
int hitpointsLevel = 72;
|
||||||
|
int magicLevel = 60;
|
||||||
|
int rangeLevel = 44;
|
||||||
|
int prayerLevel = 52;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(90, combatLevel);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(2, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOddPrayerLevelsNeededWhenNearNextCombatLevel()
|
||||||
|
{
|
||||||
|
int attackLevel = 74;
|
||||||
|
int strengthLevel = 75;
|
||||||
|
int defenceLevel = 72;
|
||||||
|
int hitpointsLevel = 72;
|
||||||
|
int magicLevel = 60;
|
||||||
|
int rangeLevel = 44;
|
||||||
|
int prayerLevel = 53;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(90, combatLevel);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(1, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNextMagicLevelBarelyReachesNextCombatLevel()
|
||||||
|
{
|
||||||
|
int attackLevel = 40;
|
||||||
|
int strengthLevel = 44;
|
||||||
|
int defenceLevel = 46;
|
||||||
|
int hitpointsLevel = 39;
|
||||||
|
int magicLevel = 57;
|
||||||
|
int rangeLevel = 40;
|
||||||
|
int prayerLevel = 29;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int meleeNeed = Experience.getNextCombatLevelMelee(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int hpDefNeed = Experience.getNextCombatLevelHpDef(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int rangeNeed = Experience.getNextCombatLevelRange(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int magicNeed = Experience.getNextCombatLevelMagic(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(52, combatLevel);
|
||||||
|
|
||||||
|
// test attack/strength
|
||||||
|
assertEquals(3, meleeNeed);
|
||||||
|
|
||||||
|
// test defence/hitpoints
|
||||||
|
assertEquals(3, hpDefNeed);
|
||||||
|
|
||||||
|
// test ranged
|
||||||
|
assertEquals(18, rangeNeed);
|
||||||
|
|
||||||
|
// test magic
|
||||||
|
assertEquals(1, magicNeed);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(5, prayerNeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRangeMagicLevelsNeeded()
|
||||||
|
{
|
||||||
|
int attackLevel = 60;
|
||||||
|
int strengthLevel = 69;
|
||||||
|
int defenceLevel = 1;
|
||||||
|
int hitpointsLevel = 78;
|
||||||
|
int magicLevel = 85;
|
||||||
|
int rangeLevel = 85;
|
||||||
|
int prayerLevel = 52;
|
||||||
|
|
||||||
|
int combatLevel = Experience.getCombatLevel(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int meleeNeed = Experience.getNextCombatLevelMelee(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int hpDefNeed = Experience.getNextCombatLevelHpDef(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int rangeNeed = Experience.getNextCombatLevelRange(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int magicNeed = Experience.getNextCombatLevelMagic(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
int prayerNeed = Experience.getNextCombatLevelPrayer(attackLevel, strengthLevel, defenceLevel, hitpointsLevel,
|
||||||
|
magicLevel, rangeLevel, prayerLevel);
|
||||||
|
|
||||||
|
// test combat level
|
||||||
|
assertEquals(68, combatLevel);
|
||||||
|
|
||||||
|
// test attack/strength
|
||||||
|
assertEquals(3, meleeNeed);
|
||||||
|
|
||||||
|
// test defence/hitpoints
|
||||||
|
assertEquals(4, hpDefNeed);
|
||||||
|
|
||||||
|
// test ranged
|
||||||
|
assertEquals(3, rangeNeed);
|
||||||
|
|
||||||
|
// test magic
|
||||||
|
assertEquals(3, magicNeed);
|
||||||
|
|
||||||
|
// test prayer
|
||||||
|
assertEquals(8, prayerNeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ import net.runelite.client.ui.overlay.OverlayRenderer;
|
|||||||
import net.runelite.client.ui.overlay.WidgetOverlay;
|
import net.runelite.client.ui.overlay.WidgetOverlay;
|
||||||
import net.runelite.client.ui.overlay.arrow.ArrowMinimapOverlay;
|
import net.runelite.client.ui.overlay.arrow.ArrowMinimapOverlay;
|
||||||
import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay;
|
import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||||
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
|
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
|
||||||
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
|
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
|
||||||
@@ -190,7 +190,7 @@ public class RuneLite
|
|||||||
private Provider<CommandManager> commandManager;
|
private Provider<CommandManager> commandManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Provider<InfoBoxOverlay> infoBoxOverlay;
|
private Provider<InfoBoxManager> infoBoxManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Provider<TooltipOverlay> tooltipOverlay;
|
private Provider<TooltipOverlay> tooltipOverlay;
|
||||||
@@ -511,6 +511,7 @@ public class RuneLite
|
|||||||
// Initialize chat colors
|
// Initialize chat colors
|
||||||
chatMessageManager.get().loadColors();
|
chatMessageManager.get().loadColors();
|
||||||
|
|
||||||
|
infoBoxManager.get();
|
||||||
overlayRenderer.get();
|
overlayRenderer.get();
|
||||||
friendChatManager.get();
|
friendChatManager.get();
|
||||||
itemManager.get();
|
itemManager.get();
|
||||||
@@ -522,14 +523,12 @@ public class RuneLite
|
|||||||
playerManager.get();
|
playerManager.get();
|
||||||
chatboxPanelManager.get();
|
chatboxPanelManager.get();
|
||||||
partyService.get();
|
partyService.get();
|
||||||
infoBoxOverlay.get();
|
|
||||||
|
|
||||||
eventBus.subscribe(GameStateChanged.class, this, hooks::onGameStateChanged);
|
eventBus.subscribe(GameStateChanged.class, this, hooks::onGameStateChanged);
|
||||||
eventBus.subscribe(ScriptCallbackEvent.class, this, hooks::onScriptCallbackEvent);
|
eventBus.subscribe(ScriptCallbackEvent.class, this, hooks::onScriptCallbackEvent);
|
||||||
|
|
||||||
// Add core overlays
|
// Add core overlays
|
||||||
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
|
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
|
||||||
overlayManager.add(infoBoxOverlay.get());
|
|
||||||
overlayManager.add(worldMapOverlay.get());
|
overlayManager.add(worldMapOverlay.get());
|
||||||
overlayManager.add(tooltipOverlay.get());
|
overlayManager.add(tooltipOverlay.get());
|
||||||
overlayManager.add(arrowWorldOverlay.get());
|
overlayManager.add(arrowWorldOverlay.get());
|
||||||
|
|||||||
@@ -400,12 +400,25 @@ public interface RuneLiteConfig extends Config
|
|||||||
return new Title();
|
return new Title();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "infoBoxTextOutline",
|
||||||
|
name = "Outline infobox text",
|
||||||
|
description = "Draw a full outline instead of a simple shadow for infobox text",
|
||||||
|
position = 31,
|
||||||
|
titleSection = "infoboxTitle"
|
||||||
|
)
|
||||||
|
default boolean infoBoxTextOutline()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "infoBoxVertical",
|
keyName = "infoBoxVertical",
|
||||||
name = "Display infoboxes vertically",
|
name = "Display infoboxes vertically",
|
||||||
description = "Toggles the infoboxes to display vertically",
|
description = "Toggles the infoboxes to display vertically",
|
||||||
position = 31,
|
position = 32,
|
||||||
titleSection = "infoboxTitle"
|
titleSection = "infoboxTitle",
|
||||||
|
hidden = true
|
||||||
)
|
)
|
||||||
default boolean infoBoxVertical()
|
default boolean infoBoxVertical()
|
||||||
{
|
{
|
||||||
@@ -416,7 +429,7 @@ public interface RuneLiteConfig extends Config
|
|||||||
keyName = "infoBoxSize",
|
keyName = "infoBoxSize",
|
||||||
name = "Infobox size",
|
name = "Infobox size",
|
||||||
description = "Configures the size of each infobox in pixels",
|
description = "Configures the size of each infobox in pixels",
|
||||||
position = 32,
|
position = 33,
|
||||||
titleSection = "infoboxTitle"
|
titleSection = "infoboxTitle"
|
||||||
)
|
)
|
||||||
@Units(Units.PIXELS)
|
@Units(Units.PIXELS)
|
||||||
@@ -429,7 +442,7 @@ public interface RuneLiteConfig extends Config
|
|||||||
keyName = "keybindsTitle",
|
keyName = "keybindsTitle",
|
||||||
name = "Key binds",
|
name = "Key binds",
|
||||||
description = "",
|
description = "",
|
||||||
position = 33
|
position = 34
|
||||||
)
|
)
|
||||||
default Title keybindsTitle()
|
default Title keybindsTitle()
|
||||||
{
|
{
|
||||||
@@ -440,7 +453,7 @@ public interface RuneLiteConfig extends Config
|
|||||||
keyName = "sidebarToggleKey",
|
keyName = "sidebarToggleKey",
|
||||||
name = "Sidebar Toggle Key",
|
name = "Sidebar Toggle Key",
|
||||||
description = "The key that will toggle the sidebar (accepts modifiers)",
|
description = "The key that will toggle the sidebar (accepts modifiers)",
|
||||||
position = 34,
|
position = 35,
|
||||||
titleSection = "keybindsTitle"
|
titleSection = "keybindsTitle"
|
||||||
)
|
)
|
||||||
default Keybind sidebarToggleKey()
|
default Keybind sidebarToggleKey()
|
||||||
@@ -452,7 +465,7 @@ public interface RuneLiteConfig extends Config
|
|||||||
keyName = "panelToggleKey",
|
keyName = "panelToggleKey",
|
||||||
name = "Plugin Panel Toggle Key",
|
name = "Plugin Panel Toggle Key",
|
||||||
description = "The key that will toggle the current or last opened plugin panel (accepts modifiers)",
|
description = "The key that will toggle the current or last opened plugin panel (accepts modifiers)",
|
||||||
position = 35,
|
position = 36,
|
||||||
titleSection = "keybindsTitle"
|
titleSection = "keybindsTitle"
|
||||||
)
|
)
|
||||||
default Keybind panelToggleKey()
|
default Keybind panelToggleKey()
|
||||||
@@ -464,7 +477,7 @@ public interface RuneLiteConfig extends Config
|
|||||||
keyName = "blockExtraMouseButtons",
|
keyName = "blockExtraMouseButtons",
|
||||||
name = "Block Extra Mouse Buttons",
|
name = "Block Extra Mouse Buttons",
|
||||||
description = "Blocks extra mouse buttons (4 and above)",
|
description = "Blocks extra mouse buttons (4 and above)",
|
||||||
position = 36,
|
position = 37,
|
||||||
titleSection = "keybindsTitle"
|
titleSection = "keybindsTitle"
|
||||||
)
|
)
|
||||||
default boolean blockExtraMouseButtons()
|
default boolean blockExtraMouseButtons()
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ public enum AgilityShortcut
|
|||||||
AL_KHARID_WINDOW(70, "Window", new WorldPoint(3293, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW),
|
AL_KHARID_WINDOW(70, "Window", new WorldPoint(3293, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW),
|
||||||
GWD_SARADOMIN_ROPE_NORTH(70, "Rope Descent", new WorldPoint(2912, 5300, 0), NULL_26371, NULL_26561),
|
GWD_SARADOMIN_ROPE_NORTH(70, "Rope Descent", new WorldPoint(2912, 5300, 0), NULL_26371, NULL_26561),
|
||||||
GWD_SARADOMIN_ROPE_SOUTH(70, "Rope Descent", new WorldPoint(2951, 5267, 0), NULL_26375, NULL_26562),
|
GWD_SARADOMIN_ROPE_SOUTH(70, "Rope Descent", new WorldPoint(2951, 5267, 0), NULL_26375, NULL_26562),
|
||||||
|
GU_TANOTH_CRUMBLING_WALL(71, "Rocks", new WorldPoint(2545, 3032, 0), CRUMBLING_WALL_40355, ROCKS_40356),
|
||||||
SLAYER_TOWER_ADVANCED_CHAIN_FIRST(71, "Spiked Chain (Floor 2)", new WorldPoint(3447, 3578, 0), SPIKEY_CHAIN ),
|
SLAYER_TOWER_ADVANCED_CHAIN_FIRST(71, "Spiked Chain (Floor 2)", new WorldPoint(3447, 3578, 0), SPIKEY_CHAIN ),
|
||||||
SLAYER_TOWER_ADVANCED_CHAIN_SECOND(71, "Spiked Chain (Floor 3)", new WorldPoint(3446, 3576, 0), SPIKEY_CHAIN_16538),
|
SLAYER_TOWER_ADVANCED_CHAIN_SECOND(71, "Spiked Chain (Floor 3)", new WorldPoint(3446, 3576, 0), SPIKEY_CHAIN_16538),
|
||||||
STRONGHOLD_SLAYER_CAVE_TUNNEL(72, "Tunnel", new WorldPoint(2431, 9806, 0), TUNNEL_30174, TUNNEL_30175),
|
STRONGHOLD_SLAYER_CAVE_TUNNEL(72, "Tunnel", new WorldPoint(2431, 9806, 0), TUNNEL_30174, TUNNEL_30175),
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -276,10 +277,10 @@ public class ItemManager
|
|||||||
/**
|
/**
|
||||||
* Look up an item's price
|
* Look up an item's price
|
||||||
*
|
*
|
||||||
* @param itemID item id
|
* @param itemID item id
|
||||||
* @param ignoreUntradeableMap should the price returned ignore the {@link UntradeableItemMapping}
|
* @param ignoreUntradeableMap should the price returned ignore items that are not tradeable for coins in regular way
|
||||||
* @return item price
|
* @return item price
|
||||||
*/
|
* */
|
||||||
public int getItemPrice(int itemID, boolean ignoreUntradeableMap)
|
public int getItemPrice(int itemID, boolean ignoreUntradeableMap)
|
||||||
{
|
{
|
||||||
if (itemID == ItemID.COINS_995)
|
if (itemID == ItemID.COINS_995)
|
||||||
@@ -291,31 +292,38 @@ public class ItemManager
|
|||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemDefinition itemComposition = getItemDefinition(itemID);
|
ItemDefinition itemDefinition = getItemDefinition(itemID);
|
||||||
if (itemComposition.getNote() != -1)
|
if (itemDefinition.getNote() != -1)
|
||||||
{
|
{
|
||||||
itemID = itemComposition.getLinkedNoteId();
|
itemID = itemDefinition.getLinkedNoteId();
|
||||||
}
|
}
|
||||||
itemID = WORN_ITEMS.getOrDefault(itemID, itemID);
|
itemID = WORN_ITEMS.getOrDefault(itemID, itemID);
|
||||||
|
|
||||||
if (!ignoreUntradeableMap)
|
|
||||||
{
|
|
||||||
UntradeableItemMapping p = UntradeableItemMapping.map(ItemVariationMapping.map(itemID));
|
|
||||||
if (p != null)
|
|
||||||
{
|
|
||||||
return getItemPrice(p.getPriceID()) * p.getQuantity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int price = 0;
|
int price = 0;
|
||||||
for (int mappedID : ItemMapping.map(itemID))
|
|
||||||
|
final Collection<ItemMapping> mappedItems = ItemMapping.map(itemID);
|
||||||
|
|
||||||
|
if (mappedItems == null)
|
||||||
{
|
{
|
||||||
ItemPrice ip = itemPrices.get(mappedID);
|
final ItemPrice ip = itemPrices.get(itemID);
|
||||||
|
|
||||||
if (ip != null)
|
if (ip != null)
|
||||||
{
|
{
|
||||||
price += ip.getPrice();
|
price += ip.getPrice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (final ItemMapping mappedItem : mappedItems)
|
||||||
|
{
|
||||||
|
if (ignoreUntradeableMap && mappedItem.isUntradeable())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
price += getItemPrice(mappedItem.getTradeableItem(), ignoreUntradeableMap) * mappedItem.getQuantity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,12 +28,14 @@ package net.runelite.client.game;
|
|||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import javax.annotation.Nullable;
|
||||||
|
import lombok.Getter;
|
||||||
import static net.runelite.api.ItemID.*;
|
import static net.runelite.api.ItemID.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts untradeable items to it's tradeable counterparts
|
* Converts untradeable items to it's tradeable counterparts
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
public enum ItemMapping
|
public enum ItemMapping
|
||||||
{
|
{
|
||||||
// Barrows equipment
|
// Barrows equipment
|
||||||
@@ -249,6 +251,9 @@ public enum ItemMapping
|
|||||||
ITEM_CRYSTAL_BOW(CRYSTAL_WEAPON_SEED, CRYSTAL_BOW, CRYSTAL_BOW_24123, CRYSTAL_BOW_INACTIVE),
|
ITEM_CRYSTAL_BOW(CRYSTAL_WEAPON_SEED, CRYSTAL_BOW, CRYSTAL_BOW_24123, CRYSTAL_BOW_INACTIVE),
|
||||||
ITEM_CRYSTAL_HALBERD(CRYSTAL_WEAPON_SEED, CRYSTAL_HALBERD, CRYSTAL_HALBERD_24125, CRYSTAL_HALBERD_INACTIVE),
|
ITEM_CRYSTAL_HALBERD(CRYSTAL_WEAPON_SEED, CRYSTAL_HALBERD, CRYSTAL_HALBERD_24125, CRYSTAL_HALBERD_INACTIVE),
|
||||||
ITEM_CRYSTAL_SHIELD(CRYSTAL_WEAPON_SEED, CRYSTAL_SHIELD, CRYSTAL_SHIELD_24127, CRYSTAL_SHIELD_INACTIVE),
|
ITEM_CRYSTAL_SHIELD(CRYSTAL_WEAPON_SEED, CRYSTAL_SHIELD, CRYSTAL_SHIELD_24127, CRYSTAL_SHIELD_INACTIVE),
|
||||||
|
ITEM_CRYSTAL_HELMET(CRYSTAL_ARMOUR_SEED, CRYSTAL_HELM, CRYSTAL_HELM_INACTIVE),
|
||||||
|
ITEM_CRYSTAL_LEGS(CRYSTAL_ARMOUR_SEED, 2L, CRYSTAL_LEGS, CRYSTAL_LEGS_INACTIVE),
|
||||||
|
ITEM_CRYSTAL_BODY(CRYSTAL_ARMOUR_SEED, 3L, CRYSTAL_BODY, CRYSTAL_BODY_INACTIVE),
|
||||||
|
|
||||||
// Bird nests
|
// Bird nests
|
||||||
ITEM_BIRD_NEST(BIRD_NEST_5075, BIRD_NEST, BIRD_NEST_5071, BIRD_NEST_5072, BIRD_NEST_5073, BIRD_NEST_5074, BIRD_NEST_7413, BIRD_NEST_13653, BIRD_NEST_22798, BIRD_NEST_22800, CLUE_NEST_EASY, CLUE_NEST_MEDIUM, CLUE_NEST_HARD, CLUE_NEST_ELITE),
|
ITEM_BIRD_NEST(BIRD_NEST_5075, BIRD_NEST, BIRD_NEST_5071, BIRD_NEST_5072, BIRD_NEST_5073, BIRD_NEST_5074, BIRD_NEST_7413, BIRD_NEST_13653, BIRD_NEST_22798, BIRD_NEST_22800, CLUE_NEST_EASY, CLUE_NEST_MEDIUM, CLUE_NEST_HARD, CLUE_NEST_ELITE),
|
||||||
@@ -256,11 +261,41 @@ public enum ItemMapping
|
|||||||
// Ancestral robes
|
// Ancestral robes
|
||||||
ITEM_ANCESTRAL_HAT(ANCESTRAL_HAT, TWISTED_ANCESTRAL_HAT),
|
ITEM_ANCESTRAL_HAT(ANCESTRAL_HAT, TWISTED_ANCESTRAL_HAT),
|
||||||
ITEM_ANCESTRAL_ROBE_TOP(ANCESTRAL_ROBE_TOP, TWISTED_ANCESTRAL_ROBE_TOP),
|
ITEM_ANCESTRAL_ROBE_TOP(ANCESTRAL_ROBE_TOP, TWISTED_ANCESTRAL_ROBE_TOP),
|
||||||
ITEM_ANCESTRAL_ROBE_BOTTOM(ANCESTRAL_ROBE_BOTTOM, TWISTED_ANCESTRAL_ROBE_BOTTOM);
|
ITEM_ANCESTRAL_ROBE_BOTTOM(ANCESTRAL_ROBE_BOTTOM, TWISTED_ANCESTRAL_ROBE_BOTTOM),
|
||||||
|
|
||||||
private static final Multimap<Integer, Integer> MAPPINGS = HashMultimap.create();
|
// Graceful
|
||||||
|
ITEM_MARK_OF_GRACE(AMYLASE_CRYSTAL, true, 10L, MARK_OF_GRACE),
|
||||||
|
ITEM_GRACEFUL_HOOD(MARK_OF_GRACE, true, 28L, GRACEFUL_HOOD),
|
||||||
|
ITEM_GRACEFUL_TOP(MARK_OF_GRACE, true, 44L, GRACEFUL_TOP),
|
||||||
|
ITEM_GRACEFUL_LEGS(MARK_OF_GRACE, true, 48L, GRACEFUL_LEGS),
|
||||||
|
ITEM_GRACEFUL_GLOVES(MARK_OF_GRACE, true, 24L, GRACEFUL_GLOVES),
|
||||||
|
ITEM_GRACEFUL_BOOTS(MARK_OF_GRACE, true, 32L, GRACEFUL_BOOTS),
|
||||||
|
ITEM_GRACEFUL_CAPE(MARK_OF_GRACE, true, 32L, GRACEFUL_CAPE),
|
||||||
|
|
||||||
|
// 10 golden nuggets = 100 soft clay
|
||||||
|
ITEM_GOLDEN_NUGGET(SOFT_CLAY, true, 10L, GOLDEN_NUGGET),
|
||||||
|
ITEM_PROSPECTOR_HELMET(GOLDEN_NUGGET, true, 32L, PROSPECTOR_HELMET),
|
||||||
|
ITEM_PROSPECTOR_JACKET(GOLDEN_NUGGET, true, 48L, PROSPECTOR_JACKET),
|
||||||
|
ITEM_PROSPECTOR_LEGS(GOLDEN_NUGGET, true, 40L, PROSPECTOR_LEGS),
|
||||||
|
ITEM_PROSPECTOR_BOOTS(GOLDEN_NUGGET, true, 24L, PROSPECTOR_BOOTS),
|
||||||
|
|
||||||
|
// 10 unidentified minerals = 100 soft clay
|
||||||
|
ITEM_UNIDENTIFIED_MINERALS(SOFT_CLAY, true, 10L, UNIDENTIFIED_MINERALS),
|
||||||
|
|
||||||
|
// Converted to coins
|
||||||
|
ITEM_TATTERED_PAGE(COINS_995, true, 1000L, TATTERED_MOON_PAGE, TATTERED_SUN_PAGE, TATTERED_TEMPLE_PAGE),
|
||||||
|
ITEM_LONG_BONE(COINS_995, true, 1000L, LONG_BONE),
|
||||||
|
ITEM_CURVED_BONE(COINS_995, true, 2000L, CURVED_BONE),
|
||||||
|
ITEM_PERFECT_SHELL(COINS_995, true, 600L, PERFECT_SHELL),
|
||||||
|
ITEM_PERFECT_SNAIL_SHELL(COINS_995, true, 600L, PERFECT_SNAIL_SHELL),
|
||||||
|
ITEM_SNAIL_SHELL(COINS_995, true, 600L, SNAIL_SHELL),
|
||||||
|
ITEM_TORTOISE_SHELL(COINS_995, true, 250L, TORTOISE_SHELL);
|
||||||
|
|
||||||
|
private static final Multimap<Integer, ItemMapping> MAPPINGS = HashMultimap.create();
|
||||||
private final int tradeableItem;
|
private final int tradeableItem;
|
||||||
private final int[] untradableItems;
|
private final int[] untradableItems;
|
||||||
|
private final long quantity;
|
||||||
|
private final boolean untradeable;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
@@ -268,15 +303,35 @@ public enum ItemMapping
|
|||||||
{
|
{
|
||||||
for (int itemId : item.untradableItems)
|
for (int itemId : item.untradableItems)
|
||||||
{
|
{
|
||||||
MAPPINGS.put(itemId, item.tradeableItem);
|
if (item.untradeable)
|
||||||
|
{
|
||||||
|
for (final Integer variation : ItemVariationMapping.getVariations(itemId))
|
||||||
|
{
|
||||||
|
MAPPINGS.put(variation, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MAPPINGS.put(itemId, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemMapping(int tradeableItem, int... untradableItems)
|
ItemMapping(int tradeableItem, boolean untradeable, long quantity, int... untradableItems)
|
||||||
{
|
{
|
||||||
this.tradeableItem = tradeableItem;
|
this.tradeableItem = tradeableItem;
|
||||||
this.untradableItems = untradableItems;
|
this.untradableItems = untradableItems;
|
||||||
|
this.quantity = quantity;
|
||||||
|
this.untradeable = untradeable;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMapping(int tradeableItem, long quantity, int... untradableItems)
|
||||||
|
{
|
||||||
|
this(tradeableItem, false, quantity, untradableItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMapping(int tradeableItem, int... untradableItems)
|
||||||
|
{
|
||||||
|
this(tradeableItem, 1L, untradableItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -285,36 +340,19 @@ public enum ItemMapping
|
|||||||
* @param itemId the item id
|
* @param itemId the item id
|
||||||
* @return the collection
|
* @return the collection
|
||||||
*/
|
*/
|
||||||
public static Collection<Integer> map(int itemId)
|
@Nullable
|
||||||
|
public static Collection<ItemMapping> map(int itemId)
|
||||||
{
|
{
|
||||||
final Collection<Integer> mapping = MAPPINGS.get(itemId);
|
final Collection<ItemMapping> mapping = MAPPINGS.get(itemId);
|
||||||
|
|
||||||
if (mapping == null || mapping.isEmpty())
|
if (mapping.isEmpty())
|
||||||
{
|
{
|
||||||
return Collections.singleton(itemId);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Map an item from its untradeable version to its tradeable version
|
|
||||||
*
|
|
||||||
* @param itemId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static int mapFirst(int itemId)
|
|
||||||
{
|
|
||||||
final Collection<Integer> mapping = MAPPINGS.get(itemId);
|
|
||||||
|
|
||||||
if (mapping == null || mapping.isEmpty())
|
|
||||||
{
|
|
||||||
return itemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapping.iterator().next();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isMapped(int itemId)
|
public static boolean isMapped(int itemId)
|
||||||
{
|
{
|
||||||
return MAPPINGS.containsValue(itemId);
|
return MAPPINGS.containsValue(itemId);
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
|
||||||
* 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.game;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import net.runelite.api.ItemID;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public enum UntradeableItemMapping
|
|
||||||
{
|
|
||||||
MARK_OF_GRACE(ItemID.MARK_OF_GRACE, 10, ItemID.AMYLASE_CRYSTAL),
|
|
||||||
GRACEFUL_HOOD(ItemID.GRACEFUL_HOOD, 28, ItemID.MARK_OF_GRACE),
|
|
||||||
GRACEFUL_TOP(ItemID.GRACEFUL_TOP, 44, ItemID.MARK_OF_GRACE),
|
|
||||||
GRACEFUL_LEGS(ItemID.GRACEFUL_LEGS, 48, ItemID.MARK_OF_GRACE),
|
|
||||||
GRACEFUL_GLOVES(ItemID.GRACEFUL_GLOVES, 24, ItemID.MARK_OF_GRACE),
|
|
||||||
GRACEFUL_BOOTS(ItemID.GRACEFUL_BOOTS, 32, ItemID.MARK_OF_GRACE),
|
|
||||||
GRACEFUL_CAPE(ItemID.GRACEFUL_CAPE, 32, ItemID.MARK_OF_GRACE),
|
|
||||||
|
|
||||||
// 10 golden nuggets = 100 soft clay
|
|
||||||
GOLDEN_NUGGET(ItemID.GOLDEN_NUGGET, 10, ItemID.SOFT_CLAY),
|
|
||||||
PROSPECTOR_HELMET(ItemID.PROSPECTOR_HELMET, 32, ItemID.GOLDEN_NUGGET),
|
|
||||||
PROSPECTOR_JACKET(ItemID.PROSPECTOR_JACKET, 48, ItemID.GOLDEN_NUGGET),
|
|
||||||
PROSPECTOR_LEGS(ItemID.PROSPECTOR_LEGS, 40, ItemID.GOLDEN_NUGGET),
|
|
||||||
PROSPECTOR_BOOTS(ItemID.PROSPECTOR_BOOTS, 24, ItemID.GOLDEN_NUGGET),
|
|
||||||
|
|
||||||
CRYSTAL_HELMET(ItemID.CRYSTAL_HELM, 1, ItemID.CRYSTAL_ARMOUR_SEED),
|
|
||||||
CRYSTAL_HELMET_INACTIVE(ItemID.CRYSTAL_HELM_INACTIVE, 1, ItemID.CRYSTAL_ARMOUR_SEED),
|
|
||||||
CRYSTAL_LEGS(ItemID.CRYSTAL_LEGS, 2, ItemID.CRYSTAL_ARMOUR_SEED),
|
|
||||||
CRYSTAL_LEGS_INACTIVE(ItemID.CRYSTAL_LEGS_INACTIVE, 2, ItemID.CRYSTAL_ARMOUR_SEED),
|
|
||||||
CRYSTAL_BODY(ItemID.CRYSTAL_BODY, 3, ItemID.CRYSTAL_ARMOUR_SEED),
|
|
||||||
CRYSTAL_BODY_INACTIVE(ItemID.CRYSTAL_BODY_INACTIVE, 3, ItemID.CRYSTAL_ARMOUR_SEED),
|
|
||||||
|
|
||||||
TATTERED_MOON_PAGE(ItemID.TATTERED_MOON_PAGE, 1000, ItemID.COINS_995),
|
|
||||||
TATTERED_SUN_PAGE(ItemID.TATTERED_SUN_PAGE, 1000, ItemID.COINS_995),
|
|
||||||
TATTERED_TEMPLE_PAGE(ItemID.TATTERED_TEMPLE_PAGE, 1000, ItemID.COINS_995),
|
|
||||||
|
|
||||||
LONG_BONE(ItemID.LONG_BONE, 1000, ItemID.COINS_995),
|
|
||||||
CURVED_BONE(ItemID.CURVED_BONE, 2000, ItemID.COINS_995),
|
|
||||||
PERFECT_SHELL(ItemID.PERFECT_SHELL, 600, ItemID.COINS_995),
|
|
||||||
PERFECT_SNAIL_SHELL(ItemID.PERFECT_SNAIL_SHELL, 600, ItemID.COINS_995),
|
|
||||||
SNAIL_SHELL(ItemID.SNAIL_SHELL, 600, ItemID.COINS_995),
|
|
||||||
TORTOISE_SHELL(ItemID.TORTOISE_SHELL, 250, ItemID.COINS_995);
|
|
||||||
|
|
||||||
private static final ImmutableMap<Integer, UntradeableItemMapping> UNTRADEABLE_RECLAIM_MAP;
|
|
||||||
|
|
||||||
private final int itemID;
|
|
||||||
private final int quantity;
|
|
||||||
private final int priceID;
|
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
ImmutableMap.Builder<Integer, UntradeableItemMapping> map = ImmutableMap.builder();
|
|
||||||
for (UntradeableItemMapping p : values())
|
|
||||||
{
|
|
||||||
map.put(p.getItemID(), p);
|
|
||||||
}
|
|
||||||
UNTRADEABLE_RECLAIM_MAP = map.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UntradeableItemMapping map(int itemId)
|
|
||||||
{
|
|
||||||
return UNTRADEABLE_RECLAIM_MAP.get(itemId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -30,10 +30,12 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@Slf4j
|
||||||
public class KeyManager
|
public class KeyManager
|
||||||
{
|
{
|
||||||
private final Client client;
|
private final Client client;
|
||||||
@@ -50,13 +52,18 @@ public class KeyManager
|
|||||||
{
|
{
|
||||||
if (!keyListeners.contains(keyListener))
|
if (!keyListeners.contains(keyListener))
|
||||||
{
|
{
|
||||||
|
log.debug("Registering key listener: {}", keyListener);
|
||||||
keyListeners.add(keyListener);
|
keyListeners.add(keyListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterKeyListener(KeyListener keyListener)
|
public void unregisterKeyListener(KeyListener keyListener)
|
||||||
{
|
{
|
||||||
keyListeners.remove(keyListener);
|
final boolean unregistered = keyListeners.remove(keyListener);
|
||||||
|
if (unregistered)
|
||||||
|
{
|
||||||
|
log.debug("Unregistered key listener: {}", keyListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processKeyPressed(KeyEvent keyEvent)
|
public void processKeyPressed(KeyEvent keyEvent)
|
||||||
@@ -73,9 +80,12 @@ public class KeyManager
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.trace("Processing key pressed {} for key listener {}", keyEvent.paramString(), keyListener);
|
||||||
|
|
||||||
keyListener.keyPressed(keyEvent);
|
keyListener.keyPressed(keyEvent);
|
||||||
if (keyEvent.isConsumed())
|
if (keyEvent.isConsumed())
|
||||||
{
|
{
|
||||||
|
log.debug("Consuming key pressed {} for key listener {}", keyEvent.paramString(), keyListener);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,9 +105,12 @@ public class KeyManager
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.trace("Processing key released {} for key listener {}", keyEvent.paramString(), keyListener);
|
||||||
|
|
||||||
keyListener.keyReleased(keyEvent);
|
keyListener.keyReleased(keyEvent);
|
||||||
if (keyEvent.isConsumed())
|
if (keyEvent.isConsumed())
|
||||||
{
|
{
|
||||||
|
log.debug("Consuming key released {} for listener {}", keyEvent.paramString(), keyListener);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,9 +130,12 @@ public class KeyManager
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.trace("Processing key typed {} for key listener {}", keyEvent.paramString(), keyListener);
|
||||||
|
|
||||||
keyListener.keyTyped(keyEvent);
|
keyListener.keyTyped(keyEvent);
|
||||||
if (keyEvent.isConsumed())
|
if (keyEvent.isConsumed())
|
||||||
{
|
{
|
||||||
|
log.debug("Consuming key typed {} for key listener {}", keyEvent.paramString(), keyListener);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.config;
|
package net.runelite.client.plugins.config;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
@@ -102,6 +103,7 @@ public class PluginListPanel extends PluginPanel
|
|||||||
|
|
||||||
private static final String RUNELITE_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).value();
|
private static final String RUNELITE_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).value();
|
||||||
private static final String PINNED_PLUGINS_CONFIG_KEY = "pinnedPlugins";
|
private static final String PINNED_PLUGINS_CONFIG_KEY = "pinnedPlugins";
|
||||||
|
private static final Splitter SPLITTER = Splitter.on(" ").trimResults().omitEmptyStrings();
|
||||||
private static final List<String> CATEGORY_TAGS = List.of(
|
private static final List<String> CATEGORY_TAGS = List.of(
|
||||||
"Combat",
|
"Combat",
|
||||||
"Chat",
|
"Chat",
|
||||||
@@ -443,10 +445,9 @@ public class PluginListPanel extends PluginPanel
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final String[] searchTerms = text.toLowerCase().split(" ");
|
|
||||||
pluginList.forEach(listItem ->
|
pluginList.forEach(listItem ->
|
||||||
{
|
{
|
||||||
if (pinned == listItem.isPinned() && Text.matchesSearchTerms(searchTerms, listItem.getKeywords()))
|
if (pinned == listItem.isPinned() && Text.matchesSearchTerms(SPLITTER.split(text.toLowerCase()), listItem.getKeywords()))
|
||||||
{
|
{
|
||||||
if (openOSRSConfig.pluginSortMode() == OpenOSRSConfig.SortStyle.ALPHABETICALLY || (!openOSRSConfig.enableCategories() && (openOSRSConfig.pluginSortMode() != OpenOSRSConfig.SortStyle.REPOSITORY)))
|
if (openOSRSConfig.pluginSortMode() == OpenOSRSConfig.SortStyle.ALPHABETICALLY || (!openOSRSConfig.enableCategories() && (openOSRSConfig.pluginSortMode() != OpenOSRSConfig.SortStyle.REPOSITORY)))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.ui;
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.GraphicsConfiguration;
|
import java.awt.GraphicsConfiguration;
|
||||||
import java.awt.GraphicsDevice;
|
import java.awt.GraphicsDevice;
|
||||||
@@ -49,6 +50,7 @@ public class ContainableFrame extends JFrame
|
|||||||
NEVER
|
NEVER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int SCREEN_EDGE_CLOSE_DISTANCE = 40;
|
||||||
private static boolean jdk8231564;
|
private static boolean jdk8231564;
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -56,9 +58,7 @@ public class ContainableFrame extends JFrame
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
String javaVersion = System.getProperty("java.version");
|
String javaVersion = System.getProperty("java.version");
|
||||||
String[] s = javaVersion.split("\\.");
|
jdk8231564 = jdk8231564(javaVersion);
|
||||||
int major = Integer.parseInt(s[0]), minor = Integer.parseInt(s[1]), patch = Integer.parseInt(s[2]);
|
|
||||||
jdk8231564 = major > 11 || (major == 11 && minor > 0) || (major == 11 && minor == 0 && patch >= 8);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -66,7 +66,23 @@ public class ContainableFrame extends JFrame
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int SCREEN_EDGE_CLOSE_DISTANCE = 40;
|
@VisibleForTesting
|
||||||
|
static boolean jdk8231564(String javaVersion)
|
||||||
|
{
|
||||||
|
int idx = javaVersion.indexOf('_');
|
||||||
|
if (idx != -1)
|
||||||
|
{
|
||||||
|
javaVersion = javaVersion.substring(0, idx);
|
||||||
|
}
|
||||||
|
String[] s = javaVersion.split("\\.");
|
||||||
|
int major = Integer.parseInt(s[0]), minor = Integer.parseInt(s[1]), patch = Integer.parseInt(s[2]);
|
||||||
|
if (major == 12 || major == 13 || major == 14)
|
||||||
|
{
|
||||||
|
// These versions are since EOL & do not include JDK-8231564
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return major > 11 || (major == 11 && minor > 0) || (major == 11 && minor == 0 && patch >= 8);
|
||||||
|
}
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private ExpandResizeType expandResizeType;
|
private ExpandResizeType expandResizeType;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import java.awt.Rectangle;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
@@ -52,6 +53,13 @@ public abstract class Overlay implements LayoutableRenderableEntity
|
|||||||
private boolean resizable;
|
private boolean resizable;
|
||||||
private boolean resettable = true;
|
private boolean resettable = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this overlay can be dragged onto other overlays & have
|
||||||
|
* other overlays dragged onto it.
|
||||||
|
*/
|
||||||
|
@Setter(AccessLevel.PROTECTED)
|
||||||
|
private boolean dragTargetable;
|
||||||
|
|
||||||
protected Overlay()
|
protected Overlay()
|
||||||
{
|
{
|
||||||
plugin = null;
|
plugin = null;
|
||||||
@@ -75,4 +83,17 @@ public abstract class Overlay implements LayoutableRenderableEntity
|
|||||||
public void onMouseOver()
|
public void onMouseOver()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an overlay is dragged onto this, if dragTargetable is true.
|
||||||
|
* Return true to consume the mouse event and prevent the other
|
||||||
|
* overlay from being moved
|
||||||
|
*
|
||||||
|
* @param other the overlay being dragged
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean onDrag(Overlay other)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import lombok.Setter;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.KeyCode;
|
||||||
import net.runelite.api.MenuEntry;
|
import net.runelite.api.MenuEntry;
|
||||||
import net.runelite.api.events.BeforeRender;
|
import net.runelite.api.events.BeforeRender;
|
||||||
import net.runelite.api.events.ClientTick;
|
import net.runelite.api.events.ClientTick;
|
||||||
@@ -80,6 +81,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
private static final Color SNAP_CORNER_ACTIVE_COLOR = new Color(0, 255, 0, 100);
|
private static final Color SNAP_CORNER_ACTIVE_COLOR = new Color(0, 255, 0, 100);
|
||||||
private static final Color MOVING_OVERLAY_COLOR = new Color(255, 255, 0, 100);
|
private static final Color MOVING_OVERLAY_COLOR = new Color(255, 255, 0, 100);
|
||||||
private static final Color MOVING_OVERLAY_ACTIVE_COLOR = new Color(255, 255, 0, 200);
|
private static final Color MOVING_OVERLAY_ACTIVE_COLOR = new Color(255, 255, 0, 200);
|
||||||
|
private static final Color MOVING_OVERLAY_TARGET_COLOR = Color.RED;
|
||||||
private static final Color MOVING_OVERLAY_RESIZING_COLOR = new Color(255, 0, 255, 200);
|
private static final Color MOVING_OVERLAY_RESIZING_COLOR = new Color(255, 0, 255, 200);
|
||||||
private final Client client;
|
private final Client client;
|
||||||
private final OverlayManager overlayManager;
|
private final OverlayManager overlayManager;
|
||||||
@@ -90,11 +92,11 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
private final Point overlayOffset = new Point();
|
private final Point overlayOffset = new Point();
|
||||||
private final Point mousePosition = new Point();
|
private final Point mousePosition = new Point();
|
||||||
private Overlay currentManagedOverlay;
|
private Overlay currentManagedOverlay;
|
||||||
|
private Overlay dragTargetOverlay;
|
||||||
private Rectangle currentManagedBounds;
|
private Rectangle currentManagedBounds;
|
||||||
private boolean inOverlayManagingMode;
|
private boolean inOverlayManagingMode;
|
||||||
private boolean inOverlayResizingMode;
|
private boolean inOverlayResizingMode;
|
||||||
private boolean inOverlayDraggingMode;
|
private boolean inOverlayDraggingMode;
|
||||||
private boolean inMenuEntryMode;
|
|
||||||
private boolean startedMovingOverlay;
|
private boolean startedMovingOverlay;
|
||||||
private MenuEntry[] menuEntries;
|
private MenuEntry[] menuEntries;
|
||||||
|
|
||||||
@@ -141,7 +143,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
resetOverlayManagementMode();
|
resetOverlayManagementMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
inMenuEntryMode = false;
|
|
||||||
menuEntries = null;
|
menuEntries = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +154,8 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inMenuEntryMode && runeLiteConfig.menuEntryShift())
|
final boolean shift = client.isKeyPressed(KeyCode.KC_SHIFT);
|
||||||
|
if (!shift && runeLiteConfig.menuEntryShift())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -313,15 +315,28 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
{
|
{
|
||||||
if (inOverlayManagingMode)
|
if (inOverlayManagingMode)
|
||||||
{
|
{
|
||||||
|
Color boundsColor;
|
||||||
if (inOverlayResizingMode && currentManagedOverlay == overlay)
|
if (inOverlayResizingMode && currentManagedOverlay == overlay)
|
||||||
{
|
{
|
||||||
graphics.setColor(MOVING_OVERLAY_RESIZING_COLOR);
|
boundsColor = MOVING_OVERLAY_RESIZING_COLOR;
|
||||||
|
}
|
||||||
|
else if (inOverlayDraggingMode && currentManagedOverlay == overlay)
|
||||||
|
{
|
||||||
|
boundsColor = MOVING_OVERLAY_ACTIVE_COLOR;
|
||||||
|
}
|
||||||
|
else if (inOverlayDraggingMode && overlay.isDragTargetable() && currentManagedOverlay.isDragTargetable()
|
||||||
|
&& currentManagedOverlay.getBounds().intersects(bounds))
|
||||||
|
{
|
||||||
|
boundsColor = MOVING_OVERLAY_TARGET_COLOR;
|
||||||
|
assert currentManagedOverlay != overlay;
|
||||||
|
dragTargetOverlay = overlay;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphics.setColor(inOverlayDraggingMode && currentManagedOverlay == overlay ? MOVING_OVERLAY_ACTIVE_COLOR : MOVING_OVERLAY_COLOR);
|
boundsColor = MOVING_OVERLAY_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
graphics.setColor(boundsColor);
|
||||||
graphics.draw(bounds);
|
graphics.draw(bounds);
|
||||||
graphics.setPaint(paint);
|
graphics.setPaint(paint);
|
||||||
}
|
}
|
||||||
@@ -402,6 +417,12 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
{
|
{
|
||||||
for (Overlay overlay : overlayManager.getOverlays())
|
for (Overlay overlay : overlayManager.getOverlays())
|
||||||
{
|
{
|
||||||
|
if (overlay.getPosition() == OverlayPosition.DYNAMIC || overlay.getPosition() == OverlayPosition.TOOLTIP)
|
||||||
|
{
|
||||||
|
// never allow moving dynamic or tooltip overlays
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
final Rectangle bounds = overlay.getBounds();
|
final Rectangle bounds = overlay.getBounds();
|
||||||
if (bounds.contains(mousePoint))
|
if (bounds.contains(mousePoint))
|
||||||
{
|
{
|
||||||
@@ -472,6 +493,12 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
return mouseEvent;
|
return mouseEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dragTargetOverlay != null && !currentManagedOverlay.getBounds().intersects(dragTargetOverlay.getBounds()))
|
||||||
|
{
|
||||||
|
// No longer over drag target
|
||||||
|
dragTargetOverlay = null;
|
||||||
|
}
|
||||||
|
|
||||||
final Rectangle canvasRect = new Rectangle(client.getRealDimensions());
|
final Rectangle canvasRect = new Rectangle(client.getRealDimensions());
|
||||||
|
|
||||||
if (!canvasRect.contains(p))
|
if (!canvasRect.contains(p))
|
||||||
@@ -598,7 +625,17 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
|
|
||||||
mousePosition.setLocation(-1, -1);
|
mousePosition.setLocation(-1, -1);
|
||||||
|
|
||||||
// do not snapcorner detached overlays
|
if (dragTargetOverlay != null)
|
||||||
|
{
|
||||||
|
if (dragTargetOverlay.onDrag(currentManagedOverlay))
|
||||||
|
{
|
||||||
|
mouseEvent.consume();
|
||||||
|
resetOverlayManagementMode();
|
||||||
|
return mouseEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the overlay is over a snapcorner and move it if so, unless it is a detached overlay
|
||||||
if (currentManagedOverlay.getPosition() != OverlayPosition.DETACHED && inOverlayDraggingMode)
|
if (currentManagedOverlay.getPosition() != OverlayPosition.DETACHED && inOverlayDraggingMode)
|
||||||
{
|
{
|
||||||
final OverlayBounds snapCorners = this.snapCorners.translated(-SNAP_CORNER_SIZE.width, -SNAP_CORNER_SIZE.height);
|
final OverlayBounds snapCorners = this.snapCorners.translated(-SNAP_CORNER_SIZE.width, -SNAP_CORNER_SIZE.height);
|
||||||
@@ -640,11 +677,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
{
|
{
|
||||||
inOverlayManagingMode = true;
|
inOverlayManagingMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.isShiftDown() && runeLiteConfig.menuEntryShift())
|
|
||||||
{
|
|
||||||
inMenuEntryMode = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -655,11 +687,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
inOverlayManagingMode = false;
|
inOverlayManagingMode = false;
|
||||||
resetOverlayManagementMode();
|
resetOverlayManagementMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e.isShiftDown())
|
|
||||||
{
|
|
||||||
inMenuEntryMode = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void safeRender(Client client, Overlay overlay, OverlayLayer layer, Graphics2D graphics, Point point)
|
private void safeRender(Client client, Overlay overlay, OverlayLayer layer, Graphics2D graphics, Point point)
|
||||||
@@ -750,6 +777,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
inOverlayResizingMode = false;
|
inOverlayResizingMode = false;
|
||||||
inOverlayDraggingMode = false;
|
inOverlayDraggingMode = false;
|
||||||
currentManagedOverlay = null;
|
currentManagedOverlay = null;
|
||||||
|
dragTargetOverlay = null;
|
||||||
currentManagedBounds = null;
|
currentManagedBounds = null;
|
||||||
clientUI.setCursor(clientUI.getDefaultCursor());
|
clientUI.setCursor(clientUI.getDefaultCursor());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public class InfoBoxComponent implements LayoutableRenderableEntity
|
|||||||
private Dimension preferredSize = new Dimension(DEFAULT_SIZE, DEFAULT_SIZE);
|
private Dimension preferredSize = new Dimension(DEFAULT_SIZE, DEFAULT_SIZE);
|
||||||
private String text;
|
private String text;
|
||||||
private Color color = Color.WHITE;
|
private Color color = Color.WHITE;
|
||||||
|
private boolean outline;
|
||||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||||
private BufferedImage image;
|
private BufferedImage image;
|
||||||
@Getter
|
@Getter
|
||||||
@@ -93,6 +94,7 @@ public class InfoBoxComponent implements LayoutableRenderableEntity
|
|||||||
{
|
{
|
||||||
final TextComponent textComponent = new TextComponent();
|
final TextComponent textComponent = new TextComponent();
|
||||||
textComponent.setColor(color);
|
textComponent.setColor(color);
|
||||||
|
textComponent.setOutline(outline);
|
||||||
textComponent.setText(text);
|
textComponent.setText(text);
|
||||||
textComponent.setPosition(new Point(baseX + ((size - metrics.stringWidth(text)) / 2), baseY + size - SEPARATOR));
|
textComponent.setPosition(new Point(baseX + ((size - metrics.stringWidth(text)) / 2), baseY + size - SEPARATOR));
|
||||||
textComponent.render(graphics);
|
textComponent.render(graphics);
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ public class ProgressBarComponent implements LayoutableRenderableEntity
|
|||||||
|
|
||||||
// Draw bar
|
// Draw bar
|
||||||
graphics.setColor(backgroundColor);
|
graphics.setColor(backgroundColor);
|
||||||
graphics.fillRect(barX, barY, width, height);
|
graphics.fillRect(barX + progressFill, barY, width - progressFill, height);
|
||||||
graphics.setColor(foregroundColor);
|
graphics.setColor(foregroundColor);
|
||||||
graphics.fillRect(barX, barY, progressFill, height);
|
graphics.fillRect(barX, barY, progressFill, height);
|
||||||
|
|
||||||
|
|||||||
@@ -81,4 +81,11 @@ public abstract class InfoBox
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
// Use a combination of plugin name and infobox implementation name to try and make each infobox as unique
|
||||||
|
// as possible by default
|
||||||
|
return plugin.getClass().getSimpleName() + "_" + getClass().getSimpleName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,43 +24,112 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.ui.overlay.infobox;
|
package net.runelite.client.ui.overlay.infobox;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ComparisonChain;
|
import com.google.common.collect.ComparisonChain;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.MenuOpcode;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
import net.runelite.client.eventbus.EventBus;
|
import net.runelite.client.eventbus.EventBus;
|
||||||
import net.runelite.client.events.ConfigChanged;
|
import net.runelite.client.events.ConfigChanged;
|
||||||
|
import net.runelite.client.events.InfoBoxMenuClicked;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||||
|
import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
||||||
|
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||||
import net.runelite.client.util.AsyncBufferedImage;
|
import net.runelite.client.util.AsyncBufferedImage;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class InfoBoxManager
|
public class InfoBoxManager
|
||||||
{
|
{
|
||||||
private final List<InfoBox> infoBoxes = new CopyOnWriteArrayList<>();
|
private static final String INFOBOXLAYER_KEY = "infoboxlayer";
|
||||||
|
private static final String INFOBOXOVERLAY_KEY = "infoboxoverlay";
|
||||||
|
private static final String INFOBOXOVERLAY_ORIENTATION_PREFIX = "orient_";
|
||||||
|
private static final String DEFAULT_LAYER = "InfoBoxOverlay";
|
||||||
|
|
||||||
|
private static final String DETACH = "Detach";
|
||||||
|
private static final String FLIP = "Flip";
|
||||||
|
private static final String DELETE = "Delete";
|
||||||
|
|
||||||
|
private static final OverlayMenuEntry DETACH_ME = new OverlayMenuEntry(MenuOpcode.RUNELITE_INFOBOX, DETACH, "InfoBox");
|
||||||
|
private static final OverlayMenuEntry FLIP_ME = new OverlayMenuEntry(MenuOpcode.RUNELITE_INFOBOX, FLIP, "InfoBox Group");
|
||||||
|
private static final OverlayMenuEntry DELETE_ME = new OverlayMenuEntry(MenuOpcode.RUNELITE_INFOBOX, DELETE, "InfoBox Group");
|
||||||
|
|
||||||
|
private final Map<String, InfoBoxOverlay> layers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final RuneLiteConfig runeLiteConfig;
|
private final RuneLiteConfig runeLiteConfig;
|
||||||
|
private final TooltipManager tooltipManager;
|
||||||
|
private final Client client;
|
||||||
|
private final EventBus eventBus;
|
||||||
|
private final OverlayManager overlayManager;
|
||||||
|
private final ConfigManager configManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private InfoBoxManager(final RuneLiteConfig runeLiteConfig, final EventBus eventbus)
|
private InfoBoxManager(final RuneLiteConfig runeLiteConfig,
|
||||||
|
final TooltipManager tooltipManager,
|
||||||
|
final Client client,
|
||||||
|
final EventBus eventBus,
|
||||||
|
final OverlayManager overlayManager,
|
||||||
|
final ConfigManager configManager,
|
||||||
|
final EventBus eventbus)
|
||||||
{
|
{
|
||||||
this.runeLiteConfig = runeLiteConfig;
|
this.runeLiteConfig = runeLiteConfig;
|
||||||
|
this.tooltipManager = tooltipManager;
|
||||||
|
this.client = client;
|
||||||
|
this.eventBus = eventBus;
|
||||||
|
this.overlayManager = overlayManager;
|
||||||
|
this.configManager = configManager;
|
||||||
|
|
||||||
eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||||
|
eventbus.subscribe(InfoBoxMenuClicked.class, this, this::onInfoBoxMenuClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onConfigChanged(ConfigChanged event)
|
private void onConfigChanged(ConfigChanged event)
|
||||||
{
|
{
|
||||||
if (event.getGroup().equals("runelite") && event.getKey().equals("infoBoxSize"))
|
if (event.getGroup().equals("runelite") && event.getKey().equals("infoBoxSize"))
|
||||||
{
|
{
|
||||||
infoBoxes.forEach(this::updateInfoBoxImage);
|
|
||||||
|
layers.values().forEach(l -> l.getInfoBoxes().forEach(this::updateInfoBoxImage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onInfoBoxMenuClicked(InfoBoxMenuClicked event)
|
||||||
|
{
|
||||||
|
if (DETACH.equals(event.getEntry().getOption()))
|
||||||
|
{
|
||||||
|
// The layer name doesn't matter as long as it is unique
|
||||||
|
splitInfobox(event.getInfoBox().getName() + "_" + System.currentTimeMillis(), event.getInfoBox());
|
||||||
|
}
|
||||||
|
else if (FLIP.equals(event.getEntry().getOption()))
|
||||||
|
{
|
||||||
|
InfoBoxOverlay infoBoxOverlay = layers.get(getLayer(event.getInfoBox()));
|
||||||
|
ComponentOrientation newOrientation = infoBoxOverlay.flip();
|
||||||
|
setOrientation(infoBoxOverlay.getName(), newOrientation);
|
||||||
|
}
|
||||||
|
else if (DELETE.equals(event.getEntry().getOption()))
|
||||||
|
{
|
||||||
|
// This is just a merge into the default layer
|
||||||
|
InfoBoxOverlay source = layers.get(getLayer(event.getInfoBox()));
|
||||||
|
InfoBoxOverlay dest = layers.computeIfAbsent(DEFAULT_LAYER, this::makeOverlay);
|
||||||
|
if (source != dest)
|
||||||
|
{
|
||||||
|
mergeInfoBoxes(source, dest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,14 +140,25 @@ public class InfoBoxManager
|
|||||||
|
|
||||||
updateInfoBoxImage(infoBox);
|
updateInfoBoxImage(infoBox);
|
||||||
|
|
||||||
|
String layerName = getLayer(infoBox);
|
||||||
|
InfoBoxOverlay overlay = layers.computeIfAbsent(layerName, this::makeOverlay);
|
||||||
|
List<OverlayMenuEntry> menuEntries = infoBox.getMenuEntries();
|
||||||
|
menuEntries.add(DETACH_ME);
|
||||||
|
menuEntries.add(FLIP_ME);
|
||||||
|
if (!layerName.equals(DEFAULT_LAYER))
|
||||||
|
{
|
||||||
|
// Non default-group infoboxes have a delete option to delete the group
|
||||||
|
menuEntries.add(DELETE_ME);
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
int idx = findInsertionIndex(infoBoxes, infoBox, (b1, b2) -> ComparisonChain
|
int idx = findInsertionIndex(overlay.getInfoBoxes(), infoBox, (b1, b2) -> ComparisonChain
|
||||||
.start()
|
.start()
|
||||||
.compare(b1.getPriority(), b2.getPriority())
|
.compare(b1.getPriority(), b2.getPriority())
|
||||||
.compare(b1.getPlugin().getName(), b2.getPlugin().getName())
|
.compare(b1.getPlugin().getName(), b2.getPlugin().getName())
|
||||||
.result());
|
.result());
|
||||||
infoBoxes.add(idx, infoBox);
|
overlay.getInfoBoxes().add(idx, infoBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedImage image = infoBox.getImage();
|
BufferedImage image = infoBox.getImage();
|
||||||
@@ -92,28 +172,40 @@ public class InfoBoxManager
|
|||||||
|
|
||||||
public synchronized void removeInfoBox(InfoBox infoBox)
|
public synchronized void removeInfoBox(InfoBox infoBox)
|
||||||
{
|
{
|
||||||
if (infoBoxes.remove(infoBox))
|
if (infoBox == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layers.get(getLayer(infoBox)).getInfoBoxes().remove(infoBox))
|
||||||
{
|
{
|
||||||
log.debug("Removed InfoBox {}", infoBox);
|
log.debug("Removed InfoBox {}", infoBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
infoBox.getMenuEntries().remove(DETACH_ME);
|
||||||
|
infoBox.getMenuEntries().remove(FLIP_ME);
|
||||||
|
infoBox.getMenuEntries().remove(DELETE_ME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void removeIf(Predicate<InfoBox> filter)
|
public synchronized void removeIf(Predicate<InfoBox> filter)
|
||||||
{
|
{
|
||||||
if (infoBoxes.removeIf(filter))
|
for (InfoBoxOverlay overlay : layers.values())
|
||||||
{
|
{
|
||||||
log.debug("Removed InfoBoxes for filter {}", filter);
|
if (overlay.getInfoBoxes().removeIf(filter))
|
||||||
|
{
|
||||||
|
log.debug("Removed InfoBoxes for filter {} from {}", filter, overlay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<InfoBox> getInfoBoxes()
|
public List<InfoBox> getInfoBoxes()
|
||||||
{
|
{
|
||||||
return Collections.unmodifiableList(infoBoxes);
|
return layers.values().stream().map(InfoBoxOverlay::getInfoBoxes).flatMap(Collection::stream).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void cull()
|
public synchronized void cull()
|
||||||
{
|
{
|
||||||
infoBoxes.removeIf(InfoBox::cull);
|
layers.values().forEach(l -> l.getInfoBoxes().removeIf(InfoBox::cull));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateInfoBoxImage(final InfoBox infoBox)
|
public void updateInfoBoxImage(final InfoBox infoBox)
|
||||||
@@ -152,9 +244,144 @@ public class InfoBoxManager
|
|||||||
infoBox.setScaledImage(resultImage);
|
infoBox.setScaledImage(resultImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InfoBoxOverlay makeOverlay(String name)
|
||||||
|
{
|
||||||
|
ComponentOrientation orientation = getOrientation(name);
|
||||||
|
if (orientation == null)
|
||||||
|
{
|
||||||
|
if (name.equals(DEFAULT_LAYER))
|
||||||
|
{
|
||||||
|
// Fall back to old orientation config option
|
||||||
|
orientation = runeLiteConfig.infoBoxVertical() ? ComponentOrientation.VERTICAL : ComponentOrientation.HORIZONTAL;
|
||||||
|
setOrientation(name, orientation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default infobox orientation
|
||||||
|
orientation = ComponentOrientation.HORIZONTAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoBoxOverlay infoBoxOverlay = new InfoBoxOverlay(
|
||||||
|
this,
|
||||||
|
tooltipManager,
|
||||||
|
client,
|
||||||
|
runeLiteConfig,
|
||||||
|
eventBus,
|
||||||
|
name,
|
||||||
|
orientation);
|
||||||
|
overlayManager.add(infoBoxOverlay);
|
||||||
|
|
||||||
|
return infoBoxOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeOverlay(InfoBoxOverlay overlay)
|
||||||
|
{
|
||||||
|
unsetOrientation(overlay.getName());
|
||||||
|
eventBus.unregister(overlay);
|
||||||
|
overlayManager.remove(overlay);
|
||||||
|
layers.remove(overlay.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void splitInfobox(String newLayer, InfoBox infoBox)
|
||||||
|
{
|
||||||
|
String layer = getLayer(infoBox);
|
||||||
|
InfoBoxOverlay oldOverlay = layers.get(layer);
|
||||||
|
// Find all infoboxes with the same name, as they are all within the same group and so move at once.
|
||||||
|
Collection<InfoBox> filtered = oldOverlay.getInfoBoxes().stream()
|
||||||
|
.filter(i -> i.getName().equals(infoBox.getName())).collect(Collectors.toList());
|
||||||
|
|
||||||
|
oldOverlay.getInfoBoxes().removeAll(filtered);
|
||||||
|
if (oldOverlay.getInfoBoxes().isEmpty())
|
||||||
|
{
|
||||||
|
log.debug("Deleted layer: {}", oldOverlay.getName());
|
||||||
|
removeOverlay(oldOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoBoxOverlay newOverlay = layers.computeIfAbsent(newLayer, this::makeOverlay);
|
||||||
|
newOverlay.getInfoBoxes().addAll(filtered);
|
||||||
|
|
||||||
|
// Adjust config for new infoboxes
|
||||||
|
for (InfoBox i : filtered)
|
||||||
|
{
|
||||||
|
setLayer(i, newLayer);
|
||||||
|
|
||||||
|
if (!i.getMenuEntries().contains(DELETE_ME))
|
||||||
|
{
|
||||||
|
i.getMenuEntries().add(DELETE_ME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Moving infobox named {} (layer {}) to layer {}: {} boxes", infoBox.getName(), layer, newLayer, filtered.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void mergeInfoBoxes(InfoBoxOverlay source, InfoBoxOverlay dest)
|
||||||
|
{
|
||||||
|
Collection<InfoBox> infoBoxesToMove = source.getInfoBoxes();
|
||||||
|
boolean isDefault = dest.getName().equals(DEFAULT_LAYER);
|
||||||
|
|
||||||
|
log.debug("Merging InfoBoxes from {} into {} ({} boxes)", source.getName(), dest.getName(), infoBoxesToMove.size());
|
||||||
|
|
||||||
|
for (InfoBox infoBox : infoBoxesToMove)
|
||||||
|
{
|
||||||
|
setLayer(infoBox, dest.getName());
|
||||||
|
|
||||||
|
if (isDefault)
|
||||||
|
{
|
||||||
|
infoBox.getMenuEntries().remove(DELETE_ME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.getInfoBoxes().addAll(infoBoxesToMove);
|
||||||
|
source.getInfoBoxes().clear();
|
||||||
|
|
||||||
|
// remove source
|
||||||
|
removeOverlay(source);
|
||||||
|
log.debug("Deleted layer: {}", source.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLayer(InfoBox infoBox)
|
||||||
|
{
|
||||||
|
String name = configManager.getConfiguration(INFOBOXLAYER_KEY, infoBox.getName());
|
||||||
|
if (Strings.isNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
return DEFAULT_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLayer(InfoBox infoBox, String layer)
|
||||||
|
{
|
||||||
|
if (layer.equals(DEFAULT_LAYER))
|
||||||
|
{
|
||||||
|
configManager.unsetConfiguration(INFOBOXLAYER_KEY, infoBox.getName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configManager.setConfiguration(INFOBOXLAYER_KEY, infoBox.getName(), layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentOrientation getOrientation(String name)
|
||||||
|
{
|
||||||
|
return configManager.getConfiguration(INFOBOXOVERLAY_KEY, INFOBOXOVERLAY_ORIENTATION_PREFIX + name, ComponentOrientation.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOrientation(String name, ComponentOrientation orientation)
|
||||||
|
{
|
||||||
|
configManager.setConfiguration(INFOBOXOVERLAY_KEY, INFOBOXOVERLAY_ORIENTATION_PREFIX + name, orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unsetOrientation(String name)
|
||||||
|
{
|
||||||
|
configManager.unsetConfiguration(INFOBOXOVERLAY_KEY, INFOBOXOVERLAY_ORIENTATION_PREFIX + name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find insertion point for the given key into the given sorted list. If key already exists in the list,
|
* Find insertion point for the given key into the given sorted list. If key already exists in the list,
|
||||||
* return the index after the last occurrence.
|
* return the index after the last occurrence.
|
||||||
|
*
|
||||||
* @param list
|
* @param list
|
||||||
* @param key
|
* @param key
|
||||||
* @param c
|
* @param c
|
||||||
|
|||||||
@@ -33,14 +33,17 @@ import java.awt.Point;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.inject.Inject;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.MenuOpcode;
|
import net.runelite.api.MenuOpcode;
|
||||||
import net.runelite.api.events.MenuOptionClicked;
|
import net.runelite.api.events.MenuOptionClicked;
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
import net.runelite.client.eventbus.EventBus;
|
import net.runelite.client.eventbus.EventBus;
|
||||||
import net.runelite.client.events.InfoBoxMenuClicked;
|
import net.runelite.client.events.InfoBoxMenuClicked;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||||
import net.runelite.client.ui.overlay.OverlayPanel;
|
import net.runelite.client.ui.overlay.OverlayPanel;
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
@@ -61,24 +64,33 @@ public class InfoBoxOverlay extends OverlayPanel
|
|||||||
private final Client client;
|
private final Client client;
|
||||||
private final RuneLiteConfig config;
|
private final RuneLiteConfig config;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
private final String name;
|
||||||
|
private ComponentOrientation orientation;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final List<InfoBox> infoBoxes = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
private InfoBoxComponent hoveredComponent;
|
private InfoBoxComponent hoveredComponent;
|
||||||
|
|
||||||
@Inject
|
InfoBoxOverlay(
|
||||||
private InfoBoxOverlay(
|
|
||||||
InfoBoxManager infoboxManager,
|
InfoBoxManager infoboxManager,
|
||||||
TooltipManager tooltipManager,
|
TooltipManager tooltipManager,
|
||||||
Client client,
|
Client client,
|
||||||
RuneLiteConfig config,
|
RuneLiteConfig config,
|
||||||
EventBus eventBus)
|
EventBus eventBus,
|
||||||
|
String name,
|
||||||
|
@NonNull ComponentOrientation orientation)
|
||||||
{
|
{
|
||||||
this.tooltipManager = tooltipManager;
|
this.tooltipManager = tooltipManager;
|
||||||
this.infoboxManager = infoboxManager;
|
this.infoboxManager = infoboxManager;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
|
this.name = name;
|
||||||
|
this.orientation = orientation;
|
||||||
setPosition(OverlayPosition.TOP_LEFT);
|
setPosition(OverlayPosition.TOP_LEFT);
|
||||||
setClearChildren(false);
|
setClearChildren(false);
|
||||||
|
setDragTargetable(true);
|
||||||
|
|
||||||
panelComponent.setWrap(true);
|
panelComponent.setWrap(true);
|
||||||
panelComponent.setBackgroundColor(null);
|
panelComponent.setBackgroundColor(null);
|
||||||
@@ -88,11 +100,15 @@ public class InfoBoxOverlay extends OverlayPanel
|
|||||||
eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked);
|
eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
final List<InfoBox> infoBoxes = infoboxManager.getInfoBoxes();
|
|
||||||
|
|
||||||
final boolean menuOpen = client.isMenuOpen();
|
final boolean menuOpen = client.isMenuOpen();
|
||||||
if (!menuOpen)
|
if (!menuOpen)
|
||||||
{
|
{
|
||||||
@@ -107,9 +123,7 @@ public class InfoBoxOverlay extends OverlayPanel
|
|||||||
// Set preferred size to the size of DEFAULT_WRAP_COUNT infoboxes, including the padding - which is applied
|
// Set preferred size to the size of DEFAULT_WRAP_COUNT infoboxes, including the padding - which is applied
|
||||||
// to the last infobox prior to wrapping too.
|
// to the last infobox prior to wrapping too.
|
||||||
panelComponent.setPreferredSize(new Dimension(DEFAULT_WRAP_COUNT * (config.infoBoxSize() + GAP), DEFAULT_WRAP_COUNT * (config.infoBoxSize() + GAP)));
|
panelComponent.setPreferredSize(new Dimension(DEFAULT_WRAP_COUNT * (config.infoBoxSize() + GAP), DEFAULT_WRAP_COUNT * (config.infoBoxSize() + GAP)));
|
||||||
panelComponent.setOrientation(config.infoBoxVertical()
|
panelComponent.setOrientation(orientation);
|
||||||
? ComponentOrientation.VERTICAL
|
|
||||||
: ComponentOrientation.HORIZONTAL);
|
|
||||||
|
|
||||||
for (InfoBox box : infoBoxes)
|
for (InfoBox box : infoBoxes)
|
||||||
{
|
{
|
||||||
@@ -127,6 +141,7 @@ public class InfoBoxOverlay extends OverlayPanel
|
|||||||
{
|
{
|
||||||
infoBoxComponent.setColor(color);
|
infoBoxComponent.setColor(color);
|
||||||
}
|
}
|
||||||
|
infoBoxComponent.setOutline(config.infoBoxTextOutline());
|
||||||
infoBoxComponent.setImage(box.getScaledImage());
|
infoBoxComponent.setImage(box.getScaledImage());
|
||||||
infoBoxComponent.setTooltip(box.getTooltip());
|
infoBoxComponent.setTooltip(box.getTooltip());
|
||||||
infoBoxComponent.setPreferredSize(new Dimension(config.infoBoxSize(), config.infoBoxSize()));
|
infoBoxComponent.setPreferredSize(new Dimension(config.infoBoxSize(), config.infoBoxSize()));
|
||||||
@@ -177,7 +192,7 @@ public class InfoBoxOverlay extends OverlayPanel
|
|||||||
|
|
||||||
public void onMenuOptionClicked(MenuOptionClicked menuOptionClicked)
|
public void onMenuOptionClicked(MenuOptionClicked menuOptionClicked)
|
||||||
{
|
{
|
||||||
if (menuOptionClicked.getMenuOpcode() != MenuOpcode.RUNELITE_INFOBOX)
|
if (menuOptionClicked.getMenuOpcode() != MenuOpcode.RUNELITE_INFOBOX || hoveredComponent == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -187,4 +202,21 @@ public class InfoBoxOverlay extends OverlayPanel
|
|||||||
.filter(me -> me.getOption().equals(menuOptionClicked.getOption()))
|
.filter(me -> me.getOption().equals(menuOptionClicked.getOption()))
|
||||||
.findAny().ifPresent(overlayMenuEntry -> eventBus.post(InfoBoxMenuClicked.class, new InfoBoxMenuClicked(overlayMenuEntry, infoBox)));
|
.findAny().ifPresent(overlayMenuEntry -> eventBus.post(InfoBoxMenuClicked.class, new InfoBoxMenuClicked(overlayMenuEntry, infoBox)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onDrag(Overlay source)
|
||||||
|
{
|
||||||
|
if (!(source instanceof InfoBoxOverlay))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoboxManager.mergeInfoBoxes((InfoBoxOverlay) source, this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentOrientation flip()
|
||||||
|
{
|
||||||
|
return orientation = orientation == ComponentOrientation.HORIZONTAL ? ComponentOrientation.VERTICAL : ComponentOrientation.HORIZONTAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 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.ui;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ContainableFrameTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void testJdk8231564()
|
||||||
|
{
|
||||||
|
assertTrue(ContainableFrame.jdk8231564("11.0.8"));
|
||||||
|
assertFalse(ContainableFrame.jdk8231564("11.0.7"));
|
||||||
|
assertFalse(ContainableFrame.jdk8231564("1.8.0_261"));
|
||||||
|
assertFalse(ContainableFrame.jdk8231564("12.0.0"));
|
||||||
|
assertFalse(ContainableFrame.jdk8231564("13.0.0"));
|
||||||
|
assertFalse(ContainableFrame.jdk8231564("14.0.0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,8 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.config.OpenOSRSConfig;
|
import net.runelite.client.config.OpenOSRSConfig;
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
@@ -58,6 +60,14 @@ public class InfoBoxManagerTest
|
|||||||
@Bind
|
@Bind
|
||||||
private OpenOSRSConfig openOSRSConfig;
|
private OpenOSRSConfig openOSRSConfig;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private ConfigManager configManager;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private Client client;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before()
|
public void before()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import java.awt.Color;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class ColorUtilTest
|
public class ColorUtilTest
|
||||||
@@ -97,26 +95,4 @@ public class ColorUtilTest
|
|||||||
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
||||||
assertEquals(hex, ColorUtil.colorToHexCode(color)));
|
assertEquals(hex, ColorUtil.colorToHexCode(color)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isFullyTransparent()
|
|
||||||
{
|
|
||||||
for (Color color : COLOR_HEXSTRING_MAP.keySet())
|
|
||||||
{
|
|
||||||
assertFalse(ColorUtil.isFullyTransparent(color));
|
|
||||||
}
|
|
||||||
assertTrue(ColorUtil.isFullyTransparent(new Color(0, 0, 0, 0)));
|
|
||||||
assertFalse(ColorUtil.isFullyTransparent(new Color(0, 0, 0, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isNotFullyTransparent()
|
|
||||||
{
|
|
||||||
for (Color color : COLOR_HEXSTRING_MAP.keySet())
|
|
||||||
{
|
|
||||||
assertTrue(ColorUtil.isNotFullyTransparent(color));
|
|
||||||
}
|
|
||||||
assertFalse(ColorUtil.isNotFullyTransparent(new Color(0, 0, 0, 0)));
|
|
||||||
assertTrue(ColorUtil.isNotFullyTransparent(new Color(0, 0, 0, 1)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import java.awt.image.BufferedImage;
|
|||||||
import java.awt.image.DataBuffer;
|
import java.awt.image.DataBuffer;
|
||||||
import java.awt.image.DataBufferInt;
|
import java.awt.image.DataBufferInt;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.function.Predicate;
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -256,11 +255,6 @@ public class ImageUtilTest
|
|||||||
assertTrue(bufferedImagesEqual(centeredPixel(GRAY), ImageUtil.fillImage(centeredPixel(BLACK), GRAY)));
|
assertTrue(bufferedImagesEqual(centeredPixel(GRAY), ImageUtil.fillImage(centeredPixel(BLACK), GRAY)));
|
||||||
assertTrue(bufferedImagesEqual(solidColor(3, 3, GREEN), ImageUtil.fillImage(solidColor(3, 3, BLACK), GREEN)));
|
assertTrue(bufferedImagesEqual(solidColor(3, 3, GREEN), ImageUtil.fillImage(solidColor(3, 3, BLACK), GREEN)));
|
||||||
assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.fillImage(oneByOne(BLACK_TRANSPARENT), WHITE)));
|
assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.fillImage(oneByOne(BLACK_TRANSPARENT), WHITE)));
|
||||||
|
|
||||||
// fillImage(BufferedImage image, Color color, Predicate<Color> fillCondition)
|
|
||||||
BufferedImage expected = solidColor(CORNER_SIZE, CORNER_SIZE, WHITE);
|
|
||||||
expected.setRGB(0, 0, new Color(0, true).getRGB());
|
|
||||||
assertTrue(bufferedImagesEqual(expected, ImageUtil.fillImage(BLACK_PIXEL_TOP_LEFT, WHITE, ColorUtil::isFullyTransparent)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -287,39 +281,11 @@ public class ImageUtilTest
|
|||||||
expected.setRGB(1, 1, new Color(0, true).getRGB());
|
expected.setRGB(1, 1, new Color(0, true).getRGB());
|
||||||
assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE)));
|
assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE)));
|
||||||
|
|
||||||
// outlineImage(BufferedImage image, Color color, Predicate<Color> fillCondition)
|
|
||||||
BufferedImage test = new BufferedImage(CORNER_SIZE, CORNER_SIZE, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
test.setRGB(0, 0, BLACK.getRGB());
|
|
||||||
test.setRGB(1, 0, GRAY.getRGB());
|
|
||||||
expected = test;
|
|
||||||
expected.setRGB(0, 1, BLUE.getRGB());
|
|
||||||
assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(test, BLUE, (color -> color.equals(BLACK)))));
|
|
||||||
|
|
||||||
// outlineImage(BufferedImage image, Color color, Boolean outlineCorners)
|
// outlineImage(BufferedImage image, Color color, Boolean outlineCorners)
|
||||||
expected = solidColor(CORNER_SIZE, CORNER_SIZE, WHITE);
|
expected = solidColor(CORNER_SIZE, CORNER_SIZE, WHITE);
|
||||||
expected.setRGB(0, 0, BLACK.getRGB());
|
expected.setRGB(0, 0, BLACK.getRGB());
|
||||||
assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE, true)));
|
assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE, true)));
|
||||||
assertTrue(bufferedImagesEqual(solidColor(3, 3, BLACK), ImageUtil.outlineImage(centeredPixel(BLACK), BLACK, true)));
|
assertTrue(bufferedImagesEqual(solidColor(3, 3, BLACK), ImageUtil.outlineImage(centeredPixel(BLACK), BLACK, true)));
|
||||||
|
|
||||||
// outlineImage(BufferedImage image, Color color, Predicate<Color> fillCondition, Boolean outlineCorners)
|
|
||||||
test = new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
test.setRGB(2, 2, BLACK.getRGB());
|
|
||||||
test.setRGB(1, 2, new Color(50, 50, 50).getRGB());
|
|
||||||
test.setRGB(3, 2, new Color(100, 100, 100).getRGB());
|
|
||||||
test.setRGB(2, 3, new Color(150, 150, 150).getRGB());
|
|
||||||
expected = test;
|
|
||||||
expected.setRGB(2, 1, RED.getRGB());
|
|
||||||
expected.setRGB(3, 1, RED.getRGB());
|
|
||||||
expected.setRGB(4, 1, RED.getRGB());
|
|
||||||
expected.setRGB(4, 2, RED.getRGB());
|
|
||||||
expected.setRGB(1, 3, RED.getRGB());
|
|
||||||
expected.setRGB(3, 3, RED.getRGB());
|
|
||||||
expected.setRGB(4, 3, RED.getRGB());
|
|
||||||
expected.setRGB(1, 4, RED.getRGB());
|
|
||||||
expected.setRGB(2, 4, RED.getRGB());
|
|
||||||
expected.setRGB(3, 4, RED.getRGB());
|
|
||||||
Predicate<Color> testPredicate = (color -> ColorUtil.isNotFullyTransparent(color) && color.getRed() > 75 && color.getGreen() > 75 && color.getBlue() > 75);
|
|
||||||
assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(test, RED, testPredicate, true)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user