Merge branch 'master' of https://github.com/runelite/runelite into upstream
Conflicts: runelite-api/src/main/java/net/runelite/api/Point.java runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithSlot.java runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java runelite-client/src/test/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPluginTest.java runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java
This commit is contained in:
@@ -44,7 +44,6 @@ import net.runelite.client.ui.overlay.components.TooltipComponent;
|
||||
public class TooltipOverlay extends Overlay
|
||||
{
|
||||
private static final int UNDER_OFFSET = 24;
|
||||
private static final int ABOVE_OFFSET = -20;
|
||||
private static final int PADDING = 2;
|
||||
private final TooltipManager tooltipManager;
|
||||
private final Client client;
|
||||
@@ -84,50 +83,28 @@ public class TooltipOverlay extends Overlay
|
||||
|
||||
private Dimension renderTooltips(Graphics2D graphics, List<Tooltip> tooltips)
|
||||
{
|
||||
final Rectangle clientCanvasBounds = new Rectangle(client.getRealDimensions());
|
||||
final int canvasWidth = client.getCanvasWidth();
|
||||
final int canvasHeight = client.getCanvasHeight();
|
||||
final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
|
||||
final int offset = runeLiteConfig.tooltipPosition() == TooltipPositionType.UNDER_CURSOR ? UNDER_OFFSET : ABOVE_OFFSET;
|
||||
final Point mousePosition = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + offset);
|
||||
final Rectangle bounds = new Rectangle(getBounds());
|
||||
bounds.setLocation(mousePosition);
|
||||
final Rectangle prevBounds = getBounds();
|
||||
|
||||
if (!clientCanvasBounds.contains(bounds))
|
||||
{
|
||||
final int clientX = (int) clientCanvasBounds.getMaxX();
|
||||
final int clientY = (int) clientCanvasBounds.getMaxY();
|
||||
final int boundsX = (int) bounds.getMaxX();
|
||||
final int boundsY = (int) bounds.getMaxY();
|
||||
final int tooltipX = Math.min(canvasWidth - prevBounds.width, mouseCanvasPosition.getX());
|
||||
final int tooltipY = runeLiteConfig.tooltipPosition() == TooltipPositionType.ABOVE_CURSOR
|
||||
? Math.max(0, mouseCanvasPosition.getY() - prevBounds.height)
|
||||
: Math.min(canvasHeight - prevBounds.height, mouseCanvasPosition.getY() + UNDER_OFFSET);
|
||||
|
||||
if (boundsY > clientY)
|
||||
{
|
||||
graphics.translate(0, -bounds.height - offset);
|
||||
}
|
||||
|
||||
if (boundsX > clientX)
|
||||
{
|
||||
graphics.translate(-bounds.width + clientCanvasBounds.width - bounds.x, 0);
|
||||
}
|
||||
}
|
||||
|
||||
final Rectangle newBounds = new Rectangle(-1, -1, 0, 0);
|
||||
final Rectangle newBounds = new Rectangle(tooltipX, tooltipY, 0, 0);
|
||||
|
||||
for (Tooltip tooltip : tooltips)
|
||||
{
|
||||
final TooltipComponent tooltipComponent = new TooltipComponent();
|
||||
tooltipComponent.setModIcons(client.getModIcons());
|
||||
tooltipComponent.setText(tooltip.getText());
|
||||
tooltipComponent.setPosition(new Point(tooltipX, tooltipY + newBounds.height));
|
||||
|
||||
if (newBounds.contains(mousePosition))
|
||||
{
|
||||
mousePosition.move(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + offset + newBounds.height);
|
||||
}
|
||||
|
||||
tooltipComponent.setPosition(mousePosition);
|
||||
final Dimension dimension = tooltipComponent.render(graphics);
|
||||
|
||||
// Create incremental tooltip newBounds
|
||||
newBounds.x = newBounds.x != -1 ? Math.min(newBounds.x, mousePosition.x) : mousePosition.x;
|
||||
newBounds.y = newBounds.y != -1 ? Math.min(newBounds.y, mousePosition.y) : mousePosition.y;
|
||||
newBounds.height += dimension.height + PADDING;
|
||||
newBounds.width = Math.max(newBounds.width, dimension.width);
|
||||
}
|
||||
|
||||
@@ -1401,11 +1401,13 @@
|
||||
],
|
||||
"coal bag": [
|
||||
764,
|
||||
12019
|
||||
12019,
|
||||
24480
|
||||
],
|
||||
"gem bag": [
|
||||
766,
|
||||
12020
|
||||
12020,
|
||||
24481
|
||||
],
|
||||
"phoenix crossbow": [
|
||||
767,
|
||||
@@ -7609,6 +7611,10 @@
|
||||
11736,
|
||||
11737
|
||||
],
|
||||
"herb box": [
|
||||
11738,
|
||||
11739
|
||||
],
|
||||
"armadyl crossbow": [
|
||||
11785,
|
||||
23611
|
||||
@@ -7815,6 +7821,10 @@
|
||||
11912,
|
||||
11914
|
||||
],
|
||||
"slice of birthday cake": [
|
||||
11916,
|
||||
11917
|
||||
],
|
||||
"dragon pickaxe": [
|
||||
11920,
|
||||
12797,
|
||||
@@ -8271,6 +8281,10 @@
|
||||
13222,
|
||||
13224
|
||||
],
|
||||
"herb sack": [
|
||||
13226,
|
||||
24478
|
||||
],
|
||||
"eternal boots": [
|
||||
13235,
|
||||
23644
|
||||
@@ -8539,6 +8553,10 @@
|
||||
13576,
|
||||
20785
|
||||
],
|
||||
"seed box": [
|
||||
13639,
|
||||
24482
|
||||
],
|
||||
"farmers boro trousers": [
|
||||
13640,
|
||||
13641
|
||||
@@ -9692,9 +9710,5 @@
|
||||
24469,
|
||||
24472,
|
||||
24475
|
||||
],
|
||||
"cat ears": [
|
||||
24522,
|
||||
24525
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
15660E39A740C416BFD71621A448A96FA6B5C5E8AD212179F3D6785AE35CAA38
|
||||
A9BA4723E7D91AD151C1AB3ABEAF84971BFFD71AA8C23E763ECCC8981A8A1429
|
||||
@@ -47,7 +47,7 @@ LABEL23:
|
||||
get_varbit 8119
|
||||
iconst 1
|
||||
if_icmpeq LABEL42
|
||||
jump LABEL144
|
||||
jump LABEL146
|
||||
LABEL42:
|
||||
iconst 105
|
||||
iconst 115
|
||||
@@ -96,11 +96,13 @@ LABEL77:
|
||||
iload 4
|
||||
iconst 1
|
||||
if_icmpeq LABEL86
|
||||
jump LABEL101
|
||||
jump LABEL103
|
||||
LABEL86:
|
||||
iconst 60
|
||||
iconst 5
|
||||
iload 3
|
||||
add
|
||||
invoke 1045
|
||||
iconst 30
|
||||
iconst 0
|
||||
iconst 0
|
||||
@@ -112,8 +114,8 @@ LABEL86:
|
||||
iconst 2
|
||||
iconst 10616871
|
||||
if_setposition
|
||||
jump LABEL113
|
||||
LABEL101:
|
||||
jump LABEL115
|
||||
LABEL103:
|
||||
iconst 0
|
||||
iconst 30
|
||||
iconst 0
|
||||
@@ -126,26 +128,26 @@ LABEL101:
|
||||
iconst 2
|
||||
iconst 10616871
|
||||
if_setposition
|
||||
LABEL113:
|
||||
LABEL115:
|
||||
iload 3
|
||||
iconst 10616889
|
||||
if_getwidth
|
||||
if_icmpgt LABEL118
|
||||
jump LABEL124
|
||||
LABEL118:
|
||||
if_icmpgt LABEL120
|
||||
jump LABEL126
|
||||
LABEL120:
|
||||
iconst 2
|
||||
iconst 2
|
||||
iconst 0
|
||||
iconst 10616889
|
||||
if_settextalign
|
||||
jump LABEL129
|
||||
LABEL124:
|
||||
jump LABEL131
|
||||
LABEL126:
|
||||
iconst 0
|
||||
iconst 2
|
||||
iconst 0
|
||||
iconst 10616889
|
||||
if_settextalign
|
||||
LABEL129:
|
||||
LABEL131:
|
||||
iconst 10616889
|
||||
if_clearops
|
||||
iconst -1
|
||||
@@ -160,8 +162,8 @@ LABEL129:
|
||||
sconst ""
|
||||
iconst 10616889
|
||||
if_setonop
|
||||
jump LABEL185
|
||||
LABEL144:
|
||||
jump LABEL187
|
||||
LABEL146:
|
||||
iconst 105
|
||||
iconst 115
|
||||
iconst 1894
|
||||
@@ -203,7 +205,7 @@ LABEL144:
|
||||
sconst "ii"
|
||||
iconst 10616889
|
||||
if_setonop
|
||||
LABEL185:
|
||||
LABEL187:
|
||||
sload 2
|
||||
iconst 10616889
|
||||
if_settext
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Jordan <nightfirecat@protonmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.itemstats;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.awt.Color;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.item.ItemEquipmentStats;
|
||||
import net.runelite.http.api.item.ItemStats;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ItemStatOverlayTest
|
||||
{
|
||||
// Weapon definitions
|
||||
private static final ItemStats ABYSSAL_DAGGER = new ItemStats(false, true, 0.453, 8,
|
||||
ItemEquipmentStats.builder()
|
||||
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||
.astab(75)
|
||||
.aslash(40)
|
||||
.acrush(-4)
|
||||
.amagic(1)
|
||||
.dmagic(1)
|
||||
.str(75)
|
||||
.aspeed(4)
|
||||
.build());
|
||||
private static final ItemStats KATANA = new ItemStats(false, true, 0, 8,
|
||||
ItemEquipmentStats.builder()
|
||||
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||
.astab(7)
|
||||
.aslash(45)
|
||||
.dstab(3)
|
||||
.dslash(7)
|
||||
.dcrush(7)
|
||||
.drange(-3)
|
||||
.str(40)
|
||||
.aspeed(4)
|
||||
.build());
|
||||
private static final ItemStats BLOWPIPE = new ItemStats(false, true, 0, 0,
|
||||
ItemEquipmentStats.builder()
|
||||
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||
.arange(60)
|
||||
.rstr(40)
|
||||
.aspeed(3)
|
||||
.build());
|
||||
private static final ItemStats HEAVY_BALLISTA = new ItemStats(false, true, 4, 8,
|
||||
ItemEquipmentStats.builder()
|
||||
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||
.arange(110)
|
||||
.aspeed(7)
|
||||
.build());
|
||||
|
||||
@Inject
|
||||
ItemStatOverlay overlay;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ItemStatConfig config;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ItemManager itemManager;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
when(config.colorBetterUncapped()).thenReturn(new Color(0));
|
||||
when(config.colorWorse()).thenReturn(new Color(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnarmedAttackSpeed()
|
||||
{
|
||||
assertEquals(ItemStatOverlay.UNARMED.getEquipment().getAspeed(), ABYSSAL_DAGGER.getEquipment().getAspeed());
|
||||
assertEquals(ItemStatOverlay.UNARMED.getEquipment().getAspeed(), KATANA.getEquipment().getAspeed());
|
||||
assertEquals(-1, BLOWPIPE.getEquipment().getAspeed() - ItemStatOverlay.UNARMED.getEquipment().getAspeed());
|
||||
assertEquals(3, HEAVY_BALLISTA.getEquipment().getAspeed() - ItemStatOverlay.UNARMED.getEquipment().getAspeed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildStatBonusString()
|
||||
{
|
||||
// Empty equipment (fully unarmed)
|
||||
final ItemContainer equipment = mock(ItemContainer.class);
|
||||
when(equipment.getItems()).thenReturn(new Item[0]);
|
||||
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipment);
|
||||
|
||||
String tooltip;
|
||||
String sanitizedTooltip;
|
||||
|
||||
tooltip = overlay.buildStatBonusString(ABYSSAL_DAGGER);
|
||||
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||
assertTrue(sanitizedTooltip.contains("Stab: +75"));
|
||||
assertTrue(sanitizedTooltip.contains("Slash: +40"));
|
||||
assertTrue(sanitizedTooltip.contains("Crush: -4"));
|
||||
assertEquals(2, StringUtils.countMatches(sanitizedTooltip, "Magic: +1")); // Attack and defense
|
||||
assertTrue(sanitizedTooltip.contains("Melee Str: +75"));
|
||||
assertFalse(sanitizedTooltip.contains("Speed:"));
|
||||
|
||||
tooltip = overlay.buildStatBonusString(KATANA);
|
||||
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||
assertTrue(sanitizedTooltip.contains("Stab: +7"));
|
||||
assertTrue(sanitizedTooltip.contains("Slash: +45"));
|
||||
assertTrue(sanitizedTooltip.contains("Stab: +3")); // Defense
|
||||
assertTrue(sanitizedTooltip.contains("Slash: +7")); // Defense
|
||||
assertTrue(sanitizedTooltip.contains("Crush: +7")); // Defense
|
||||
assertTrue(sanitizedTooltip.contains("Range: -3")); // Defense
|
||||
assertTrue(sanitizedTooltip.contains("Melee Str: +40"));
|
||||
assertFalse(sanitizedTooltip.contains("Speed:"));
|
||||
|
||||
tooltip = overlay.buildStatBonusString(BLOWPIPE);
|
||||
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||
assertTrue(sanitizedTooltip.contains("Range: +60"));
|
||||
assertTrue(sanitizedTooltip.contains("Range Str: +40"));
|
||||
assertTrue(sanitizedTooltip.contains("Speed: -1"));
|
||||
assertFalse(sanitizedTooltip.contains("Stab:"));
|
||||
|
||||
tooltip = overlay.buildStatBonusString(HEAVY_BALLISTA);
|
||||
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||
assertTrue(sanitizedTooltip.contains("Range: +110"));
|
||||
assertTrue(sanitizedTooltip.contains("Speed: +3"));
|
||||
assertFalse(sanitizedTooltip.contains("Stab:"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user