Merge branch 'master' into loot-tracker-reset

This commit is contained in:
PKLite
2019-06-28 02:35:03 -04:00
432 changed files with 10378 additions and 14155 deletions

View File

@@ -45,7 +45,6 @@ import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.MainBufferProvider;
import net.runelite.api.NullItemID;
import net.runelite.api.Point;
import net.runelite.api.RenderOverview;
import net.runelite.api.Renderable;
import net.runelite.api.WorldMapManager;
@@ -375,9 +374,6 @@ public class Hooks implements Callbacks
/**
* Copy an image
*
* @param src
* @return
*/
private static Image copy(Image src)
{
@@ -397,18 +393,6 @@ public class Hooks implements Callbacks
BufferedImage image = (BufferedImage) bufferProvider.getImage();
Graphics2D graphics2d = image.createGraphics();
// Update selected scene tile
if (!client.isMenuOpen())
{
Point p = client.getMouseCanvasPosition();
p = new Point(
p.getX() - client.getViewportXOffset(),
p.getY() - client.getViewportYOffset());
client.setCheckClick(true);
client.setMouseCanvasHoverPosition(p);
}
try
{
renderer.render(graphics2d, OverlayLayer.ABOVE_SCENE);

View File

@@ -51,16 +51,24 @@ public @interface ConfigItem
String unhide() default "";
String unhideValue() default "";
String hide() default "";
String hideValue() default "";
String parent() default "";
String enabledBy() default "";
String enabledByValue() default "";
String disabledBy() default "";
String disabledByValue() default "";
boolean parse() default false;
Class<?> clazz() default void.class;
String method() default "";
}
}

View File

@@ -432,7 +432,10 @@ public class ConfigManager
String current = getConfiguration(group.value(), item.keyName());
String valueString = objectToString(defaultValue);
if (Objects.equals(current, valueString))
// null and the empty string are treated identically in sendConfig and treated as an unset
// If a config value defaults to "" and the current value is null, it will cause an extra
// unset to be sent, so treat them as equal
if (Objects.equals(current, valueString) || (Strings.isNullOrEmpty(current) && Strings.isNullOrEmpty(valueString)))
{
continue; // already set to the default value
}

View File

@@ -325,7 +325,7 @@ public enum AgilityShortcut
TROLLHEIM_MEDIUM_CLIFF_SCRAMBLE_NORTH(43, "Rocks", new WorldPoint(2886, 3684, 0), ROCKS_3803, ROCKS_3804, ROCKS_16522),
TROLLHEIM_MEDIUM_CLIFF_SCRAMBLE_SOUTH(43, "Rocks", new WorldPoint(2876, 3666, 0), ROCKS_3803, ROCKS_3804, ROCKS_16522),
TROLLHEIM_ADVANCED_CLIFF_SCRAMBLE(44, "Rocks", new WorldPoint(2907, 3686, 0), ROCKS_16523, ROCKS_3748),
KOUREND_RIVER_STEPPING_STONES(45, "Stepping Stones", new WorldPoint(1721, 3509, 0), STEPPING_STONE_29728),
KOUREND_RIVER_STEPPING_STONES(45, "Stepping Stones", new WorldPoint(1720, 3551, 0), STEPPING_STONE_29728),
TIRANNWN_LOG_BALANCE(45, "Log Balance", null, LOG_BALANCE_3933, LOG_BALANCE_3931, LOG_BALANCE_3930, LOG_BALANCE_3929, LOG_BALANCE_3932),
COSMIC_ALTAR_MEDIUM_WALKWAY(46, "Narrow Walkway", new WorldPoint(2399, 4403, 0), JUTTING_WALL_17002),
DEEP_WILDERNESS_DUNGEON_CREVICE_NORTH(46, "Narrow Crevice", new WorldPoint(3047, 10335, 0), CREVICE_19043),

View File

@@ -59,6 +59,7 @@ public class NPCManager
/**
* Returns the {@link NPCStats} for target NPC id
*
* @param npcId NPC id
* @return the {@link NPCStats} or null if unknown
*/
@@ -70,23 +71,41 @@ public class NPCManager
/**
* Returns health for target NPC ID
*
* @param npcId NPC id
* @return health or null if unknown
*/
@Nullable
public Integer getHealth(final int npcId)
public int getHealth(final int npcId)
{
final NPCStats s = statsMap.get(npcId);
if (s == null || s.getHitpoints() == -1)
{
return null;
return -1;
}
return s.getHitpoints();
}
/**
* Returns the attack speed for target NPC ID.
*
* @param npcId NPC id
* @return attack speed in game ticks for NPC ID.
*/
public int getAttackSpeed(final int npcId)
{
final NPCStats s = statsMap.get(npcId);
if (s == null || s.getAttackSpeed() == -1)
{
return -1;
}
return s.getAttackSpeed();
}
/**
* Returns the exp modifier for target NPC ID based on its stats.
*
* @param npcId NPC id
* @return npcs exp modifier. Assumes default xp rate if npc stats are unknown (returns 1)
*/

View File

@@ -34,6 +34,7 @@ public class NPCStats
private final int hitpoints;
private final int combatLevel;
private final int slayerLevel;
private final int attackSpeed;
private final int attackLevel;
private final int strengthLevel;

View File

@@ -34,12 +34,18 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import net.runelite.api.Client;
import net.runelite.api.DecorativeObject;
import net.runelite.api.GameObject;
import net.runelite.api.GroundObject;
import net.runelite.api.ItemLayer;
import net.runelite.api.MainBufferProvider;
import net.runelite.api.Model;
import net.runelite.api.NPC;
import net.runelite.api.NPCDefinition;
import net.runelite.api.Perspective;
import net.runelite.api.Player;
import net.runelite.api.TileObject;
import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint;
import net.runelite.client.task.Schedule;
@@ -278,8 +284,7 @@ public class ModelOutlineRenderer
* @param x1 The starting x position
* @param x2 The ending x position
*/
private void simulateHorizontalLineRasterizationForOutline(
int pixelPos, int x1, int x2)
private void simulateHorizontalLineRasterizationForOutline(int pixelPos, int x1, int x2)
{
if (x2 > clipX2)
{
@@ -337,8 +342,7 @@ public class ModelOutlineRenderer
* @param x3 The starting x position of the second line
* @param x4 The ending x position of the second line
*/
private void outlineAroundHorizontalLine(
int pixelPos, int x1, int x2, int x3, int x4)
private void outlineAroundHorizontalLine(int pixelPos, int x1, int x2, int x3, int x4)
{
if (x1 < clipX1)
{
@@ -420,8 +424,7 @@ public class ModelOutlineRenderer
* @param x3 The x position of the third vertex in the triangle
* @param y3 The y position of the third vertex in the triangle
*/
private void simulateTriangleRasterizationForOutline(
int x1, int y1, int x2, int y2, int x3, int y3)
private void simulateTriangleRasterizationForOutline(int x1, int y1, int x2, int y2, int x3, int y3)
{
// Swap vertices so y1 <= y2 <= y3 using bubble sort
if (y1 > y2)
@@ -615,8 +618,7 @@ public class ModelOutlineRenderer
* @param vertexOrientation The orientation of the vertices
* @return Returns true if any of them are inside the clip area, otherwise false
*/
private boolean projectVertices(Model model,
final int localX, final int localY, final int localZ, final int vertexOrientation)
private boolean projectVertices(Model model, final int localX, final int localY, final int localZ, final int vertexOrientation)
{
final int cameraX = client.getCameraX();
final int cameraY = client.getCameraY();
@@ -742,8 +744,7 @@ public class ModelOutlineRenderer
* @param innerColor The color of the pixels of the outline closest to the model
* @param outerColor The color of the pixels of the outline furthest away from the model
*/
private void renderOutline(BufferedImage image, int outlineWidth,
Color innerColor, Color outerColor)
private void renderOutline(BufferedImage image, int outlineWidth, Color innerColor, Color outerColor)
{
int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
List<PixelDistanceAlpha> ps = getPriorityList(outlineWidth);
@@ -886,9 +887,7 @@ public class ModelOutlineRenderer
* @param innerColor The color of the pixels of the outline closest to the model
* @param outerColor The color of the pixels of the outline furthest away from the model
*/
private void drawModelOutline(Model model,
int localX, int localY, int localZ, int orientation,
int outlineWidth, Color innerColor, Color outerColor)
private void drawModelOutline(Model model, int localX, int localY, int localZ, int orientation, int outlineWidth, Color innerColor, Color outerColor)
{
if (outlineWidth <= 0)
{
@@ -930,8 +929,7 @@ public class ModelOutlineRenderer
drawOutline(npc, outlineWidth, color, color);
}
public void drawOutline(NPC npc, int outlineWidth,
Color innerColor, Color outerColor)
public void drawOutline(NPC npc, int outlineWidth, Color innerColor, Color outerColor)
{
int size = 1;
NPCDefinition composition = npc.getTransformedDefinition();
@@ -959,8 +957,7 @@ public class ModelOutlineRenderer
drawOutline(player, outlineWidth, color, color);
}
public void drawOutline(Player player, int outlineWidth,
Color innerColor, Color outerColor)
public void drawOutline(Player player, int outlineWidth, Color innerColor, Color outerColor)
{
LocalPoint lp = player.getLocalLocation();
if (lp != null)
@@ -970,4 +967,136 @@ public class ModelOutlineRenderer
player.getOrientation(), outlineWidth, innerColor, outerColor);
}
}
private void drawOutline(GameObject gameObject, int outlineWidth, Color innerColor, Color outerColor)
{
LocalPoint lp = gameObject.getLocalLocation();
if (lp != null)
{
drawModelOutline(gameObject.getModel(), lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, gameObject.getPlane()),
gameObject.getRsOrientation(), outlineWidth, innerColor, outerColor);
}
}
private void drawOutline(GroundObject groundObject, int outlineWidth, Color innerColor, Color outerColor)
{
LocalPoint lp = groundObject.getLocalLocation();
if (lp != null)
{
drawModelOutline(groundObject.getModel(), lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, client.getPlane()),
0, outlineWidth, innerColor, outerColor);
}
}
private void drawOutline(ItemLayer itemLayer, int outlineWidth, Color innerColor, Color outerColor)
{
LocalPoint lp = itemLayer.getLocalLocation();
if (lp != null)
{
Model model = itemLayer.getModelBottom();
if (model != null)
{
drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, itemLayer.getPlane()),
0, outlineWidth, innerColor, outerColor);
}
model = itemLayer.getModelMiddle();
if (model != null)
{
drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, itemLayer.getPlane()),
0, outlineWidth, innerColor, outerColor);
}
model = itemLayer.getModelTop();
if (model != null)
{
drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, itemLayer.getPlane()),
0, outlineWidth, innerColor, outerColor);
}
}
}
private void drawOutline(DecorativeObject decorativeObject, int outlineWidth, Color innerColor, Color outerColor)
{
LocalPoint lp = decorativeObject.getLocalLocation();
if (lp != null)
{
Model model = decorativeObject.getModel1();
if (model != null)
{
drawModelOutline(model,
lp.getX() + decorativeObject.getXOffset(),
lp.getY() + decorativeObject.getYOffset(),
Perspective.getTileHeight(client, lp, decorativeObject.getPlane()),
decorativeObject.getOrientation(), outlineWidth, innerColor, outerColor);
}
model = decorativeObject.getModel2();
if (model != null)
{
// Offset is not used for the second model
drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, decorativeObject.getPlane()),
decorativeObject.getOrientation(), outlineWidth, innerColor, outerColor);
}
}
}
private void drawOutline(WallObject wallObject, int outlineWidth, Color innerColor, Color outerColor)
{
LocalPoint lp = wallObject.getLocalLocation();
if (lp != null)
{
Model model = wallObject.getModelA();
if (model != null)
{
drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, wallObject.getPlane()),
wallObject.getOrientationA(), outlineWidth, innerColor, outerColor);
}
model = wallObject.getModelB();
if (model != null)
{
drawModelOutline(model, lp.getX(), lp.getY(),
Perspective.getTileHeight(client, lp, wallObject.getPlane()),
wallObject.getOrientationB(), outlineWidth, innerColor, outerColor);
}
}
}
public void drawOutline(TileObject tileObject, int outlineWidth, Color color)
{
drawOutline(tileObject, outlineWidth, color, color);
}
public void drawOutline(TileObject tileObject,
int outlineWidth, Color innerColor, Color outerColor)
{
if (tileObject instanceof GameObject)
{
drawOutline((GameObject) tileObject, outlineWidth, innerColor, outerColor);
}
else if (tileObject instanceof GroundObject)
{
drawOutline((GroundObject) tileObject, outlineWidth, innerColor, outerColor);
}
else if (tileObject instanceof ItemLayer)
{
drawOutline((ItemLayer) tileObject, outlineWidth, innerColor, outerColor);
}
else if (tileObject instanceof DecorativeObject)
{
drawOutline((DecorativeObject) tileObject, outlineWidth, innerColor, outerColor);
}
else if (tileObject instanceof WallObject)
{
drawOutline((WallObject) tileObject, outlineWidth, innerColor, outerColor);
}
}
}

View File

@@ -64,14 +64,24 @@ public class ComparableEntry
public ComparableEntry(String option, String target, int id, int type, boolean strictOption, boolean strictTarget)
{
this.option = option;
this.target = target;
this.option = Text.standardize(option);
this.target = Text.standardize(target);
this.id = id;
this.type = type;
this.strictOption = strictOption;
this.strictTarget = strictTarget;
}
// This is only used for type checking, which is why it has everything but target
// target sometimes changes to option.
public ComparableEntry(MenuEntry e)
{
this.option = Text.standardize(e.getOption());
this.id = e.getIdentifier();
this.type = e.getType();
this.strictOption = true;
}
boolean matches(MenuEntry entry)
{
String opt = Text.standardize(entry.getOption());

View File

@@ -39,6 +39,7 @@ import java.util.Set;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.MenuAction;
@@ -96,7 +97,7 @@ public class MenuManager
private final Set<ComparableEntry> hiddenEntries = new HashSet<>();
private final Map<ComparableEntry, ComparableEntry> swaps = new HashMap<>();
private final Map<MenuEntry, Integer> originalTypes = new HashMap<>();
private EntryTypeMapping originalType;
@Inject
private MenuManager(Client client, EventBus eventBus)
@@ -164,89 +165,78 @@ public class MenuManager
client.setMenuEntries(menuEntries);
}
}
final MenuEntry newestEntry = menuEntries[menuEntries.length - 1];
for (ComparableEntry p : priorityEntries)
{
if (p.matches(newestEntry))
{
currentPriorityEntries.add(newestEntry);
}
}
// Make a copy of the menu entries, cause you can't remove from Arrays.asList()
List<MenuEntry> copy = Lists.newArrayList(menuEntries);
// If there are entries we want to prioritize, we have to remove the rest
if (!currentPriorityEntries.isEmpty())
{
copy.retainAll(currentPriorityEntries);
// This is because players existing changes walk-here target
// so without this we lose track of em
if (copy.size() != currentPriorityEntries.size())
{
for (MenuEntry e : currentPriorityEntries)
{
if (copy.contains(e))
{
continue;
}
for (MenuEntry e2 : client.getMenuEntries())
{
if (e.getType() == e2.getType())
{
e.setTarget(e2.getTarget());
copy.add(e);
}
}
}
}
}
boolean isHidden = false;
for (ComparableEntry p : hiddenEntries)
{
if (p.matches(newestEntry))
{
isHidden = true;
break;
}
}
if (isHidden)
{
copy.remove(newestEntry);
}
client.setMenuEntries(copy.toArray(new MenuEntry[0]));
}
@Subscribe
private void onClientTick(ClientTick event)
{
originalTypes.clear();
originalType = null;
currentPriorityEntries.clear();
client.sortMenuEntries();
final MenuEntry[] oldentries = client.getMenuEntries();
MenuEntry[] newEntries;
MenuEntry[] oldEntries = client.getMenuEntries();
List<MenuEntry> newEntries = Lists.newArrayList(oldEntries);
if (!currentPriorityEntries.isEmpty())
for (MenuEntry entry : oldEntries)
{
newEntries = new MenuEntry[client.getMenuOptionCount() + 1];
newEntries[0] = CANCEL();
for (ComparableEntry p : priorityEntries)
{
if (p.matches(entry))
{
currentPriorityEntries.add(entry);
}
}
System.arraycopy(oldentries, 0, newEntries, 1, oldentries.length);
}
else
{
newEntries = Arrays.copyOf(oldentries, client.getMenuOptionCount());
// If there are entries we want to prioritize, we have to remove the rest
if (!currentPriorityEntries.isEmpty() && !client.isMenuOpen())
{
newEntries.retainAll(currentPriorityEntries);
// This is because players existing changes walk-here target
// so without this we lose track of em
if (newEntries.size() != currentPriorityEntries.size())
{
for (MenuEntry e : currentPriorityEntries)
{
if (newEntries.contains(e))
{
continue;
}
for (MenuEntry e2 : client.getMenuEntries())
{
if (e.getType() == e2.getType())
{
e.setTarget(e2.getTarget());
newEntries.add(e);
}
}
}
}
}
boolean isHidden = false;
for (ComparableEntry p : hiddenEntries)
{
if (p.matches(entry))
{
isHidden = true;
break;
}
}
if (isHidden)
{
newEntries.remove(entry);
}
}
MenuEntry leftClickEntry = newEntries[newEntries.length - 1];
if (!currentPriorityEntries.isEmpty() && !client.isMenuOpen())
{
newEntries.add(0, CANCEL());
}
MenuEntry leftClickEntry = newEntries.get(newEntries.size() - 1);
for (ComparableEntry src : swaps.keySet())
{
@@ -257,14 +247,14 @@ public class MenuManager
ComparableEntry tgt = swaps.get(src);
for (int i = newEntries.length - 2; i > 0; i--)
for (int i = newEntries.size() - 2; i > 0; i--)
{
MenuEntry e = newEntries[i];
MenuEntry e = newEntries.get(i);
if (tgt.matches(e))
{
newEntries[newEntries.length - 1] = e;
newEntries[i] = leftClickEntry;
newEntries.set(newEntries.size() - 1, e);
newEntries.set(i, leftClickEntry);
int type = e.getType();
@@ -273,8 +263,9 @@ public class MenuManager
int newType = getLeftClickType(type);
if (newType != -1 && newType != type)
{
MenuEntry original = MenuEntry.copy(e);
e.setType(newType);
originalTypes.put(e, type);
originalType = new EntryTypeMapping(new ComparableEntry(leftClickEntry), original);
}
}
@@ -283,8 +274,7 @@ public class MenuManager
}
}
client.setMenuEntries(newEntries);
currentPriorityEntries.clear();
client.setMenuEntries(newEntries.toArray(new MenuEntry[0]));
}
public void addPlayerMenuItem(String menuText)
@@ -409,18 +399,18 @@ public class MenuManager
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
if (originalTypes.containsKey(event.getMenuEntry()) &&
!event.getTarget().equals("do not edit"))
// Type is changed in check
if (originalType != null && originalType.check(event))
{
event.consume();
client.invokeMenuAction(
event.getActionParam0(),
event.getActionParam1(),
originalTypes.get(event.getMenuEntry()),
event.getType(),
event.getIdentifier(),
event.getOption(),
"do not edit",
event.getTarget(),
client.getMouseCanvasPosition().getX(),
client.getMouseCanvasPosition().getY()
);
@@ -749,4 +739,24 @@ public class MenuManager
{
hiddenEntries.remove(entry);
}
@AllArgsConstructor
private class EntryTypeMapping
{
private final ComparableEntry comparable;
private final MenuEntry target;
private boolean check(MenuOptionClicked event)
{
MenuEntry entry = event.getMenuEntry();
if (event.getTarget().equals("do not edit") || !comparable.matches(entry))
{
return false;
}
event.setMenuEntry(target);
return true;
}
}
}

View File

@@ -0,0 +1,219 @@
/*
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* 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.barbarianassault;
import com.google.common.collect.ImmutableMap;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
import javax.inject.Inject;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.BasicStroke;
import java.util.Map;
class AboveSceneOverlay extends Overlay
{
private static final int HEALTH_BAR_HEIGHT = 20;
private static final int HEALTH_BAR_WIDTH = 115;
private static final int CENTER_OFFSET = Perspective.LOCAL_HALF_TILE_SIZE / 8;
private static final int EGG_DIAMETER = Perspective.LOCAL_HALF_TILE_SIZE / 4;
private static final Color HEALTH_BAR_COLOR = new Color(225, 35, 0, 125);
private static final ImmutableMap<WidgetInfo, Point> TEAMMATES = ImmutableMap.of(
WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2),
WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2),
WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2),
WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2));
private final Client client;
private final BarbarianAssaultPlugin game;
private final BarbarianAssaultConfig config;
@Inject
private AboveSceneOverlay(Client client, BarbarianAssaultPlugin game, BarbarianAssaultConfig config)
{
super(game);
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE);
this.client = client;
this.game = game;
this.config = config;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!game.isInGame() || game.getRole() == null || game.isUsingGloryHorn())
{
return null;
}
switch (game.getRole())
{
case HEALER:
if (config.showTeammateHealthbars())
{
renderHealthBars(graphics);
}
if (config.healerCodes())
{
renderHealerCodes(graphics);
}
break;
case COLLECTOR:
if (config.highlightCollectorEggs())
{
renderEggs(graphics);
}
break;
}
return null;
}
//TODO add poison color change or low health color change
private void renderHealthBars(Graphics2D graphics)
{
for (Map.Entry<WidgetInfo, Point> teammate : TEAMMATES.entrySet())
{
Widget widget = client.getWidget(teammate.getKey());
if (widget == null)
{
continue;
}
// This will give us two elements, the first will be current health, and the second will be max health
String[] teammateHealth = widget.getText().split(" / ");
graphics.setColor(HEALTH_BAR_COLOR);
graphics.fillRect((widget.getCanvasLocation().getX() - teammate.getValue().getX()),
(widget.getCanvasLocation().getY() - teammate.getValue().getY()),
getBarWidth(Integer.parseInt(teammateHealth[1]), Integer.parseInt(teammateHealth[0])),
HEALTH_BAR_HEIGHT);
}
}
private int getBarWidth(int base, int current)
{
final double ratio = (double) current / base;
if (ratio >= 1)
{
return HEALTH_BAR_WIDTH;
}
return (int) Math.round(ratio * HEALTH_BAR_WIDTH);
}
private void renderHealerCodes(Graphics2D graphics)
{
for (Healer healer : game.getHealers().values())
{
Color color = Color.GREEN;
int timeLeft = 0;
if (game.getWave() != null)
{
timeLeft = healer.getLastFoodTime() - (int) game.getWave().getWaveTimer().getElapsedTime();
}
timeLeft = timeLeft < 1 ? 0 : timeLeft;
if (timeLeft > 0)
{
color = Color.RED;
}
String text = String.format("%d %d", healer.getFoodRemaining(), timeLeft);
OverlayUtil.renderActorOverlay(graphics, healer.getNpc(), text, color);
}
}
private void renderEggs(Graphics2D graphics)
{
final Color color = graphics.getColor();
final Stroke originalStroke = graphics.getStroke();
String listen = game.getLastListenText();
if (listen != null && !listen.equals("- - -"))
{
graphics.setStroke(new BasicStroke(2));
//TODO Render quantity text as well
//TODO add config options for overlay colors
switch (listen)
{
case "Red eggs":
graphics.setColor(new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue(), 150));
game.getRedEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
break;
case "Green eggs":
graphics.setColor(new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 150));
game.getGreenEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
break;
case "Blue eggs":
graphics.setColor(new Color(Color.BLUE.getRed(), Color.BLUE.getGreen(), Color.BLUE.getBlue(), 150));
game.getBlueEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
break;
}
}
graphics.setColor(new Color(Color.YELLOW.getRed(), Color.YELLOW.getGreen(), Color.YELLOW.getBlue(), 150));
game.getYellowEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
graphics.setColor(color);
graphics.setStroke(originalStroke);
}
private void drawCircle(Graphics2D graphics, LocalPoint point)
{
if (point == null)
{
return;
}
Point canvasPoint = Perspective.localToCanvas(client, point, 0);
if (canvasPoint == null)
{
return;
}
//TODO rendering a model would be better / more accurate
graphics.fillOval(canvasPoint.getX() - CENTER_OFFSET, canvasPoint.getY() - CENTER_OFFSET, EGG_DIAMETER, EGG_DIAMETER);
}
}

View File

@@ -0,0 +1,182 @@
/*
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* 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.barbarianassault;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Point;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.util.ImageUtil;
class AboveWidgetsOverlay extends Overlay
{
private static final int OFFSET_X_TEXT_QUANTITY = 0;
private static final int OFFSET_Y_TEXT_QUANTITY = 10;
private final Client client;
private final BarbarianAssaultPlugin game;
private final BarbarianAssaultConfig config;
@Inject
private AboveWidgetsOverlay(Client client, BarbarianAssaultPlugin game, BarbarianAssaultConfig config)
{
super(game);
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.client = client;
this.game = game;
this.config = config;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!game.isInGame() || game.getRole() == null || game.isUsingGloryHorn())
{
return null;
}
Role role = game.getRole();
if (config.showTimer())
{
renderTimer(graphics, role);
}
switch (role)
{
case ATTACKER:
if (config.highlightArrows())
{
renderInventoryHighlights(graphics, game.getRole().getListenItem(game.getLastListenText()), config.highlightArrowColor());
}
break;
case DEFENDER:
if (config.highlightBait())
{
renderInventoryHighlights(graphics, game.getRole().getListenItem(game.getLastListenText()), config.highlightBaitColor());
}
break;
case HEALER:
if (config.highlightPoison())
{
renderInventoryHighlights(graphics, game.getRole().getListenItem(game.getLastListenText()), config.highlightPoisonColor());
}
}
return null;
}
private void renderTimer(Graphics2D graphics, Role role)
{
Widget roleText = client.getWidget(role.getRoleText());
Widget roleSprite = client.getWidget(role.getRoleSprite());
if (roleText == null || roleSprite == null)
{
return;
}
if (role == Role.COLLECTOR && config.showEggCountOverlay() && game.getWave() != null)
{
roleText.setText("(" + game.getWave().getCollectedEggCount() + ") " + formatClock());
}
else if (role == Role.HEALER && config.showHpCountOverlay() && game.getWave() != null)
{
roleText.setText("(" + game.getWave().getHpHealed() + ") " + formatClock());
}
else
{
roleText.setText(formatClock());
}
Rectangle spriteBounds = roleSprite.getBounds();
graphics.drawImage(game.getClockImage(), spriteBounds.x, spriteBounds.y, null);
roleSprite.setHidden(true);
}
private void renderInventoryHighlights(Graphics2D graphics, int itemID, Color color)
{
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
if (inventory == null || inventory.isHidden() || itemID == -1)
{
return;
}
Color highlight = new Color(color.getRed(), color.getGreen(), color.getBlue(), 150);
BufferedImage image = ImageUtil.fillImage(client.createItemSprite(itemID, 300, 2, 0, 0, true, 710).toBufferedImage(), highlight);
for (WidgetItem item : inventory.getWidgetItems())
{
if (item.getId() == itemID)
{
OverlayUtil.renderImageLocation(graphics, item.getCanvasLocation(), image);
//The item's text quantity is rendered after the sprite's image is rendered so that the text appears on top
if (item.getQuantity() > 1)
{
OverlayUtil.renderTextLocation(graphics,
new Point(item.getCanvasLocation().getX() + OFFSET_X_TEXT_QUANTITY, item.getCanvasLocation().getY() + OFFSET_Y_TEXT_QUANTITY),
String.valueOf(item.getQuantity()), Color.YELLOW);
}
}
}
}
private String formatClock()
{
if (game.getCallTimer() == null)
{
return "- - -";
}
else
{
long timeLeft = game.getTimeToChange();
if (timeLeft < 0)
{
return "00:00";
}
else
{
return String.format("00:%02d", timeLeft);
}
}
}
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,26 +29,112 @@ import java.awt.Color;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Range;
@ConfigGroup("barbarianAssault")
public interface BarbarianAssaultConfig extends Config
{
@ConfigItem(
keyName = "swapLadder",
name = "Swap quick-start",
description = "Enables swapping of 'Climb-down' and 'Quick-start' in the wave lobby",
position = 0
)
default boolean swapLadder()
{
return true;
}
@ConfigItem(
keyName = "showTimer",
name = "Show call change timer",
description = "Show time to next call change",
position = 0
description = "Shows time to next call change",
position = 1
)
default boolean showTimer()
{
return true;
}
@ConfigItem(
keyName = "removeIncorrectCalls",
name = "Remove incorrect calls",
description = "Removes incorrect 'Tell' menu options from horn",
position = 2
)
default boolean removeIncorrectCalls()
{
return true;
}
@ConfigItem(
keyName = "removeUnusedMenus",
name = "Remove unused menus",
description = "Removes unnecessary menu options" +
"<br>Example: Attack options are removed when not attacker",
position = 3
)
default boolean removeUnusedMenus()
{
return true;
}
@ConfigItem(
keyName = "prayerMetronome",
name = "Enable prayer metronome",
description = "Turns on a metronome sync'd to the game's tick rate when any prayer is active",
position = 4
)
default boolean prayerMetronome()
{
return false;
}
@Range(
min = 1,
max = 50
)
@ConfigItem(
keyName = "prayerMetronomeVolume",
name = "Metronome volume",
description = "Adjusts the metronome's volume",
position = 5,
hidden = true,
unhide = "prayerMetronome"
)
default int prayerMetronomeVolume()
{
return 10;
}
@ConfigItem(
keyName = "showDeathTimes",
name = "Show death times",
description = "Shows the time all penance monsters of a certain type are killed in the chat box, an info box, or both",
position = 6
)
default boolean showDeathTimes()
{
return true;
}
@ConfigItem(
keyName = "showDeathTimesMode",
name = "Mode",
description = "",
position = 7,
hidden = true,
unhide = "showDeathTimes"
)
default DeathTimesMode showDeathTimesMode()
{
return DeathTimesMode.BOTH;
}
@ConfigItem(
keyName = "waveTimes",
name = "Show wave and game duration",
description = "Displays wave and game duration",
position = 1
description = "Displays wave duration after each wave and total game time after wave 10",
position = 8
)
default boolean waveTimes()
{
@@ -55,112 +142,329 @@ public interface BarbarianAssaultConfig extends Config
}
@ConfigItem(
keyName = "showEggCountMessage",
name = "Show count of eggs collected as collector.",
description = "Display egg count as collector after each wave",
position = 2
keyName = "showTotalRewards",
name = "Summarize total reward points",
description = "Gives summary of advanced points breakdown in chat log",
position = 9
)
default boolean showEggCount()
default boolean showTotalRewards()
{
return true;
}
/*///************///*/
/*/// Attacker ///*/
/*///************///*/
@ConfigItem(
keyName = "highlightArrows",
name = "Highlight called arrows",
description = "Highlights arrows called by your teammate",
position = 0,
group = "Attacker"
)
default boolean highlightArrows()
{
return true;
}
@ConfigItem(
keyName = "highlightArrowColor",
name = "Arrow color",
description = "Configures the color to highlight the called arrows",
position = 1,
group = "Attacker",
hidden = true,
unhide = "highlightArrows"
)
default Color highlightArrowColor()
{
return Color.GREEN;
}
@ConfigItem(
keyName = "removeIncorrectAttackStyles",
name = "Remove incorrect attack styles",
description = "Hides wrong attack styles for dragon claws and crystal halberd",
position = 2,
group = "Attacker"
)
default boolean removeIncorrectAttackStyles()
{
return false;
}
@ConfigItem(
keyName = "showEggCountOverlay",
name = "Overlay of eggs counted",
description = "Display current egg count as collector",
position = 3
keyName = "tagging",
name = "Enable tagging",
description = "Highlights the menu entry of an attacker/ranger that has not been tagged.",
position = 3,
group = "Attacker"
)
default boolean showEggCountOverlay()
default boolean tagging()
{
return false;
}
/*///************///*/
/*/// Defender ///*/
/*///************///*/
@ConfigItem(
keyName = "showHpCountMessage",
name = "Show count of Hp healed as healer.",
description = "Display healed count as healer after each wave",
position = 4
keyName = "highlightBait",
name = "Highlight called bait",
description = "Highlights bait called by your teammate",
position = 0,
group = "Defender"
)
default boolean showHpCount()
default boolean highlightBait()
{
return false;
return true;
}
@ConfigItem(
keyName = "highlightBaitColor",
name = "Bait color",
description = "Configures the color to highlight the called bait",
position = 1,
group = "Defender",
hidden = true,
unhide = "highlightBait"
)
default Color highlightBaitColor()
{
return Color.GREEN;
}
@ConfigItem(
keyName = "showDefTimer",
name = "Show defender tick timer",
description = "Shows the current cycle tick of runners",
position = 2,
group = "Defender"
)
default boolean showDefTimer()
{
return true;
}
@ConfigItem(
keyName = "deprioritizeBait",
name = "Deprioritize bait",
description = "Moves 'Take' menu option for all bait below 'Walk Here'",
position = 3,
group = "Defender"
)
default boolean deprioritizeBait()
{
return true;
}
@ConfigItem(
keyName = "removePenanceCave",
name = "Remove penance cave",
description = "Removes 'Block' menu option from penance cave",
position = 4,
group = "Defender"
)
default boolean removePenanceCave()
{
return true;
}
/*///**********///*/
/*/// Healer ///*/
/*///**********///*/
@ConfigItem(
keyName = "highlightPoison",
name = "Highlight called poison",
description = "Highlights poison called by your teammate",
position = 0,
group = "Healer"
)
default boolean highlightPoison()
{
return true;
}
@ConfigItem(
keyName = "highlightPoisonColor",
name = "Poison color",
description = "Configures the color to highlight the called poison",
position = 1,
group = "Healer",
hidden = true,
unhide = "highlightPoison"
)
default Color highlightPoisonColor()
{
return Color.GREEN;
}
@ConfigItem(
keyName = "highlightNotification",
name = "Highlight incorrect notification",
description = "Highlights incorrect poison chat notification",
position = 2,
group = "Healer"
)
default boolean highlightNotification()
{
return true;
}
@ConfigItem(
keyName = "highlightNotificationColor",
name = "Notification color",
description = "Configures the color to highlight the notification text",
position = 3,
group = "Healer",
hidden = true,
unhide = "highlightNotification"
)
default Color highlightNotificationColor()
{
return Color.RED;
}
@ConfigItem(
keyName = "showHpCountOverlay",
name = "Overlay of Hp counted",
description = "Display current healed count as healer",
position = 5
name = "Show number of hitpoints healed",
description = "Displays current number of hitpoints healed",
position = 4,
group = "Healer"
)
default boolean showHpCountOverlay()
{
return true;
}
@ConfigItem(
keyName = "showTeammateHealthbars",
name = "Show health bars",
description = "Displays a health bar where a teammate's remaining health is located",
position = 5,
group = "Healer"
)
default boolean showTeammateHealthbars()
{
return true;
}
@ConfigItem(
keyName = "healerCodes",
name = "Show healer codes",
description = "Overlay to show healer codes",
position = 6,
group = "Healer"
)
default boolean healerCodes()
{
return false;
}
@ConfigItem(
keyName = "healerMenuOption",
name = "Show healer menu options",
description = "Shows tick count in healer menu options",
position = 7,
group = "Healer"
)
default boolean healerMenuOption()
{
return false;
}
@ConfigItem(
keyName = "shiftOverstock",
name = "Enable shift overstock",
description = "Enables overstocking by pressing shift",
position = 8,
group = "Healer"
)
default boolean shiftOverstock()
{
return true;
}
@ConfigItem(
keyName = "controlHealer",
name = "Control Healer",
description = "Hold ctrl to put last healer clicked on top",
position = 9,
group = "Healer"
)
default boolean controlHealer()
{
return true;
}
/*///*************///*/
/*/// Collector ///*/
/*///*************///*/
@ConfigItem(
keyName = "swapCollectorBag",
name = "Swap empty",
description = "Enables swapping of 'Look-in' and 'Empty' on the collector's bag",
position = 0,
group = "Collector"
)
default boolean swapCollectorBag()
{
return true;
}
@ConfigItem(
keyName = "swapDestroyEggs",
name = "Swap destroy",
description = "Enables swapping of 'Use' and 'Destroy' on collector eggs; this does not affect yellow/omega eggs",
position = 1,
group = "Collector"
)
default boolean swapDestroyEggs()
{
return true;
}
@ConfigItem(
keyName = "highlightCollectorEggs",
name = "Highlight collector eggs",
description = "Highlight called egg colors",
position = 6
position = 2,
group = "Collector"
)
default boolean highlightCollectorEggs()
{
return false;
return true;
}
@ConfigItem(
keyName = "showTotalRewards",
name = "Summarize total reward points",
description = "Displays total eggs/healed hp and missed attacks/lost runners",
position = 7
keyName = "deprioritizeIncorrectEggs",
name = "Deprioritize incorrect eggs",
description = "Moves 'Take' menu option for incorrect eggs below 'Walk Here'",
position = 3,
group = "Collector"
)
default boolean showTotalRewards()
default boolean deprioritizeIncorrectEggs()
{
return false;
return true;
}
@ConfigItem(
keyName = "showSummaryOfPoints",
name = "Display summary of advanced points",
description = "Gives summary of advanced points breakdown in chat log",
position = 8
keyName = "showEggCountOverlay",
name = "Show number of eggs collected",
description = "Displays current number of eggs collected",
position = 4,
group = "Collector"
)
default boolean showSummaryOfPoints()
default boolean showEggCountOverlay()
{
return false;
return true;
}
@ConfigItem(
keyName = "wrongPoisonFoodTextColor",
name = "Change healer wrong poison pack color",
description = "Change healer wrong poison pack color",
position = 9
)
default Color wrongPoisonFoodTextColor()
{
return Color.BLACK;
}
@ConfigItem(
keyName = "highlightItems",
name = "Highlight called poison/bait",
description = "Highlights the poison or bait that was called by your teammate",
position = 10
)
default boolean highlightItems()
{
return false;
}
@ConfigItem(
keyName = "highlightColor",
name = "Highlight color",
description = "Configures the color to highlight the called poison/bait",
position = 11
)
default Color highlightColor()
{
return Color.GREEN;
}
}
}

View File

@@ -0,0 +1,227 @@
/*
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* 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.barbarianassault;
import com.google.common.collect.Sets;
import lombok.Getter;
import lombok.Setter;
import net.runelite.client.menus.ComparableEntry;
import net.runelite.client.menus.MenuManager;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
class BarbarianAssaultMenu
{
private final MenuManager menuManager;
private final BarbarianAssaultPlugin game;
private final BarbarianAssaultConfig config;
private final ArrayList<ComparableEntry> tracker = new ArrayList<>();
@Getter @Setter
private boolean hornUpdated = false;
@Getter @Setter
private boolean rebuildForced = false;
@Inject
BarbarianAssaultMenu(MenuManager menuManager, BarbarianAssaultPlugin game, BarbarianAssaultConfig config)
{
this.menuManager = menuManager;
this.game = game;
this.config = config;
}
private boolean isHornOptionHidden(String option)
{
if (game.isInGame() && game.getRole() != null && game.getRole().getTell(game.getLastCallText()).toLowerCase().equals(option))
{
// This will force the menu to be rebuilt after the correct tell is found
// medic will be added to the menu if it wasn't there before
if (!hornUpdated)
{
rebuildForced = true;
}
hornUpdated = true;
return false;
}
return true;
}
void clearHiddenMenus()
{
// Clears menus from MenuManager and tracker
for (Iterator<ComparableEntry> iterator = tracker.iterator(); iterator.hasNext();)
{
menuManager.removeHiddenEntry(iterator.next());
iterator.remove();
}
}
//TODO add omega egg use on?
void validateHiddenMenus(Role role)
{
clearHiddenMenus();
HashSet<Menus> hiddenMenus = Sets.newHashSet(Menus.getMenus());
HashSet<Menus> conditionalMenus = Sets.newHashSet(Menus.getMenus());
// Any option left in this set will not be hidden
// Checking each option for the correct role prevents MenuManager from
// iterating over off role menu entry options that are not possible
conditionalMenus.removeIf(entry ->
{
switch (entry)
{
// Attacker role options
case TELL_BLUE_ATTACKER_HORN:
case TELL_GREEN_ATTACKER_HORN:
case TELL_RED_ATTACKER_HORN:
return ((role == Role.ATTACKER && isHornOptionHidden(entry.getOption())) || role == null) && config.removeIncorrectCalls();
case ATTACK_PENANCE_FIGHTER:
case ATTACK_PENANCE_RANGER:
case GET_SPIKES_PETRIFIED_MUSHROOM:
case TAKE_ATTACKER_ITEM_MACHINE:
return (role != Role.ATTACKER && role != null) && config.removeUnusedMenus();
// Defender role Options
case TELL_MEAT_DEFENDER_HORN:
case TELL_TOFU_DEFENDER_HORN:
case TELL_WORMS_DEFENDER_HORN:
return ((role == Role.DEFENDER && isHornOptionHidden(entry.getOption())) || role == null) && config.removeIncorrectCalls();
case BLOCK_PENANCE_CAVE:
return ((role != Role.DEFENDER && role != null) && config.removeUnusedMenus())
|| (role == Role.DEFENDER && config.removePenanceCave());
case DUNK_LAVA_CRATER:
case FIX:
case STOCK_UP_DEFENDER_ITEM_MACHINE:
case TAKE_DEFENDER_ITEM_MACHINE:
case TAKE_HAMMER:
case TAKE_LOGS:
return (role != Role.DEFENDER && role != null) && config.removeUnusedMenus();
// Collector role options
case TELL_ACCURATE_COLLECTOR_HORN:
case TELL_AGGRESSIVE_COLLECTOR_HORN:
case TELL_CONTROLLED_COLLECTOR_HORN:
case TELL_DEFENSIVE_COLLECTOR_HORN:
return ((role == Role.COLLECTOR && isHornOptionHidden(entry.getOption())) || role == null) && config.removeIncorrectCalls();
case CONVERT_COLLECTOR_CONVERTER:
case LOAD_EGG_HOPPER:
case TAKE_BLUE_EGG:
case TAKE_GREEN_EGG:
case TAKE_RED_EGG:
case TAKE_YELLOW_EGG:
return (role != Role.COLLECTOR && role != null) && config.removeUnusedMenus();
// Healer role options
case TELL_CRACKERS_HEALER_HORN:
case TELL_TOFU_HEALER_HORN:
case TELL_WORMS_HEALER_HORN:
return ((role == Role.HEALER && isHornOptionHidden(entry.getOption())) || role == null) && config.removeIncorrectCalls();
case DUNK_POISON_CRATER:
case STOCK_UP_HEALER_ITEM_MACHINE:
case TAKE_HEALER_ITEM_MACHINE:
case TAKE_FROM_HEALER_SPRING:
case DRINK_FROM_HEALER_SPRING:
return (role != Role.HEALER && role != null) && config.removeUnusedMenus();
case USE_VIAL_GROUND:
case USE_VIAL_ITEM:
case USE_VIAL_NPC:
case USE_VIAL_WIDGET:
return role == Role.HEALER && config.removeUnusedMenus();
// Any role options
case DROP_HORN:
case EXAMINE_HORN:
case USE_HORN:
return config.removeIncorrectCalls();
case MEDIC_HORN:
return config.removeIncorrectCalls() && !hornUpdated;
default:
return config.removeUnusedMenus();
}
});
hiddenMenus.removeAll(conditionalMenus);
for (Menus entry : hiddenMenus)
{
menuManager.addHiddenEntry(entry.getEntry());
tracker.add(entry.getEntry());
}
}
void enableSwaps()
{
if (config.swapLadder())
{
menuManager.addSwap("climb-down", "ladder", "quick-start", "ladder");
}
if (config.swapCollectorBag())
{
menuManager.addSwap("look-in", "collection bag", "empty", "collection bag");
}
if (config.swapDestroyEggs())
{
menuManager.addSwap("use", "blue egg", "destroy", "blue egg");
menuManager.addSwap("use", "green egg", "destroy", "green egg");
menuManager.addSwap("use", "red egg", "destroy", "red egg");
}
}
void disableSwaps(boolean force)
{
if (!config.swapLadder() || force)
{
menuManager.removeSwap("climb-down", "ladder", "quick-start", "ladder");
}
if (!config.swapCollectorBag() || force)
{
menuManager.removeSwap("look-in", "collection bag", "empty", "collection bag");
}
if (!config.swapDestroyEggs() || force)
{
menuManager.removeSwap("use", "blue egg", "destroy", "blue egg");
menuManager.removeSwap("use", "green egg", "destroy", "green egg");
menuManager.removeSwap("use", "red egg", "destroy", "red egg");
}
}
}

View File

@@ -1,247 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.barbarianassault;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.image.BufferedImage;
import java.util.Map;
import javax.inject.Inject;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
import net.runelite.api.Perspective;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.util.ImageUtil;
class BarbarianAssaultOverlay extends Overlay
{
private static final int MAX_EGG_DISTANCE = 2500;
private static final int HEALTH_BAR_HEIGHT = 20;
private final Color HEALTH_BAR_COLOR = new Color(225, 35, 0, 125);
private static final Color BACKGROUND = new Color(0, 0, 0, 150);
private static final int OFFSET_Z = 20;
private final Client client;
private final ItemManager itemManager;
private final BarbarianAssaultPlugin plugin;
private final BarbarianAssaultConfig config;
@Getter
@Setter
private Round currentRound;
@Inject
private BarbarianAssaultOverlay(Client client, ItemManager itemManager, BarbarianAssaultPlugin plugin, BarbarianAssaultConfig config)
{
super(plugin);
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.client = client;
this.itemManager = itemManager;
this.plugin = plugin;
this.config = config;
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "B.A. overlay"));
}
@Override
public Dimension render(Graphics2D graphics)
{
if (client.getGameState() != GameState.LOGGED_IN || currentRound == null)
{
return null;
}
Role role = currentRound.getRoundRole();
if (role == null)
{
return null;
}
Widget roleText = client.getWidget(role.getRoleText());
Widget roleSprite = client.getWidget(role.getRoleSprite());
if (config.showTimer() && roleText != null && roleSprite != null)
{
if (config.showEggCountOverlay() && role.equals(Role.COLLECTOR))
{
roleText.setText(String.format("(%d) 00:%02d", plugin.getCollectedEggCount(), currentRound.getTimeToChange()));
}
else if (config.showHpCountOverlay() && role.equals(Role.HEALER))
{
roleText.setText(String.format("(%d) 00:%02d", plugin.getHpHealed(), currentRound.getTimeToChange()));
}
else
{
roleText.setText(String.format("00:%02d", currentRound.getTimeToChange()));
}
Rectangle spriteBounds = roleSprite.getBounds();
roleSprite.setHidden(true);
graphics.drawImage(plugin.getClockImage(), spriteBounds.x, spriteBounds.y, null);
}
if (role == Role.COLLECTOR && config.highlightCollectorEggs())
{
String heardCall = plugin.getCollectorHeardCall();
Color highlightColor = BarbarianAssaultPlugin.getEggColor(heardCall);
Map<WorldPoint, Integer> calledEggMap = plugin.getCalledEggMap();
Map<WorldPoint, Integer> yellowEggMap = plugin.getYellowEggs();
if (calledEggMap != null)
{
renderEggLocations(graphics, calledEggMap, highlightColor);
}
// Always show yellow eggs
renderEggLocations(graphics, yellowEggMap, Color.YELLOW);
}
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
if (config.highlightItems() && inventory != null && !inventory.isHidden() && ((role == Role.DEFENDER || role == Role.HEALER)))
{
int listenItemId = plugin.getListenItemId(role.getListen());
if (listenItemId != -1)
{
Color color = config.highlightColor();
BufferedImage highlight = ImageUtil.fillImage(itemManager.getImage(listenItemId), new Color(color.getRed(), color.getGreen(), color.getBlue(), 150));
for (WidgetItem item : inventory.getWidgetItems())
{
if (item.getId() == listenItemId)
{
OverlayUtil.renderImageLocation(graphics, item.getCanvasLocation(), highlight);
}
}
}
}
if (role == Role.HEALER)
{
for (HealerTeam teammate : HealerTeam.values())
{
Widget widget = client.getWidget(teammate.getTeammate());
if (widget == null)
{
continue;
}
String[] teammateHealth = widget.getText().split(" / ");
final int curHealth = Integer.parseInt(teammateHealth[0]);
final int maxHealth = Integer.parseInt(teammateHealth[1]);
int width = teammate.getWidth();
final int filledWidth = getBarWidth(maxHealth, curHealth, width);
int offsetX = teammate.getOffset().getX();
int offsetY = teammate.getOffset().getY();
int x = widget.getCanvasLocation().getX() - offsetX;
int y = widget.getCanvasLocation().getY() - offsetY;
graphics.setColor(HEALTH_BAR_COLOR);
graphics.fillRect(x, y, filledWidth, HEALTH_BAR_HEIGHT);
}
}
return null;
}
private static int getBarWidth(int base, int current, int size)
{
final double ratio = (double) current / base;
if (ratio >= 1)
{
return size;
}
return (int) Math.round(ratio * size);
}
private void renderEggLocations(Graphics2D graphics, Map<WorldPoint, Integer> eggMap, Color color)
{
Player player = client.getLocalPlayer();
if (player == null)
{
return;
}
final Stroke originalStroke = graphics.getStroke();
for (WorldPoint worldPoint : eggMap.keySet())
{
LocalPoint groundPoint = LocalPoint.fromWorld(client, worldPoint);
if (groundPoint == null)
{
continue;
}
if (player.getLocalLocation().distanceTo(groundPoint) > MAX_EGG_DISTANCE)
{
continue;
}
Polygon poly = Perspective.getCanvasTilePoly(client, groundPoint);
if (poly == null)
{
continue;
}
int quantity = eggMap.get(worldPoint);
String quantityText = "x" + quantity;
Point textPoint = Perspective.getCanvasTextLocation(client, graphics, groundPoint, quantityText, OFFSET_Z);
graphics.setColor(color);
graphics.setStroke(new BasicStroke(2));
graphics.drawPolygon(poly);
OverlayUtil.renderTextLocation(graphics, textPoint, quantityText, Color.WHITE);
}
graphics.setStroke(originalStroke);
}
}

View File

@@ -1,83 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.barbarianassault;
import java.util.HashMap;
import java.util.Map;
public enum Calls
{ //Attacker Calls
RED_EGG("Red egg", "Tell-red"),
GREEN_EGG("Green egg", "Tell-green"),
BLUE_EGG("Blue egg", "Tell-blue"),
//Collector Calls
CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"),
ACCURATE("Accurate/Field/Water", "Tell-accurate"),
AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"),
DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"),
//Healer Calls
TOFU("Tofu", "Tell-tofu"),
CRACKERS("Crackers", "Tell-crackers"),
WORMS("Worms", "Tell-worms"),
//Defender Calls
POIS_WORMS("Pois. Worms", "Tell-worms"),
POIS_TOFU("Pois. Tofu", "Tell-tofu"),
POIS_MEAT("Pois. Meat", "Tell-meat");
private final String call;
private final String option;
private static final Map<String, String> CALL_MENU = new HashMap<>();
static
{
for (Calls s : values())
{
CALL_MENU.put(s.getCall(), s.getOption());
}
}
Calls(String call, String option)
{
this.call = call;
this.option = option;
}
public String getCall()
{
return call;
}
public String getOption()
{
return option;
}
public static String getOption(String call)
{
return CALL_MENU.get(call);
}
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -10,6 +11,7 @@
* 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
@@ -21,26 +23,25 @@
* (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.ticktimers;
package net.runelite.client.plugins.barbarianassault;
import java.awt.Font;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum FontStyle
public enum DeathTimesMode
{
BOLD("Bold", Font.BOLD),
ITALIC("Italic", Font.ITALIC),
PLAIN("Plain", Font.PLAIN);
BOTH("Both"),
CHAT_BOX("Chat Box"),
INFO_BOX("Info Box");
private String name;
private int font;
private final String name;
DeathTimesMode(String name)
{
this.name = name;
}
@Override
public String toString()
{
return getName();
return name;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* 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.barbarianassault;
import com.google.common.collect.ImmutableList;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import net.runelite.api.NPC;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
@Data
class Healer
{
@Getter(AccessLevel.NONE)
private static final List<List<int[]>> CODES = ImmutableList.of(
// ImmutableList.of(firstCallFood, secondCallFood, lastFoodTime),
ImmutableList.of(new int[]{1, 1}, new int[]{0, 0}, new int[]{0, 0}),
ImmutableList.of(new int[]{1, 1, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 21}),
ImmutableList.of(new int[]{1, 6, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 0}),
ImmutableList.of(new int[]{2, 5, 2, 0}, new int[]{0, 0, 7, 10}, new int[]{0, 0, 0, 0}),
ImmutableList.of(new int[]{2, 5, 2, 3, 0}, new int[]{0, 0, 0, 0, 7}, new int[]{0, 0, 21, 30, 0}),
ImmutableList.of(new int[]{3, 5, 2, 2, 0, 0}, new int[]{0, 0, 0, 2, 9, 10}, new int[]{12, 18, 21, 0, 0, 0}),
ImmutableList.of(new int[]{3, 7, 1, 1, 0, 0, 0}, new int[]{2, 0, 1, 1, 2, 4, 10}, new int[]{0, 21, 0, 0, 30, 45, 0}),
ImmutableList.of(new int[]{1, 9, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 2, 10}, new int[]{0, 0, 0, 0, 33, 42, 0}),
ImmutableList.of(new int[]{2, 8, 1, 1, 0, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 1, 1, 10}, new int[]{0, 21, 0, 0, 0, 0, 0, 0, 0}),
ImmutableList.of(new int[]{2, 5, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 4, 4, 8}, new int[]{21, 33, 0, 33, 30, 45, 0}));
private final NPC npc;
private int wave;
private int spawnNumber;
private int foodRemaining;
private int lastFoodTime;
private int firstCallFood;
private int secondCallFood;
private Instant timeLastPoisoned = null;
Healer(NPC npc, int spawnNumber, int wave)
{
this.npc = npc;
this.wave = wave;
this.spawnNumber = spawnNumber;
List<int[]> code = CODES.get(wave - 1);
this.firstCallFood = code.get(0)[spawnNumber];
this.secondCallFood = code.get(1)[spawnNumber];
this.lastFoodTime = code.get(2)[spawnNumber];
this.foodRemaining = firstCallFood + secondCallFood;
}
int timeToPoison()
{
if (timeLastPoisoned == null)
{
return -1;
}
else
{
long time = Duration.between(timeLastPoisoned, Instant.now()).getSeconds();
return time > 20 ? 0 : (int)(20 - time);
}
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* 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.barbarianassault;
import com.google.common.collect.ImmutableSet;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.MenuAction;
import net.runelite.client.menus.ComparableEntry;
@AllArgsConstructor
public enum Menus
{
ATTACK_PENANCE_FIGHTER(Role.ATTACKER, new ComparableEntry("attack", "penance fighter", -1, -1, true, false)),
ATTACK_PENANCE_RANGER(Role.ATTACKER, new ComparableEntry("attack", "penance ranger", -1, -1, true, false)),
GET_SPIKES_PETRIFIED_MUSHROOM(Role.ATTACKER, new ComparableEntry("get-spikes", "petrified mushroom", -1, -1, true, true)),
TAKE_ATTACKER_ITEM_MACHINE(Role.ATTACKER, new ComparableEntry("take", "attacker item machine", -1, -1, false, true)),
TELL_RED_ATTACKER_HORN(Role.ATTACKER, new ComparableEntry("tell-red", "attacker horn", -1, -1, true, true)),
TELL_GREEN_ATTACKER_HORN(Role.ATTACKER, new ComparableEntry("tell-green", "attacker horn", -1, -1, true, true)),
TELL_BLUE_ATTACKER_HORN(Role.ATTACKER, new ComparableEntry("tell-blue", "attacker horn", -1, -1, true, true)),
BLOCK_PENANCE_CAVE(Role.DEFENDER, new ComparableEntry("block", "penance cave", -1, -1, true, true)),
DUNK_LAVA_CRATER(Role.DEFENDER, new ComparableEntry("dunk", "lava crater", -1, -1, true, true)),
FIX(Role.DEFENDER, new ComparableEntry("fix", "", -1, -1, true, false)),
STOCK_UP_DEFENDER_ITEM_MACHINE(Role.DEFENDER, new ComparableEntry("stock-up", "defender item machine", -1, -1, true, true)),
TAKE_DEFENDER_ITEM_MACHINE(Role.DEFENDER, new ComparableEntry("take", "defender item machine", -1, -1, false, true)),
TAKE_HAMMER(Role.DEFENDER, new ComparableEntry("take", "hammer", -1, -1, true, true)),
TAKE_LOGS(Role.DEFENDER, new ComparableEntry("take", "logs", -1, -1, true, true)),
TELL_WORMS_DEFENDER_HORN(Role.DEFENDER, new ComparableEntry("tell-worms", "defender horn", -1, -1, true, true)),
TELL_TOFU_DEFENDER_HORN(Role.DEFENDER, new ComparableEntry("tell-tofu", "defender horn", -1, -1, true, true)),
TELL_MEAT_DEFENDER_HORN(Role.DEFENDER, new ComparableEntry("tell-meat", "defender horn", -1, -1, true, true)),
DRINK_FROM_HEALER_SPRING(Role.HEALER, new ComparableEntry("drink-from", "healer spring", -1, -1, true, true)),
DUNK_POISON_CRATER(Role.HEALER, new ComparableEntry("dunk", "poison crater", -1, -1, true, true)),
STOCK_UP_HEALER_ITEM_MACHINE(Role.HEALER, new ComparableEntry("stock-up", "healer item machine", -1, -1, true, true)),
TAKE_HEALER_ITEM_MACHINE(Role.HEALER, new ComparableEntry("take", "healer item machine", -1, -1, false, true)),
TAKE_FROM_HEALER_SPRING(Role.HEALER, new ComparableEntry("take-from", "healer spring", -1, -1, true, true)),
TELL_TOFU_HEALER_HORN(Role.HEALER, new ComparableEntry("tell-tofu", "healer horn", -1, -1, true, true)),
TELL_CRACKERS_HEALER_HORN(Role.HEALER, new ComparableEntry("tell-crackers", "healer horn", -1, -1, true, true)),
TELL_WORMS_HEALER_HORN(Role.HEALER, new ComparableEntry("tell-worms", "healer horn", -1, -1, true, true)),
USE_VIAL_GROUND(Role.HEALER, new ComparableEntry("use", "healing vial", -1, MenuAction.ITEM_USE_ON_GROUND_ITEM.getId(), true, false)),
USE_VIAL_ITEM(Role.HEALER, new ComparableEntry("use", "healing vial", -1, MenuAction.ITEM_USE_ON_WIDGET_ITEM.getId(), true, false)),
USE_VIAL_NPC(Role.HEALER, new ComparableEntry("use", "healing vial", -1, MenuAction.ITEM_USE_ON_NPC.getId(), true, false)),
USE_VIAL_WIDGET(Role.HEALER, new ComparableEntry("use", "healing vial", -1, MenuAction.ITEM_USE_ON_WIDGET.getId(), true, false)),
CONVERT_COLLECTOR_CONVERTER(Role.COLLECTOR, new ComparableEntry("convert", "collector converter", -1, -1, true, true)),
LOAD_EGG_HOPPER(Role.COLLECTOR, new ComparableEntry("load", "egg hopper", -1, -1, true, true)),
TAKE_BLUE_EGG(Role.COLLECTOR, new ComparableEntry("take", "blue egg", -1, -1, true, true)),
TAKE_GREEN_EGG(Role.COLLECTOR, new ComparableEntry("take", "green egg", -1, -1, true, true)),
TAKE_RED_EGG(Role.COLLECTOR, new ComparableEntry("take", "red egg", -1, -1, true, true)),
TAKE_YELLOW_EGG(Role.COLLECTOR, new ComparableEntry("take", "yellow egg", -1, -1, true, true)),
TELL_CONTROLLED_COLLECTOR_HORN(Role.COLLECTOR, new ComparableEntry("tell-controlled", "collector horn", -1, -1, true, true)),
TELL_ACCURATE_COLLECTOR_HORN(Role.COLLECTOR, new ComparableEntry("tell-accurate", "collector horn", -1, -1, true, true)),
TELL_AGGRESSIVE_COLLECTOR_HORN(Role.COLLECTOR, new ComparableEntry("tell-aggressive", "collector horn", -1, -1, true, true)),
TELL_DEFENSIVE_COLLECTOR_HORN(Role.COLLECTOR, new ComparableEntry("tell-defensive", "collector horn", -1, -1, true, true)),
ATTACK_PENANCE_QUEEN(null, new ComparableEntry("attack", "penance queen", -1, -1, true, false)),
ATTACK_QUEEN_SPAWN(null, new ComparableEntry("attack", "queen spawn", -1, -1, true, false)),
DROP_HORN(null, new ComparableEntry("drop", "horn", -1, -1, true, false)),
EXAMINE_HORN(null, new ComparableEntry("examine", "horn", -1, -1, true, false)),
LIGHT_LOGS(null, new ComparableEntry("light", "logs", -1, -1, true, true)),
MEDIC_HORN(null, new ComparableEntry("medic", "horn", -1, -1, true, false)),
USE_HORN(null, new ComparableEntry("use", "horn", -1, -1, true, false));
@Getter
private final Role role;
@Getter
private final ComparableEntry entry;
private static final ImmutableSet<Menus> ALL = ImmutableSet.copyOf(Menus.values());
public String getOption()
{
return entry.getOption();
}
public String getTarget()
{
return entry.getTarget();
}
public int getId()
{
return entry.getId();
}
public int getType()
{
return entry.getType();
}
public boolean isStrictOption()
{
return entry.isStrictOption();
}
public boolean isStrictTarget()
{
return entry.isStrictTarget();
}
public static ImmutableSet<Menus> getMenus()
{
return ALL;
}
}

View File

@@ -1,5 +1,7 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,39 +26,211 @@
*/
package net.runelite.client.plugins.barbarianassault;
import com.google.common.collect.ImmutableMap;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.ItemID;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
@AllArgsConstructor
enum Role
{
ATTACKER(WidgetInfo.BA_ATK_LISTEN_TEXT, WidgetInfo.BA_ATK_CALL_TEXT, WidgetInfo.BA_ATK_ROLE_TEXT, WidgetInfo.BA_ATK_ROLE_SPRITE),
DEFENDER(WidgetInfo.BA_DEF_LISTEN_TEXT, WidgetInfo.BA_DEF_CALL_TEXT, WidgetInfo.BA_DEF_ROLE_TEXT, WidgetInfo.BA_DEF_ROLE_SPRITE),
COLLECTOR(WidgetInfo.BA_COLL_LISTEN_TEXT, WidgetInfo.BA_COLL_CALL_TEXT, WidgetInfo.BA_COLL_ROLE_TEXT, WidgetInfo.BA_COLL_ROLE_SPRITE),
HEALER(WidgetInfo.BA_HEAL_LISTEN_TEXT, WidgetInfo.BA_HEAL_CALL_TEXT, WidgetInfo.BA_HEAL_ROLE_TEXT, WidgetInfo.BA_HEAL_ROLE_SPRITE);
ATTACKER(WidgetInfo.BA_ATK_WAVE_TEXT, WidgetInfo.BA_ATK_LISTEN_TOP_TEXT, WidgetInfo.BA_ATK_HORN_LISTEN_TEXT,
WidgetInfo.BA_ATK_CALL_TEXT, WidgetInfo.BA_COLL_HORN_LISTEN_TEXT, WidgetInfo.BA_ATK_ROLE_TEXT,
WidgetInfo.BA_ATK_ROLE_SPRITE),
DEFENDER(WidgetInfo.BA_DEF_WAVE_TEXT, WidgetInfo.BA_DEF_LISTEN_TEXT, WidgetInfo.BA_DEF_HORN_LISTEN_TEXT,
WidgetInfo.BA_DEF_CALL_TEXT, WidgetInfo.BA_HEAL_HORN_LISTEN_TEXT, WidgetInfo.BA_DEF_ROLE_TEXT,
WidgetInfo.BA_DEF_ROLE_SPRITE),
COLLECTOR(WidgetInfo.BA_COLL_WAVE_TEXT, WidgetInfo.BA_COLL_LISTEN_TEXT, WidgetInfo.BA_COLL_HORN_LISTEN_TEXT,
WidgetInfo.BA_COLL_CALL_TEXT, WidgetInfo.BA_ATK_HORN_LISTEN_TEXT, WidgetInfo.BA_COLL_ROLE_TEXT,
WidgetInfo.BA_COLL_ROLE_SPRITE),
HEALER(WidgetInfo.BA_HEAL_WAVE_TEXT, WidgetInfo.BA_HEAL_LISTEN_TEXT, WidgetInfo.BA_DEF_HORN_LISTEN_TEXT,
WidgetInfo.BA_HEAL_CALL_TEXT, WidgetInfo.BA_DEF_HORN_LISTEN_TEXT, WidgetInfo.BA_HEAL_ROLE_TEXT,
WidgetInfo.BA_HEAL_ROLE_SPRITE);
@Getter
private final WidgetInfo wave;
@Getter
private final WidgetInfo listen;
@Getter
private final WidgetInfo gloryListen;
@Getter
private final WidgetInfo call;
@Getter
private final WidgetInfo gloryCall;
@Getter
private final WidgetInfo roleText;
@Getter
private final WidgetInfo roleSprite;
Role(WidgetInfo listen, WidgetInfo call, WidgetInfo role, WidgetInfo roleSprite)
// Duplicate* entries are to catch instances where the horn of glory has
// text different than the normal horn
private static final ImmutableMap<String, String> TELLS = ImmutableMap.<String, String>builder()
.put("Red egg", "Tell-red")
.put("Green egg", "Tell-green")
.put("Blue egg", "Tell-blue")
.put("Controlled/Bullet/Wind", "Tell-controlled")
.put("Accurate/Field/Water", "Tell-accurate")
.put("Aggressive/Blunt/Earth", "Tell-aggressive")
.put("Defensive/Barbed/Fire", "Tell-defensive")
.put("Tofu", "Tell-tofu")
.put("Crackers", "Tell-crackers")
.put("Worms", "Tell-worms")
.put("Poison Worms", "Tell-worms")
.put("Pois. Worms", "Tell-worms")
.put("Poison Tofu", "Tell-tofu")
.put("Pois. Tofu", "Tell-tofu")
.put("Poison Meat", "Tell-meat")
.put("Pois. Meat", "Tell-meat")
.build();
private static final ImmutableMap<String, String> GLORY_CALLS = ImmutableMap.<String, String>builder()
.put("Controlled/Bullet/Wind", "Controlled/")
.put("Accurate/Field/Water", "Accurate/")
.put("Aggressive/Blunt/Earth", "Aggressive/")
.put("Defensive/Barbed/Fire", "Defensive/")
.put("Tofu", "Tofu")
.put("Crackers", "Crackers")
.put("Worms", "Worms")
.put("Poison worms", "Pois. Worms")
.put("Poison tofu", "Pois. Tofu")
.put("Poison meat", "Pois. Meat")
.put("Red egg", "Red egg")
.put("Green egg", "Green egg")
.put("Blue egg", "Blue egg")
.build();
private static final ImmutableMap<String, Integer> ITEMS = ImmutableMap.<String, Integer>builder()
.put("Tofu", ItemID.TOFU)
.put("Crackers", ItemID.CRACKERS)
.put("Worms", ItemID.WORMS)
.put("Pois. Worms", ItemID.POISONED_WORMS)
.put("Pois. Tofu", ItemID.POISONED_TOFU)
.put("Pois. Meat", ItemID.POISONED_MEAT)
.put("Defensive/", ItemID.BARBED_ARROW)
.put("Aggressive/", ItemID.BLUNT_ARROW)
.put("Accurate/", ItemID.FIELD_ARROW)
.put("Controlled/", ItemID.BULLET_ARROW)
.build();
private static final ImmutableMap<String, String> SPLIT_LISTENS = ImmutableMap.<String, String>builder()
.put("Controlled/", "Bullet/Wind")
.put("Bullet/Wind", "Controlled/")
.put("Accurate/", "Field/Water")
.put("Field/Water", "Accurate/")
.put("Aggressive/", "Blunt/Earth")
.put("Blunt/Earth", "Aggressive/")
.put("Defensive/", "Barbed/Fire")
.put("Barbed/Fire", "Defensive/")
.build();
int getListenItem(String listen)
{
this.listen = listen;
this.call = call;
this.roleText = role;
this.roleSprite = roleSprite;
return ITEMS.getOrDefault(listen, -1);
}
@Override
public String toString()
String getTell(String call)
{
return name();
return TELLS.getOrDefault(call, "");
}
}
String getCall(Client client)
{
// Do not reverse these if statements to be more efficient
// The normal widgets are no longer null/hidden after you
// click one time in the horn, and the values are incorrect
Widget callWidget = client.getWidget(getGloryCall());
if (callWidget != null)
{
return GLORY_CALLS.get(callWidget.getText());
}
callWidget = client.getWidget(getCall());
if (callWidget != null)
{
return callWidget.getText();
}
return null;
}
String getListen(Client client)
{
// See the comment in getCall(Client client), before editing
Widget listenWidget = client.getWidget(getGloryListen());
if (listenWidget != null)
{
return GLORY_CALLS.get(listenWidget.getText());
}
listenWidget = client.getWidget(getListen());
if (listenWidget != null)
{
return listenWidget.getText();
}
return null;
}
static String getMissingListen(String listen)
{
return SPLIT_LISTENS.getOrDefault(listen, "- - -");
}
// I call it "Switchception" :wutwedoin:
// Should probably switch to using an interface instead of an enum at this point
String getCallFromTell(String listen)
{
switch (this)
{
case COLLECTOR:
switch (listen)
{
case "Tell-controlled":
return "Controlled/";
case "Tell-accurate":
return "Accurate/";
case "Tell-aggressive":
return "Aggressive/";
case "Tell-defensive":
return "Defensive/";
}
break;
case ATTACKER:
switch (listen)
{
case "Tell-red":
return "Red egg";
case "Tell-green":
return "Green egg";
case "Tell-blue":
return "Blue egg";
}
break;
case HEALER:
switch (listen)
{
case "Tell-tofu":
return "Tofu";
case "Tell-crackers":
return "Crackers";
case "Tell-worms":
return "Worms";
}
break;
case DEFENDER:
switch (listen)
{
case "Tell-meat":
return "Pois. Meat";
case "Tell-tofu":
return "Pois. Tofu";
case "Tell-worms":
return "Pois. Worms";
}
break;
}
return null;
}
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
* Copyright (c) 2019, https://runelitepl.us
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,18 +27,21 @@ package net.runelite.client.plugins.barbarianassault;
import java.awt.Color;
import java.util.ArrayList;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.events.ChatMessage;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.eventbus.Subscribe;
@Getter
public class Game
public class Scorecard
{
private Client client;
private String currentWave;
private ArrayList<Wave> Waves = new ArrayList<>();
private BarbarianAssaultPlugin game;
@Getter(AccessLevel.NONE)
private ArrayList<Wave> waves = new ArrayList<>();
private String[] totalDescriptions = {
"A: ",
"; D: ",
@@ -55,46 +59,46 @@ public class Game
private int[] totalAmounts = new int[6];
private int[] otherRolesPoints = new int[4];
Game(Client client)
Scorecard(BarbarianAssaultPlugin game)
{
this.client = client;
}
Game(Client client, ArrayList<Wave> waves)
{
this.client = client;
this.Waves = waves;
this.game = game;
}
@Subscribe
public void onChatMessage(ChatMessage chatMessage)
{
if (chatMessage.getMessage().startsWith("---- Wave:"))
if (chatMessage.getMessage().startsWith("---- Points:"))
{
String[] tempMessage = chatMessage.getMessage().split(" ");
currentWave = tempMessage[2];
String[] temp = currentWave.split(" ");
}
if (currentWave.equals("1"))
{
Waves = null;
totalPoints = new int[6];
totalAmounts = new int[6];
if (game.getStage() == 1)
{
totalPoints = new int[6];
totalAmounts = new int[6];
}
}
}
void addWave(Wave wave)
{
this.waves.add(wave);
}
int getNumberOfWaves()
{
return waves.size();
}
ChatMessageBuilder getGameSummary()
{
int[] amountsList;
int[] pointsList;
int[] otherRolesPointsList;
ChatMessageBuilder message = new ChatMessageBuilder();
message.append("Round points: ");
for (Wave w : Waves)
message.append("Game points: ");
for (Wave wave : waves)
{
amountsList = w.getWaveAmounts();
pointsList = w.getWavePoints();
otherRolesPointsList = w.getOtherRolesPointsList();
amountsList = wave.getAmounts();
pointsList = wave.getPoints();
otherRolesPointsList = wave.getOtherRolesPointsList();
for (int j = 0; j < totalAmounts.length; j++)
{
totalAmounts[j] += amountsList[j];

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2019, https://runelitepl.us
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,37 +24,31 @@
*/
package net.runelite.client.plugins.barbarianassault;
import lombok.Getter;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import net.runelite.api.Constants;
class GameTimer
class Timer
{
final private Instant startTime = Instant.now();
private Instant prevWave = startTime;
@Getter
private final Instant startTime;
String getTime(boolean waveTime)
Timer()
{
final Instant now = Instant.now();
final Duration elapsed;
if (waveTime)
{
elapsed = Duration.between(prevWave, now);
}
else
{
elapsed = Duration.between(startTime, now).minusMillis(Constants.GAME_TICK_LENGTH);
}
return formatTime(LocalTime.ofSecondOfDay(elapsed.getSeconds()));
this.startTime = Instant.now();
}
void setWaveStartTime()
long getElapsedTime()
{
prevWave = Instant.now();
return Duration.between(startTime, Instant.now()).getSeconds();
}
String getElapsedTimeFormatted()
{
return formatTime(LocalTime.ofSecondOfDay(getElapsedTime()));
}
private static String formatTime(LocalTime time)

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,50 +25,65 @@
*/
package net.runelite.client.plugins.barbarianassault;
import java.time.Duration;
import java.time.Instant;
import javax.inject.Inject;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.Constants;
import lombok.Data;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.ui.overlay.infobox.InfoBox;
class Round
import java.awt.Color;
import java.awt.image.BufferedImage;
@Data
public class TimerBox extends InfoBox
{
private final Instant roundStartTime;
private int count;
@Getter
private final Role roundRole;
private boolean inSync = true;
@Getter
@Setter
private boolean runnersKilled;
private boolean tooltipEnabled = false;
@Getter
@Setter
private boolean rangersKilled;
@Getter
@Setter
private boolean healersKilled;
@Getter
@Setter
private boolean fightersKilled;
@Inject
public Round(Role role)
TimerBox(BufferedImage image, Plugin plugin, int count)
{
this.roundRole = role;
this.roundStartTime = Instant.now().plusMillis(2 * Constants.GAME_TICK_LENGTH);
super(image, plugin);
this.count = count;
}
public long getRoundTime()
@Override
public String getText()
{
return Duration.between(roundStartTime, Instant.now()).getSeconds();
if (count == -1)
{
return "";
}
return Integer.toString(getCount());
}
long getTimeToChange()
@Override
public Color getTextColor()
{
return 30 + (Duration.between(Instant.now(), roundStartTime).getSeconds() % 30);
if (inSync)
{
return Color.WHITE;
}
else
{
return Color.RED;
}
}
@Override
public String getTooltip()
{
if (!tooltipEnabled)
{
return "";
}
else if (inSync)
{
return "<col=00FF00>Valid";
}
else
{
return "<col=FF0000>Invalid";
}
}
}

View File

@@ -1,5 +1,7 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
* Copyright (c) 2019, https://runelitepl.us
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,90 +27,105 @@
package net.runelite.client.plugins.barbarianassault;
import com.google.common.collect.ImmutableList;
import java.awt.Color;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.chat.ChatMessageBuilder;
@Getter
class Wave
{
private Client client;
private final ImmutableList<WidgetInfo> WIDGETS = ImmutableList.of(
WidgetInfo.BA_FAILED_ATTACKER_ATTACKS,
WidgetInfo.BA_RUNNERS_PASSED,
WidgetInfo.BA_EGGS_COLLECTED,
WidgetInfo.BA_HITPOINTS_REPLENISHED,
WidgetInfo.BA_WRONG_POISON_PACKS,
WidgetInfo.BA_HONOUR_POINTS_REWARD
);
private final ImmutableList<WidgetInfo> POINTSWIDGETS = ImmutableList.of(
//base
WidgetInfo.BA_BASE_POINTS,
//att
WidgetInfo.BA_FAILED_ATTACKER_ATTACKS_POINTS,
WidgetInfo.BA_RANGERS_KILLED,
WidgetInfo.BA_FIGHTERS_KILLED,
//def
WidgetInfo.BA_RUNNERS_PASSED_POINTS,
WidgetInfo.BA_RUNNERS_KILLED,
//coll
WidgetInfo.BA_EGGS_COLLECTED_POINTS,
//heal
WidgetInfo.BA_HEALERS_KILLED,
WidgetInfo.BA_HITPOINTS_REPLENISHED_POINTS,
WidgetInfo.BA_WRONG_POISON_PACKS_POINTS
);
private int[] waveAmounts = new int[6];
private int[] allPointsList = new int[10];
private int[] wavePoints = new int[6];
private int[] otherRolesPointsList = new int[4];
private String[] descriptions = {
" A: ",
"; D: ",
"; C: ",
"; Vial: ",
"; H packs: ",
"; Total: "};
import java.awt.Color;
private String[] otherPointsDescriptions = {
" A: ",
" D: ",
" C: ",
" H: "
};
@Data
public class Wave
{
@Getter(AccessLevel.NONE)
private static final ImmutableList<WidgetInfo> WIDGETS = ImmutableList.of(
WidgetInfo.BA_FAILED_ATTACKER_ATTACKS,
WidgetInfo.BA_RUNNERS_PASSED,
WidgetInfo.BA_EGGS_COLLECTED,
WidgetInfo.BA_HITPOINTS_REPLENISHED,
WidgetInfo.BA_WRONG_POISON_PACKS,
WidgetInfo.BA_HONOUR_POINTS_REWARD
);
@Getter(AccessLevel.NONE)
private static final ImmutableList<WidgetInfo> POINTSWIDGETS = ImmutableList.of(
//Base
WidgetInfo.BA_BASE_POINTS,
//Attacker
WidgetInfo.BA_FAILED_ATTACKER_ATTACKS_POINTS,
WidgetInfo.BA_RANGERS_KILLED,
WidgetInfo.BA_FIGHTERS_KILLED,
//Defender
WidgetInfo.BA_RUNNERS_PASSED_POINTS,
WidgetInfo.BA_RUNNERS_KILLED,
//Collector
WidgetInfo.BA_EGGS_COLLECTED_POINTS,
//Healer
WidgetInfo.BA_HEALERS_KILLED,
WidgetInfo.BA_HITPOINTS_REPLENISHED_POINTS,
WidgetInfo.BA_WRONG_POISON_PACKS_POINTS
);
@Getter(AccessLevel.NONE)
private final Client client;
private final Timer waveTimer;
private boolean runnersKilled;
private boolean rangersKilled;
private boolean healersKilled;
private boolean fightersKilled;
private int collectedEggCount = 0;
private int positiveEggCount = 0;
private int wrongEggs = 0;
private int hpHealed = 0;
private int totalCollectedEggCount = 0;
private int totalHpHealed = 0;
private int[] amounts = new int[6];
private int[] allPointsList = new int[10];
private int[] points = new int[6];
private int[] otherRolesPointsList = new int[4];
private String[] descriptions = {" A: ", "; D: ", "; C: ", "; Vial: ", "; H packs: ", "; Total: "};
private String[] otherPointsDescriptions = {" A: ", " D: ", " C: ", " H: "};
Wave(Client client)
{
this.client = client;
this.waveTimer = new Timer();
}
void setWaveAmounts(int[] amounts)
{
System.arraycopy(amounts, 0, waveAmounts, 0, amounts.length);
}
void setWavePoints(int[] points, int[] otherRolesPoints)
{
System.arraycopy(points, 0, wavePoints, 0, points.length);
System.arraycopy(otherRolesPoints, 0, otherRolesPointsList, 0, otherRolesPoints.length);
}
void setWaveAmounts()
void setAmounts()
{
for (int i = 0; i < WIDGETS.size(); i++)
{
Widget w = client.getWidget(WIDGETS.get(i));
if (w != null)
{
waveAmounts[i] = Integer.parseInt(w.getText());
amounts[i] = Integer.parseInt(w.getText());
}
}
}
void setWavePoints()
void setPoints()
{
for (int i = 0; i < POINTSWIDGETS.size(); i++)
{
@@ -117,26 +134,26 @@ class Wave
switch (i)
{
case 1:
wavePoints[0] += allPointsList[i];
points[0] += allPointsList[i];
break;
case 4:
wavePoints[1] += allPointsList[i];
points[1] += allPointsList[i];
break;
case 6:
wavePoints[2] += allPointsList[i];
points[2] += allPointsList[i];
break;
case 8:
case 9:
wavePoints[3] += allPointsList[i];
points[3] += allPointsList[i];
break;
default:
break;
}
}
wavePoints[5] = 0;
for (int i = 0; i < wavePoints.length - 1; i++)
points[5] = 0;
for (int i = 0; i < points.length - 1; i++)
{
wavePoints[5] += wavePoints[i];
points[5] += points[i];
}
for (int i = 0; i < POINTSWIDGETS.size(); i++)
{
@@ -166,37 +183,35 @@ class Wave
case 9:
otherRolesPointsList[3] += Integer.parseInt(w.getText());
break;
default:
break;
}
}
}
ChatMessageBuilder getWaveSummary()
ChatMessageBuilder getSummary()
{
ChatMessageBuilder message = new ChatMessageBuilder();
message.append("Wave points:");
for (int i = 0; i < descriptions.length; i++)
{
if (i != 4)
message.append(descriptions[i]);
if (i != 5)
{
message.append(descriptions[i]);
message.append(String.valueOf(waveAmounts[i]));
message.append("(");
if (wavePoints[i] < 0)
{
message.append(Color.RED, String.valueOf(wavePoints[i]));
}
else if (wavePoints[i] > 0)
{
message.append(Color.BLUE, String.valueOf(wavePoints[i]));
}
else
{
message.append(String.valueOf(wavePoints[i]));
}
message.append(")");
message.append(String.valueOf(amounts[i]));
}
message.append("(");
if (points[i] < 0)
{
message.append(Color.RED, String.valueOf(points[i]));
}
else if (points[i] > 0)
{
message.append(Color.BLUE, String.valueOf(points[i]));
}
else
{
message.append(String.valueOf(points[i]));
}
message.append(")");
}
message.append(System.getProperty("line.separator"));
message.append("All roles points this wave: ");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

View File

@@ -1,214 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.batools;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("BATools")
public interface BAToolsConfig extends Config
{
@ConfigItem(
keyName = "defTimer",
name = "Defender Tick Timer",
description = "Shows the current cycle tick of runners."
)
default boolean defTimer()
{
return false;
}
@ConfigItem(
keyName = "calls",
name = "Remove Incorrect Calls",
description = "Remove incorrect calls."
)
default boolean calls()
{
return false;
}
@ConfigItem(
keyName = "swapLadder",
name = "Swap ladder option",
description = "Swap Climb-down with Quick-start in the wave lobbies"
)
default boolean swapLadder()
{
return true;
}
@ConfigItem(
keyName = "swapCollectorBag",
name = "swaps collector bag in ba to empty left click",
description = "Make empty the left-click option on collector bag"
)
default boolean swapCollectorBag()
{
return false;
}
@ConfigItem(
keyName = "swapDestroyEggs",
name = "Left click destroy eggs in BA",
description = "Make destroy the left-click option for collector eggs"
)
default boolean swapDestroyEggs()
{
return false;
}
@ConfigItem(
keyName = "healerCodes",
name = "Healer Codes",
description = "Overlay to show healer codes"
)
default boolean healerCodes()
{
return false;
}
@ConfigItem(
keyName = "healerMenuOption",
name = "Healer menu options",
description = "Shows time since last food placed on healer"
)
default boolean healerMenuOption()
{
return false;
}
@ConfigItem(
keyName = "eggBoi",
name = "Collector helper",
description = "Hold shift to collect the correct egg"
)
default boolean eggBoi()
{
return false;
}
@ConfigItem(
keyName = "osHelp",
name = "Shift OS",
description = "Hold shift to only pick up correct eggs"
)
default boolean osHelp()
{
return false;
}
@ConfigItem(
keyName = "prayerMetronome",
name = "Prayer Metronome",
description = "Similar to metronome plugin but only activates when a prayer is active"
)
default boolean prayerMetronome()
{
return false;
}
@ConfigItem(
keyName = "prayerMetronomeVolume",
name = "Prayer Metronome Volume",
description = "Volume level"
)
default int prayerMetronomeVolume()
{
return 1;
}
@ConfigItem(
keyName = "attackStyles",
name = "Attack Styles",
description = "Hide attack styles depending on weapon."
)
default boolean attackStyles()
{
return false;
}
@ConfigItem(
keyName = "removeBA",
name = "*Barbarian Assault Helper*",
description = "Remove unnecessary menu options in Barbarian Assault depending on role<br>Examples: Remove attack options when not attacker<br>Remove take options when not collector"
)
default boolean removeBA()
{
return true;
}
@ConfigItem(
keyName = "removeWrongEggs",
name = "Remove wrong eggs - *Barbarian Assault Helper*",
description = "Remove unnecessary menu options in Barbarian Assault depending on role<br>Examples: Remove attack options when not attacker<br>Remove take options when not collector"
)
default boolean removeWrongEggs()
{
return false;
}
@ConfigItem(
keyName = "removeWrongHealFood",
name = "Remove wrong Heal Food - *Barbarian Assault Helper*",
description = "Remove unnecessary menu options in Barbarian Assault depending on role<br>Examples: Remove attack options when not attacker<br>Remove take options when not collector"
)
default boolean removeHealWrongFood()
{
return false;
}
@ConfigItem(
keyName = "tagging",
name = "Attack Tags",
description = "Highlights the menu entry of an attacker/ranger that has not been tagged."
)
default boolean tagging()
{
return false;
}
@ConfigItem(
keyName = "ctrlHealer",
name = "Control Healer",
description = "Hold ctrl to put last healer clicked on top"
)
default boolean ctrlHealer()
{
return false;
}
@ConfigItem(
keyName = "removePenanceCave",
name = "Remove Block Penance Cave",
description = "Removes unnecessary menu option, however Moon wanted it back"
)
default boolean removePenanceCave()
{
return false;
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.batools;
import java.awt.Color;
import static java.awt.Color.GREEN;
import static java.awt.Color.RED;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.time.Duration;
import java.time.Instant;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
@Slf4j
public class BAToolsOverlay extends Overlay
{
private final BAToolsConfig config;
private BAToolsPlugin plugin;
@Inject
public BAToolsOverlay(BAToolsPlugin plugin, BAToolsConfig config)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE);
this.config = config;
this.plugin = plugin;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!config.healerCodes())
{
return null;
}
for (Healer healer : plugin.getHealers().values())
{
Color color;
int timeLeft = healer.getLastFoodTime() - (int) Duration.between(plugin.getWave_start(), Instant.now()).getSeconds();
timeLeft = timeLeft < 1 ? 0 : timeLeft;
if (healer.getFoodRemaining() > 1)
{
color = GREEN;
}
else if (healer.getFoodRemaining() == 1)
{
if (timeLeft > 0)
{
color = RED;
}
else
{
color = GREEN;
}
}
else
{
continue;
}
String text = String.format("%d %d",
healer.getFoodRemaining(),
timeLeft);
OverlayUtil.renderActorOverlay(graphics, healer.getNpc(), text, color);
}
return null;
}
}

View File

@@ -1,862 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.batools;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Provides;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.ItemID;
import net.runelite.api.MenuEntry;
import net.runelite.api.NPC;
import net.runelite.api.NpcID;
import net.runelite.api.Prayer;
import net.runelite.api.SoundEffectID;
import net.runelite.api.Varbits;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.HitsplatApplied;
import net.runelite.api.events.InteractingChanged;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import static net.runelite.api.widgets.WidgetInfo.BA_ATK_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_ATK_LISTEN_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_ATK_ROLE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_COLL_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_COLL_LISTEN_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_COLL_ROLE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_DEF_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_DEF_ROLE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_HEAL_CALL_TEXT;
import static net.runelite.api.widgets.WidgetInfo.BA_HEAL_LISTEN_TEXT;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_FOUR;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_ONE;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_THREE;
import static net.runelite.api.widgets.WidgetInfo.COMBAT_STYLE_TWO;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.util.Text;
import org.apache.commons.lang3.ArrayUtils;
import net.runelite.client.menus.MenuManager;
@Slf4j
@PluginDescriptor(
name = "BA Tools",
description = "Custom tools for Barbarian Assault",
tags = {"minigame", "overlay", "timer"},
type = PluginType.PVM,
enabledByDefault = false
)
public class BAToolsPlugin extends Plugin implements KeyListener
{
private boolean inGame;
private int tickNum;
private int pastCall = 0;
private int currentWave = 1;
private int lastHealer;
private static final int BA_WAVE_NUM_INDEX = 2;
private static final WorldPoint healerSpawnPoint = new WorldPoint(1898, 1586, 0);
private final List<MenuEntry> entries = new ArrayList<>();
private ImmutableMap<WidgetInfo, Boolean> originalAttackStyles;
private HashMap<Integer, Instant> foodPressed = new HashMap<>();
private CycleCounter counter;
private Actor lastInteracted;
private boolean shiftDown;
private boolean ctrlDown;
@Inject
private Client client;
@Inject
private OverlayManager overlayManager;
@Inject
private BAToolsConfig config;
@Inject
private ItemManager itemManager;
@Inject
private InfoBoxManager infoBoxManager;
@Inject
private BAToolsOverlay overlay;
@Getter
private Map<NPC, Healer> healers;
@Getter
private Instant wave_start;
@Inject
private MenuManager menuManager;
@Inject
private KeyManager keyManager;
@Provides
BAToolsConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(BAToolsConfig.class);
}
@Override
protected void startUp() throws Exception
{
overlayManager.add(overlay);
healers = new HashMap<>();
wave_start = Instant.now();
//lastInteracted = null;
foodPressed.clear();
keyManager.registerKeyListener(this);
}
@Override
protected void shutDown() throws Exception
{
removeCounter();
healers.clear();
inGame = false;
lastInteracted = null;
overlayManager.remove(overlay);
keyManager.unregisterKeyListener(this);
shiftDown = false;
}
@Subscribe
public void onWidgetLoaded(WidgetLoaded event)
{
switch (event.getGroupId())
{
case WidgetID.BA_REWARD_GROUP_ID:
{
Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT);
if (rewardWidget != null && rewardWidget.getText().contains("<br>5"))
{
tickNum = 0;
}
}
}
}
@Subscribe
public void onGameTick(GameTick event)
{
Widget callWidget = getWidget();
if (callWidget != null)
{
if (callWidget.getTextColor() != pastCall && callWidget.getTextColor() == 16316664)
{
tickNum = 0;
}
pastCall = callWidget.getTextColor();
}
if (inGame && config.defTimer())
{
if (tickNum > 9)
{
tickNum = 0;
}
if (counter == null)
{
addCounter();
lastHealer = 0;
}
counter.setCount(tickNum);
tickNum++;
}
Widget weapon = client.getWidget(593, 1);
if (config.attackStyles()
&& weapon != null
&& inGame
&& weapon.getText().contains("Crystal halberd") || weapon.getText().contains("Dragon claws")
&& client.getWidget(BA_ATK_LISTEN_TEXT) != null)
{
if (originalAttackStyles == null)
{
ImmutableMap.Builder<WidgetInfo, Boolean> builder = new ImmutableMap.Builder<>();
builder.put(COMBAT_STYLE_ONE, client.getWidget(COMBAT_STYLE_ONE).isHidden());
builder.put(COMBAT_STYLE_TWO, client.getWidget(COMBAT_STYLE_TWO).isHidden());
builder.put(COMBAT_STYLE_THREE, client.getWidget(COMBAT_STYLE_THREE).isHidden());
builder.put(COMBAT_STYLE_FOUR, client.getWidget(COMBAT_STYLE_FOUR).isHidden());
originalAttackStyles = builder.build();
}
String style = client.getWidget(BA_ATK_LISTEN_TEXT).getText();
if (style.contains("Defensive"))
{
client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
client.getWidget(COMBAT_STYLE_FOUR).setHidden(false);
}
else if (style.contains("Aggressive"))
{
client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
client.getWidget(COMBAT_STYLE_TWO).setHidden(false);
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
}
else if (style.contains("Controlled"))
{
if (weapon.getText().contains("Crystal halberd"))
{
client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
}
else
{
client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
client.getWidget(COMBAT_STYLE_THREE).setHidden(false);
}
client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
}
else if (style.contains("Accurate") && weapon.getText().contains("Dragon claws"))
{
client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
}
else
{
client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
client.getWidget(COMBAT_STYLE_TWO).setHidden(false);
client.getWidget(COMBAT_STYLE_THREE).setHidden(false);
client.getWidget(COMBAT_STYLE_FOUR).setHidden(false);
}
}
else if (originalAttackStyles != null)
{
originalAttackStyles.forEach((w, b) -> client.getWidget(w).setHidden(b));
}
if (config.prayerMetronome() && isAnyPrayerActive())
{
for (int i = 0; i < config.prayerMetronomeVolume(); i++)
{
client.playSoundEffect(SoundEffectID.GE_INCREMENT_PLOP);
}
}
}
private Widget getWidget()
{
if (client.getWidget(BA_DEF_CALL_TEXT) != null)
{
return client.getWidget(BA_DEF_CALL_TEXT);
}
else if (client.getWidget(BA_ATK_CALL_TEXT) != null)
{
return client.getWidget(BA_ATK_CALL_TEXT);
}
else if (client.getWidget(BA_COLL_CALL_TEXT) != null)
{
return client.getWidget(BA_COLL_CALL_TEXT);
}
else if (client.getWidget(BA_HEAL_CALL_TEXT) != null)
{
return client.getWidget(BA_HEAL_CALL_TEXT);
}
return null;
}
@Subscribe
public void onVarbitChanged(VarbitChanged event)
{
int inGameBit = client.getVar(Varbits.IN_GAME_BA);
if (inGameBit == 1 && !inGame ||
inGameBit == 0 && inGame)
{
inGame = inGameBit == 1;
if (!inGame)
{
pastCall = 0;
removeCounter();
foodPressed.clear();
}
else
{
addCounter();
}
}
}
@Subscribe
public void onChatMessage(ChatMessage event)
{
if (event.getType() == ChatMessageType.GAMEMESSAGE
&& event.getMessage().startsWith("---- Wave:"))
{
String[] message = event.getMessage().split(" ");
currentWave = Integer.parseInt(message[BA_WAVE_NUM_INDEX]);
wave_start = Instant.now();
healers.clear();
}
}
@Subscribe
public void onNpcSpawned(NpcSpawned event)
{
NPC npc = event.getNpc();
if (inGame && isNpcHealer(npc.getId()))
{
if (checkNewSpawn(npc) || Duration.between(wave_start, Instant.now()).getSeconds() < 16)
{
int spawnNumber = healers.size();
healers.put(npc, new Healer(npc, spawnNumber, currentWave));
}
}
}
@Subscribe
public void onHitsplatApplied(HitsplatApplied hitsplatApplied)
{
Actor actor = hitsplatApplied.getActor();
if (healers.isEmpty() && !(actor instanceof NPC) && lastInteracted == null)
{
return;
}
for (Healer healer : healers.values())
{
if (healer.getNpc() == actor && actor == lastInteracted)
{
healer.setFoodRemaining(healer.getFoodRemaining() - 1);
}
}
}
@Subscribe
public void onNpcDespawned(NpcDespawned event)
{
healers.remove(event.getNpc());
}
@Subscribe
public void onInteractingChanged(InteractingChanged event)
{
Actor opponent = event.getTarget();
if (opponent instanceof NPC && isNpcHealer(((NPC) opponent).getId()) && event.getSource() != client.getLocalPlayer())
{
lastInteracted = opponent;
}
}
private static boolean isNpcHealer(int npcId)
{
return npcId == NpcID.PENANCE_HEALER ||
npcId == NpcID.PENANCE_HEALER_5766 ||
npcId == NpcID.PENANCE_HEALER_5767 ||
npcId == NpcID.PENANCE_HEALER_5768 ||
npcId == NpcID.PENANCE_HEALER_5769 ||
npcId == NpcID.PENANCE_HEALER_5770 ||
npcId == NpcID.PENANCE_HEALER_5771 ||
npcId == NpcID.PENANCE_HEALER_5772 ||
npcId == NpcID.PENANCE_HEALER_5773 ||
npcId == NpcID.PENANCE_HEALER_5774;
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded event)
{
final int itemId = event.getIdentifier();
String option = Text.removeTags(event.getOption()).toLowerCase();
String target = Text.removeTags(event.getTarget()).toLowerCase();
if (config.swapDestroyEggs() & (target.equals("red egg") || target.equals("green egg") || target.equals("blue egg")))
{
menuManager.addSwap("destroy", option, target);
}
if (config.swapCollectorBag() & target.equals("collection bag"))
{
menuManager.addSwap("empty", option, target);
}
if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder"))
{
menuManager.addSwap("Quick-start", option, target);
}
else if (config.removeBA() && client.getVar(Varbits.IN_GAME_BA) == 1 && !option.contains("tell-"))//if in barbarian assault and menu isnt from a horn
{
if (itemId == ItemID.LOGS && !target.contains("healing vial"))
{
if (client.getWidget(BA_DEF_ROLE_TEXT) == null)
{
remove(new String[]{"take", "light"}, target);
}
else //remove "Light" option (and "Take" option if not defender).
{
remove("light", target);
}
}
else if (option.equals("use"))
{
if (config.removeHealWrongFood())
{
Widget healer = client.getWidget(BA_HEAL_LISTEN_TEXT);
if (healer != null)
{
String item = target.split("-")[0].trim();
List<String> poison = Arrays.asList("poisoned tofu", "poisoned meat", "poisoned worms");
List<String> vials = Arrays.asList("healing vial", "healing vial(1)", "healing vial(2)", "healing vial(3)", "healing vial(4)");//"healing vial(4)"
if (poison.contains(item))
{
//if item is a poison item
int calledPoison = 0;
switch (healer.getText())//choose which poison to hide the use/destroy option for
{
case "Pois. Tofu":
calledPoison = ItemID.POISONED_TOFU;
break;
case "Pois. Meat":
calledPoison = ItemID.POISONED_MEAT;
break;
case "Pois. Worms":
calledPoison = ItemID.POISONED_WORMS;
break;
}
if (target.equals(item))//if targeting the item itself
{
if (calledPoison != 0 && itemId != calledPoison)//if no call or chosen item is not the called one
{
remove(new String[]{"use", "destroy", "examine"}, target);//remove options
}
}
else if (!target.contains("penance healer"))
{
remove(option, target);
}
}
else if (vials.contains(item))//if item is the healer's healing vial
{
if (!target.equals(item))//if target is not the vial itself
{
if (!target.contains("level") || target.contains("penance") || target.contains("queen spawn"))//if someone has "penance" or "queen spawn" in their name, gg...
{
remove(option, target);
}
}
}
}
}
}
else if (option.equals("attack") && client.getWidget(BA_ATK_ROLE_TEXT) == null && !target.equals("queen spawn"))//if not attacker
{
//remove attack option from everything but queen spawns
remove(option, target);
}
else if ((option.equals("fix")) && client.getWidget(WidgetInfo.BA_DEF_ROLE_TEXT) == null)//if not defender
{
remove(option, target);
}
else if ((option.equals("block") && target.equals("penance cave") && config.removePenanceCave()))
{
remove(option, target);
}
else if ((option.equals("load")) && client.getWidget(BA_COLL_ROLE_TEXT) == null)//if not collector, remove hopper options
{
remove(new String[]{option, "look-in"}, target);
}
else if (config.removeWrongEggs() && option.equals("take"))
{
Widget eggToColl = client.getWidget(BA_COLL_LISTEN_TEXT);
if (eggToColl != null)//if we're a collector
{
List<Integer> eggsToHide = new ArrayList<>();
eggsToHide.add(ItemID.HAMMER);
switch (eggToColl.getText())//choose which eggs to hide take option for
{
case "Red eggs":
eggsToHide.add(ItemID.BLUE_EGG);
eggsToHide.add(ItemID.GREEN_EGG);
break;
case "Blue eggs":
eggsToHide.add(ItemID.RED_EGG);
eggsToHide.add(ItemID.GREEN_EGG);
break;
case "Green eggs":
eggsToHide.add(ItemID.RED_EGG);
eggsToHide.add(ItemID.BLUE_EGG);
break;
}
if (eggsToHide.contains(itemId))
{
remove(option, target);//hide wrong eggs
}
}
else
{
List<Integer> defenderItems = Arrays.asList(ItemID.HAMMER, ItemID.TOFU, ItemID.CRACKERS, ItemID.WORMS);//logs are handled separately due to hiding "light" option too.
if (client.getWidget(BA_DEF_ROLE_TEXT) == null || !defenderItems.contains(itemId))//if not defender, or item is not a defenderItem
{
remove(option, target);//hide everything except hammer/logs and bait if Defender
}
}
}
}
if (client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) == getWidget() && lastHealer != 0 && inGame && config.ctrlHealer() && ctrlDown)
{
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry correctHealer = null;
entries.clear();
for (MenuEntry entry : menuEntries)
{
if (( entry.getIdentifier() == lastHealer && entry.getOption().equals("Use"))
||
(
(entry.getTarget().equals("<col=ff9040>Poisoned meat") || entry.getTarget().equals("<col=ff9040>Poisoned worms") || entry.getTarget().equals("<col=ff9040>Poisoned tofu"))
&&
entry.getOption().equals("Use")
)
)
{
correctHealer = entry;
}
else
{
log.info((entry.getIdentifier() == lastHealer && entry.getOption().equals("Use")) + " " + ((entry.getTarget().equals("<col=ff9040>Poisoned meat") || entry.getTarget().equals("<col=ff9040>Poisoned worms") || entry.getTarget().equals("<col=ff9040>Poisoned tofu")) && entry.getOption().equals("Use")) );
}
}
if (correctHealer != null)
{
entries.add(correctHealer);
}
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
}
if ((event.getTarget().contains("Penance Healer") || event.getTarget().contains("Penance Fighter") || event.getTarget().contains("Penance Ranger")))
{
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
String targett = lastEntry.getTarget();
if (foodPressed.containsKey(lastEntry.getIdentifier()))
{
lastEntry.setTarget(lastEntry.getTarget().split("\\(")[0] + "(" + Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() + ")");
if (Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() > 20)
{
lastEntry.setTarget(lastEntry.getTarget().replace("<col=ffff00>", "<col=2bff63>"));
}
}
else
{
lastEntry.setTarget(targett.replace("<col=ffff00>", "<col=2bff63>"));
}
client.setMenuEntries(menuEntries);
}
if (client.getWidget(BA_COLL_LISTEN_TEXT) != null && inGame && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown)
{
String[] currentCall = client.getWidget(BA_COLL_LISTEN_TEXT).getText().split(" ");
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry correctEgg = null;
entries.clear();
for (MenuEntry entry : menuEntries)
{
if (entry.getTarget().contains(currentCall[0]) && entry.getOption().equals("Take"))
{
correctEgg = entry;
}
else if (!entry.getOption().startsWith("Take"))
{
entries.add(entry);
}
}
if (correctEgg != null)
{
entries.add(correctEgg);
}
client.setMenuEntries(entries.toArray(new MenuEntry[0]));
}
if (client.getWidget(WidgetInfo.BA_ATK_LISTEN_TEXT) != null && inGame && config.attackStyles() && shiftDown)
{
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry correctEgg = null;
entries.clear();
for (MenuEntry entry : menuEntries)
{
if (entry.getOption().contains("Walk here"))
{
entries.add(entry);
}
}
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
}
if (client.getWidget(BA_HEAL_LISTEN_TEXT) != null && inGame && config.osHelp() && event.getTarget().equals("<col=ffff>Healer item machine") && shiftDown)
{
String[] currentCall = client.getWidget(BA_HEAL_LISTEN_TEXT).getText().split(" ");
if (!currentCall[0].contains("Pois."))
{
return;
}
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry correctEgg = null;
entries.clear();
for (MenuEntry entry : menuEntries)
{
if (entry.getOption().equals("Take-" + currentCall[1]))
{
correctEgg = entry;
}
}
if (correctEgg != null)
{
entries.add(correctEgg);
client.setMenuEntries(entries.toArray(new MenuEntry[0]));
}
}
}
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
String target = event.getTarget();
if (config.tagging() && (event.getTarget().contains("Penance Ranger") || event.getTarget().contains("Penance Fighter")))
{
if (event.getOption().contains("Attack"))
{
foodPressed.put(event.getIdentifier(), Instant.now());
}
log.info(target);
}
if (config.healerMenuOption() && target.contains("Penance Healer") && target.contains("<col=ff9040>Poisoned") && target.contains("->"))
{
foodPressed.put(event.getIdentifier(), Instant.now());
lastHealer = event.getIdentifier();
log.info("Last healer changed: " + lastHealer);
}
}
public void onConfigChanged(ConfigChanged event)
{
if (counter != null && !config.defTimer())
{
removeCounter();
}
}
private void addCounter()
{
if (!config.defTimer() || counter != null)
{
return;
}
int itemSpriteId = ItemID.FIGHTER_TORSO;
BufferedImage taskImg = itemManager.getImage(itemSpriteId);
counter = new CycleCounter(taskImg, this, tickNum);
infoBoxManager.addInfoBox(counter);
}
private void removeCounter()
{
if (counter == null)
{
return;
}
infoBoxManager.removeInfoBox(counter);
counter = null;
}
private void remove(String option, String target)
{
MenuEntry[] entries = client.getMenuEntries();
int idx = searchIndex(entries, option, target);
if (idx >= 0 && entries[idx] != null)
{
entries = ArrayUtils.removeElement(entries, entries[idx]);
client.setMenuEntries(entries);
}
}
private void remove(String[] options, String target)
{
MenuEntry[] entries = client.getMenuEntries();
for (String option : options)
{
int idx = searchIndex(entries, option, target);
if (idx >= 0 && entries[idx] != null)
{
entries = ArrayUtils.removeElement(entries, entries[idx]);
}
}
client.setMenuEntries(entries);
}
private int searchIndex(MenuEntry[] entries, String option, String target)
{
for (int i = entries.length - 1; i >= 0; i--)
{
MenuEntry entry = entries[i];
String entryOption = Text.removeTags(entry.getOption()).toLowerCase();
String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase();
if (entryOption.equals(option) && entryTarget.equals(target))
{
return i;
}
}
return -1;
}
private boolean checkNewSpawn(NPC npc)
{
for (WorldPoint p : WorldPoint.toLocalInstance(client, healerSpawnPoint))
{
if (p.distanceTo(npc.getWorldLocation()) < 5)
{
return true;
}
}
return false;
}
@Override
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
{
shiftDown = true;
}
if (e.getKeyCode() == KeyEvent.VK_CONTROL)
{
ctrlDown = true;
}
}
@Override
public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
{
shiftDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_CONTROL)
{
ctrlDown = false;
}
}
private boolean isAnyPrayerActive()
{
for (Prayer pray : Prayer.values())//Check if any prayers are active
{
if (client.isPrayerActive(pray))
{
return true;
}
}
return false;
}
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.batools;
import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
@Getter
public enum Calls
{
//Attacker Calls
RED_EGG("Red egg", "Tell-red"),
GREEN_EGG("Green egg", "Tell-green"),
BLUE_EGG("Blue egg", "Tell-blue"),
//Collector Calls
CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"),
ACCURATE("Accurate/Field/Water", "Tell-accurate"),
AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"),
DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"),
//Healer Calls
TOFU("Tofu", "Tell-tofu"),
CRACKERS("Crackers", "Tell-crackers"),
WORMS("Worms", "Tell-worms"),
//Defender Calls
POIS_WORMS("Pois. Worms", "Tell-worms"),
POIS_TOFU("Pois. Tofu", "Tell-tofu"),
POIS_MEAT("Pois. Meat", "Tell-meat");
private final String call;
private final String option;
private static final Map<String, String> CALL_MENU = new HashMap<>();
static
{
for (Calls s : values())
{
CALL_MENU.put(s.getCall(), s.getOption());
}
}
Calls(String call, String option)
{
this.call = call;
this.option = option;
}
public static String getOption(String call)
{
return CALL_MENU.get(call);
}
}

View File

@@ -1,102 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.batools;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.NPC;
class Healer
{
@Getter
private NPC npc;
@Getter
@Setter
private int wave;
@Getter
@Setter
private int spawnNumber;
@Getter
@Setter
private int foodRemaining;
@Getter
@Setter
private int lastFoodTime;
@Getter
@Setter
private int firstCallFood;
@Getter
@Setter
private int secondCallFood;
Healer(NPC npc, int spawnNumber, int wave)
{
this.npc = npc;
this.wave = wave;
this.spawnNumber = spawnNumber;
this.firstCallFood = getCode(wave).getFirstCallFood()[spawnNumber];
this.secondCallFood = getCode(wave).getSecondCallFood()[spawnNumber];
this.foodRemaining = firstCallFood + secondCallFood;
this.lastFoodTime = getCode(wave).getSpacing()[spawnNumber];
}
private HealerCode getCode(int wave)
{
switch (wave)
{
case 1:
return HealerCode.WAVEONE;
case 2:
return HealerCode.WAVETWO;
case 3:
return HealerCode.WAVETHREE;
case 4:
return HealerCode.WAVEFOUR;
case 5:
return HealerCode.WAVEFIVE;
case 6:
return HealerCode.WAVESIX;
case 7:
return HealerCode.WAVESEVEN;
case 8:
return HealerCode.WAVEEIGHT;
case 9:
return HealerCode.WAVENINE;
case 10:
return HealerCode.WAVETEN;
default:
return null;
}
}
}

View File

@@ -1,58 +0,0 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* 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.batools;
import lombok.Getter;
enum HealerCode
{
WAVEONE(new int[]{1, 1}, new int[]{0, 0}, new int[]{0, 0}),
WAVETWO(new int[]{1, 1, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 21}),
WAVETHREE(new int[]{1, 6, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 0}),
WAVEFOUR(new int[]{2, 5, 2, 0}, new int[]{0, 0, 7, 10}, new int[]{0, 0, 0, 0}),
WAVEFIVE(new int[]{2, 5, 2, 3, 0}, new int[]{0, 0, 0, 0, 7}, new int[]{0, 0, 21, 30, 0}),
WAVESIX(new int[]{3, 5, 2, 2, 0, 0}, new int[]{0, 0, 0, 2, 9, 10}, new int[]{12, 18, 21, 0, 0, 0}),
WAVESEVEN(new int[]{3, 7, 1, 1, 0, 0, 0}, new int[]{2, 0, 1, 1, 2, 4, 10}, new int[]{0, 21, 0, 0, 30, 45, 0}),
WAVEEIGHT(new int[]{1, 9, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 2, 10}, new int[]{0, 0, 0, 0, 33, 42, 0}),
WAVENINE(new int[]{2, 8, 1, 1, 0, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 1, 1, 10}, new int[]{0, 21, 0, 0, 0, 0, 0, 0, 0}),
WAVETEN(new int[]{2, 5, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 4, 4, 8}, new int[]{21, 33, 0, 33, 30, 45, 0});
@Getter
private final int[] firstCallFood;
@Getter
private final int[] secondCallFood;
@Getter
private final int[] spacing;
HealerCode(int[] firstCallFood, int[] secondCallFood, int[] spacing)
{
this.firstCallFood = firstCallFood;
this.secondCallFood = secondCallFood;
this.spacing = spacing;
}
}

View File

@@ -30,6 +30,7 @@ import java.awt.Graphics2D;
import java.awt.Polygon;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.EquipmentInventorySlot;
@@ -214,6 +215,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
}
private final String text;
@Nullable
private final STASHUnit stashUnit;
private final WorldPoint location;
private final Emote firstEmote;
@@ -256,15 +258,19 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
if (itemRequirements.length > 0)
{
Client client = plugin.getClient();
client.runScript(ScriptID.WATSON_STASH_UNIT_CHECK, stashUnit.getObjectId(), 0, 0, 0);
int[] intStack = client.getIntStack();
boolean stashUnitBuilt = intStack[0] == 1;
panelComponent.getChildren().add(LineComponent.builder()
.left("STASH Unit:")
.right(stashUnitBuilt ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X)
.rightColor(stashUnitBuilt ? Color.GREEN : Color.RED)
.build());
if (stashUnit != null)
{
client.runScript(ScriptID.WATSON_STASH_UNIT_CHECK, stashUnit.getObjectId(), 0, 0, 0);
int[] intStack = client.getIntStack();
boolean stashUnitBuilt = intStack[0] == 1;
panelComponent.getChildren().add(LineComponent.builder()
.left("STASH Unit:")
.right(stashUnitBuilt ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X)
.rightColor(stashUnitBuilt ? Color.GREEN : Color.RED)
.build());
}
panelComponent.getChildren().add(LineComponent.builder().left("Equip:").build());
@@ -312,18 +318,21 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localPoint, plugin.getEmoteImage(), Color.ORANGE);
}
final WorldPoint[] worldPoints = stashUnit.getWorldPoints();
for (final WorldPoint worldPoint : worldPoints)
if (stashUnit != null)
{
final LocalPoint stashUnitLocalPoint = LocalPoint.fromWorld(plugin.getClient(), worldPoint);
final WorldPoint[] worldPoints = stashUnit.getWorldPoints();
if (stashUnitLocalPoint != null)
for (final WorldPoint worldPoint : worldPoints)
{
final Polygon poly = Perspective.getCanvasTilePoly(plugin.getClient(), stashUnitLocalPoint);
if (poly != null)
final LocalPoint stashUnitLocalPoint = LocalPoint.fromWorld(plugin.getClient(), worldPoint);
if (stashUnitLocalPoint != null)
{
OverlayUtil.renderPolygon(graphics, poly, Color.RED);
final Polygon poly = Perspective.getCanvasTilePoly(plugin.getClient(), stashUnitLocalPoint);
if (poly != null)
{
OverlayUtil.renderPolygon(graphics, poly, Color.RED);
}
}
}
}

View File

@@ -79,7 +79,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl
{
private static final List<FaloTheBardClue> CLUES = ImmutableList.of(
new FaloTheBardClue("A blood red weapon, a strong curved sword, found on the island of primate lords.", item(DRAGON_SCIMITAR)),
new FaloTheBardClue("A book that preaches of some great figure, lending strength, might, and vigour.", any("Any god book (must be complete)", item(HOLY_BOOK), item(BOOK_OF_BALANCE), item(UNHOLY_BOOK), item(BOOK_OF_LAW), item(BOOK_OF_WAR), item(BOOK_OF_DARKNESS))),
new FaloTheBardClue("A book that preaches of some great figure, lending strength, might and vigour.", any("Any god book (must be complete)", item(HOLY_BOOK), item(BOOK_OF_BALANCE), item(UNHOLY_BOOK), item(BOOK_OF_LAW), item(BOOK_OF_WAR), item(BOOK_OF_DARKNESS))),
new FaloTheBardClue("A bow of elven craft was made, it shimmers bright, but will soon fade.", any("Crystal Bow", range(NEW_CRYSTAL_BOW, CRYSTAL_BOW_110), range(NEW_CRYSTAL_BOW_I, CRYSTAL_BOW_110_I))),
new FaloTheBardClue("A fiery axe of great inferno, when you use it, you'll wonder where the logs go.", item(INFERNAL_AXE)),
new FaloTheBardClue("A mark used to increase one's grace, found atop a seer's place.", item(MARK_OF_GRACE)),
@@ -88,7 +88,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl
// The wiki doesn't specify whether the trimmed dragon defender will work so I've assumed that it doesn't
new FaloTheBardClue("A sword held in the other hand, red its colour, Cyclops strength you must withstand.", item(DRAGON_DEFENDER)),
new FaloTheBardClue("A token used to kill mythical beasts, in hopes of a blade or just for an xp feast.", item(WARRIOR_GUILD_TOKEN)),
new FaloTheBardClue("Green is my favorite, mature ale I do love, this takes your herblore above.", item(GREENMANS_ALEM)),
new FaloTheBardClue("Green is my favourite, mature ale I do love, this takes your herblore above.", item(GREENMANS_ALEM)),
new FaloTheBardClue("It can hold down a boat or crush a goat, this object, you see, is quite heavy.", item(BARRELCHEST_ANCHOR)),
new FaloTheBardClue("It comes from the ground, underneath the snowy plain. Trolls aplenty, with what looks like a mane.", item(BASALT)),
new FaloTheBardClue("No attack to wield, only strength is required, made of obsidian, but with no room for a shield.", item(TZHAARKETOM)),

View File

@@ -633,6 +633,26 @@ public class ConfigPanel extends PluginPanel
{
show = Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName()));
}
else if (cid2.getType().isEnum())
{
Class<? extends Enum> type = (Class<? extends Enum>) cid2.getType();
try
{
Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName()));
if (!cid.getItem().unhideValue().equals(""))
{
show = selectedItem.toString().equals(cid.getItem().unhideValue());
}
else if (!cid.getItem().hideValue().equals(""))
{
show = !selectedItem.toString().equals(cid.getItem().hideValue());
}
}
catch (IllegalArgumentException ex)
{
log.info("So bad, so sad: {}", ex.toString());
}
}
}
if (show)
@@ -817,7 +837,7 @@ public class ConfigPanel extends PluginPanel
}
}
});
if (cid.getItem().parse())
{
JLabel parsingLabel = new JLabel();
@@ -1067,8 +1087,8 @@ public class ConfigPanel extends PluginPanel
.splitToList(String.format("%s || %s", cid2.getItem().unhide(), cid2.getItem().hide()));
if (itemHide.contains(cid.getItem().keyName()))
{ // If another options visibility changes depending on the value of this checkbox, then render the entire menu again
{
// If another options visibility changes depending on the value of this checkbox, then render the entire menu again
reloadPluginlist(listItem, config, cd);
}
}
@@ -1107,6 +1127,36 @@ public class ConfigPanel extends PluginPanel
{
JComboBox jComboBox = (JComboBox) component;
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), ((Enum) jComboBox.getSelectedItem()).name());
for (ConfigItemDescriptor cid2 : cd.getItems())
{
if (cid2.getItem().hidden() || !cid2.getItem().hide().isEmpty())
{
List<String> itemHide = Splitter
.onPattern("\\|\\|")
.trimResults()
.omitEmptyStrings()
.splitToList(String.format("%s || %s", cid2.getItem().unhide(), cid2.getItem().hide()));
if (itemHide.contains(cid.getItem().keyName()))
{
reloadPluginlist(listItem, config, cd);
}
String changedVal = ((Enum) jComboBox.getSelectedItem()).name();
if (cid2.getItem().enabledBy().contains(cid.getItem().keyName()) && cid2.getItem().enabledByValue().equals(changedVal))
{
configManager.setConfiguration(cd.getGroup().value(), cid2.getItem().keyName(), "true");
reloadPluginlist(listItem, config, cd);
}
else if (cid2.getItem().disabledBy().contains(cid.getItem().keyName()) && cid2.getItem().disabledByValue().equals(changedVal))
{
configManager.setConfiguration(cd.getGroup().value(), cid2.getItem().keyName(), "false");
reloadPluginlist(listItem, config, cd);
}
}
}
}
else if (component instanceof HotkeyButton)
{
@@ -1223,4 +1273,4 @@ public class ConfigPanel extends PluginPanel
{
openGroupConfigPanel(listItem, config, cd, true);
}
}
}

View File

@@ -172,7 +172,8 @@ public class CookingPlugin extends Plugin
session.increaseCookAmount();
}
else if (message.startsWith("You accidentally burn"))
else if (message.startsWith("You accidentally burn")
|| message.startsWith("You accidentally spoil"))
{
if (session == null)
{

View File

@@ -43,10 +43,8 @@ import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.components.ComponentConstants;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
import net.runelite.client.ui.overlay.components.table.TableAlignment;
import net.runelite.client.ui.overlay.components.table.TableComponent;
import net.runelite.client.util.ColorUtil;
class CorpDamageOverlay extends Overlay
{
@@ -93,9 +91,6 @@ class CorpDamageOverlay extends Overlay
panelComponent.getChildren().clear();
TableComponent tableComponent = new TableComponent();
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
NPC core = corpPlugin.getCore();
if (core != null)
{
@@ -119,14 +114,25 @@ class CorpDamageOverlay extends Overlay
int textWidth = Math.max(ComponentConstants.STANDARD_WIDTH, fontMetrics.stringWidth(text));
panelComponent.setPreferredSize(new Dimension(textWidth, 0));
tableComponent.addRow(ColorUtil.prependColorTag(text, Color.RED), "");
panelComponent.getChildren().add(LineComponent.builder()
.left(text)
.leftColor(Color.RED)
.build());
}
}
if (config.showDamage())
{
tableComponent.addRow("Your damage", ColorUtil.prependColorTag(Integer.toString(myDamage), damageForKill > 0 && myDamage >= damageForKill ? Color.GREEN : Color.RED));
tableComponent.addRow("Total damage:", Integer.toString(totalDamage));
panelComponent.getChildren().add(LineComponent.builder()
.left("Your damage")
.right(Integer.toString(myDamage))
.rightColor(damageForKill > 0 && myDamage >= damageForKill ? Color.GREEN : Color.RED)
.build());
panelComponent.getChildren().add(LineComponent.builder()
.left("Total damage")
.right(Integer.toString(totalDamage))
.build());
}
return panelComponent.render(graphics);

View File

@@ -206,7 +206,7 @@ public class CoxOverlay extends Overlay
if (plugin.isHandCripple())
{
int tick = plugin.getTimer();
int tick = plugin.getCrippleTimer();
NPC olmHand = plugin.getHand();
final String tickStr = String.valueOf(tick);
Point canvasPoint = olmHand.getCanvasTextLocation(graphics, tickStr, 50);

View File

@@ -132,7 +132,7 @@ public class CoxPlugin extends Plugin
@Getter(AccessLevel.PACKAGE)
private Actor acidTarget;
@Getter(AccessLevel.PACKAGE)
private int timer = 45;
private int crippleTimer = 45;
@Getter(AccessLevel.PACKAGE)
private int burnTicks = 41;
@Getter(AccessLevel.PACKAGE)
@@ -172,7 +172,7 @@ public class CoxPlugin extends Plugin
Olm_TP.clear();
prayAgainstOlm = null;
burnTarget.clear();
timer = 45;
crippleTimer = 45;
burnTicks = 40;
acidTicks = 25;
teleportTicks = 10;
@@ -225,6 +225,7 @@ public class CoxPlugin extends Plugin
OlmPhase = 0;
runOlm = true;
needOlm = true;
crippleTimer = 45;
Olm_NextSpec = -1;
break;
case "the great olm fires a sphere of aggression your way. your prayers have been sapped.":
@@ -251,6 +252,8 @@ public class CoxPlugin extends Plugin
prayAgainstOlm = PrayAgainst.RANGED;
lastPrayTime = System.currentTimeMillis();
break;
case "the great olm's left claw clenches to protect itself temporarily.":
HandCripple = true;
}
}
@@ -450,11 +453,11 @@ public class CoxPlugin extends Plugin
if (HandCripple)
{
timer--;
if (timer <= 0)
crippleTimer--;
if (crippleTimer <= 0)
{
HandCripple = false;
timer = 45;
crippleTimer = 45;
}
}

View File

@@ -133,6 +133,8 @@ class DevToolsPanel extends PluginPanel
}
});
container.add(plugin.getSoundEffects());
return container;
}
}

View File

@@ -100,6 +100,9 @@ public class DevToolsPlugin extends Plugin
@Inject
private WorldMapRegionOverlay mapRegionOverlay;
@Inject
private SoundEffectOverlay soundEffectOverlay;
@Inject
private EventBus eventBus;
@@ -128,6 +131,7 @@ public class DevToolsPlugin extends Plugin
private DevToolsButton widgetInspector;
private DevToolsButton varInspector;
private DevToolsButton logMenuActions;
private DevToolsButton soundEffects;
private NavigationButton navButton;
@Provides
@@ -154,30 +158,35 @@ public class DevToolsPlugin extends Plugin
location = new DevToolsButton("Location");
worldMapLocation = new DevToolsButton("World Map Location");
tileLocation = new DevToolsButton("Tile Location");
cursorPos = new DevToolsButton("Cursor Position");
cameraPosition = new DevToolsButton("Camera Position");
chunkBorders = new DevToolsButton("Chunk Borders");
mapSquares = new DevToolsButton("Map Squares");
mapSquares = new DevToolsButton("Map Squares");
lineOfSight = new DevToolsButton("Line Of Sight");
validMovement = new DevToolsButton("Valid Movement");
interacting = new DevToolsButton("Interacting");
examine = new DevToolsButton("Examine");
examine = new DevToolsButton("Examine");
detachedCamera = new DevToolsButton("Detached Camera");
widgetInspector = new DevToolsButton("Widget Inspector");
varInspector = new DevToolsButton("Var Inspector");
soundEffects = new DevToolsButton("Sound Effects");
logMenuActions = new DevToolsButton("Menu Actions");
overlayManager.add(overlay);
overlayManager.add(locationOverlay);
overlayManager.add(sceneOverlay);
overlayManager.add(cameraOverlay);
overlayManager.add(worldMapLocationOverlay);
overlayManager.add(mapRegionOverlay);
logMenuActions = new DevToolsButton("Menu Actions");
overlayManager.add(soundEffectOverlay);
final DevToolsPanel panel = injector.getInstance(DevToolsPanel.class);
@@ -191,17 +200,21 @@ public class DevToolsPlugin extends Plugin
.build();
clientToolbar.addNavigation(navButton);
eventBus.register(soundEffectOverlay);
}
@Override
protected void shutDown() throws Exception
{
eventBus.unregister(soundEffectOverlay);
overlayManager.remove(overlay);
overlayManager.remove(locationOverlay);
overlayManager.remove(sceneOverlay);
overlayManager.remove(cameraOverlay);
overlayManager.remove(worldMapLocationOverlay);
overlayManager.remove(mapRegionOverlay);
overlayManager.remove(soundEffectOverlay);
clientToolbar.removeNavigation(navButton);
}
@@ -341,6 +354,12 @@ public class DevToolsPlugin extends Plugin
player.getPlayerAppearance().setHash();
break;
}
case "sound":
{
int id = Integer.parseInt(args[0]);
client.playSoundEffect(id);
break;
}
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2018, WooxSolo <https://github.com/WooxSolo>
* 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.devtools;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Player;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.events.AreaSoundEffectPlayed;
import net.runelite.api.events.SoundEffectPlayed;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
class SoundEffectOverlay extends Overlay
{
private final static int MAX_LINES = 16;
private final static Color COLOR_SOUND_EFFECT = Color.WHITE;
private final static Color COLOR_AREA_SOUND_EFFECT = Color.YELLOW;
private final static Color COLOR_SILENT_SOUND_EFFECT = Color.GRAY;
private final Client client;
private final DevToolsPlugin plugin;
private final PanelComponent panelComponent = new PanelComponent();
@Inject
SoundEffectOverlay(Client client, DevToolsPlugin plugin)
{
this.client = client;
this.plugin = plugin;
panelComponent.setPreferredSize(new Dimension(200, 0));
panelComponent.getChildren().add(LineComponent.builder()
.left("Sound Effects")
.leftColor(Color.CYAN)
.build());
setPosition(OverlayPosition.TOP_LEFT);
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!plugin.getSoundEffects().isActive())
{
return null;
}
return panelComponent.render(graphics);
}
@Subscribe
public void onSoundEffectPlayed(SoundEffectPlayed event)
{
if (!plugin.getSoundEffects().isActive())
{
return;
}
String text =
"Id: " + event.getSoundId() +
" - D: " + event.getDelay();
panelComponent.getChildren().add(LineComponent.builder()
.left(text)
.leftColor(COLOR_SOUND_EFFECT)
.build());
checkMaxLines();
}
@Subscribe
public void onAreaSoundEffectPlayed(AreaSoundEffectPlayed event)
{
if (!plugin.getSoundEffects().isActive())
{
return;
}
Color textColor = COLOR_AREA_SOUND_EFFECT;
// Check if the player is within range to hear the sound
Player localPlayer = client.getLocalPlayer();
if (localPlayer != null)
{
LocalPoint lp = localPlayer.getLocalLocation();
if (lp != null)
{
int sceneX = lp.getSceneX();
int sceneY = lp.getSceneY();
int distance = Math.abs(sceneX - event.getSceneX()) + Math.abs(sceneY - event.getSceneY());
if (distance > event.getRange())
{
textColor = COLOR_SILENT_SOUND_EFFECT;
}
}
}
String text =
"Id: " + event.getSoundId() +
" - L: " + event.getSceneX() + "," + event.getSceneY() +
" - R: " + event.getRange() +
" - D: " + event.getDelay();
panelComponent.getChildren().add(LineComponent.builder()
.left(text)
.leftColor(textColor)
.build());
checkMaxLines();
}
private void checkMaxLines()
{
while (panelComponent.getChildren().size() > MAX_LINES)
{
panelComponent.getChildren().remove(1);
}
}
}

View File

@@ -88,7 +88,6 @@ public class WidgetField<T>
}
else
{
setter.accept(widget, (T) value);
log.warn("Type {} is not supported for editing", type);
}
setter.accept(widget, (T) value);

View File

@@ -47,7 +47,7 @@ class WorldMapRegionOverlay extends Overlay
private static final int LABEL_PADDING = 4;
private static final int REGION_SIZE = 1 << 6;
// Bitmask to return first coordinate in region
private static final int REGION_TRUNCATE = -(1 << 6);
private static final int REGION_TRUNCATE = ~((1 << 6) - 1);
private final Client client;
private final DevToolsPlugin plugin;

View File

@@ -1,135 +0,0 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Abexlry <abexlry@gmail.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.entertochat;
import com.google.common.base.Strings;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.VarClientStr;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.MouseAdapter;
class EnterToChatListener extends MouseAdapter implements KeyListener
{
@Inject
private EnterToChatPlugin plugin;
@Inject
private Client client;
@Inject
private ClientThread clientThread;
private final Map<Integer, Integer> modified = new HashMap<>();
@Override
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyPressed(KeyEvent e)
{
if (client.getGameState() != GameState.LOGGED_IN || !plugin.chatboxFocused())
{
return;
}
if (!plugin.isTyping())
{
switch (e.getKeyCode())
{
case KeyEvent.VK_ENTER:
case KeyEvent.VK_SLASH:
case KeyEvent.VK_COLON:
// refocus chatbox
plugin.setTyping(true);
clientThread.invoke(() ->
{
plugin.unlockChat();
});
break;
}
}
else
{
switch (e.getKeyCode())
{
case KeyEvent.VK_ENTER:
plugin.setTyping(false);
clientThread.invoke(() ->
{
plugin.lockChat();
});
break;
case KeyEvent.VK_ESCAPE:
plugin.setTyping(false);
clientThread.invoke(() ->
{
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
plugin.lockChat();
});
break;
case KeyEvent.VK_BACK_SPACE:
if (Strings.isNullOrEmpty(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)))
{
plugin.setTyping(false);
clientThread.invoke(() -> plugin.lockChat());
}
}
}
}
@Override
public void keyReleased(KeyEvent e)
{
if (client.getGameState() != GameState.LOGGED_IN)
{
return;
}
if (plugin.chatboxFocused() && !plugin.isTyping())
{
modified.remove(e.getKeyCode());
}
else
{
// press d + enter + release d - causes the right arrow to never be released
Integer m = modified.get(e.getKeyCode());
if (m != null)
{
modified.remove(e.getKeyCode());
e.setKeyCode(m);
}
}
}
}

View File

@@ -1,207 +0,0 @@
/*'
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Abexlry <abexlry@gmail.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.entertochat;
import java.awt.Color;
import javax.inject.Inject;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.IconID;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr;
import net.runelite.api.Varbits;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
@PluginDescriptor(
name = "Press Enter to Chat",
description = "'Press Enter to Chat'",
tags = {"enter", "chat"},
type = PluginType.UTILITY,
enabledByDefault = false
)
public class EnterToChatPlugin extends Plugin
{
private static final String PRESS_ENTER_TO_CHAT = "Press Enter to Chat...";
private static final String SCRIPT_EVENT_SET_CHATBOX_INPUT = "setChatboxInput";
private static final String SCRIPT_EVENT_BLOCK_CHAT_INPUT = "blockChatInput";
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private ConfigManager configManager;
@Inject
private KeyManager keyManager;
@Inject
private EnterToChatListener inputListener;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private boolean typing;
@Override
protected void startUp() throws Exception
{
configManager.setConfiguration("runelite", "wasdcameraplugin", false);
typing = false;
keyManager.registerKeyListener(inputListener);
clientThread.invoke(() ->
{
if (client.getGameState() == GameState.LOGGED_IN)
{
lockChat();
}
});
}
@Override
protected void shutDown() throws Exception
{
clientThread.invoke(() ->
{
if (client.getGameState() == GameState.LOGGED_IN)
{
unlockChat();
}
});
keyManager.unregisterKeyListener(inputListener);
}
boolean chatboxFocused()
{
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
if (chatboxParent == null || chatboxParent.getOnKeyListener() == null)
{
return false;
}
// the search box on the world map can be focused, and chat input goes there, even
// though the chatbox still has its key listener.
Widget worldMapSearch = client.getWidget(WidgetInfo.WORLD_MAP_SEARCH);
return worldMapSearch == null || client.getVar(VarClientInt.WORLD_MAP_SEARCH_FOCUSED) != 1;
}
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
{
switch (scriptCallbackEvent.getEventName())
{
case SCRIPT_EVENT_SET_CHATBOX_INPUT:
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null)
{
if (chatboxFocused() && !typing)
{
chatboxInput.setText(PRESS_ENTER_TO_CHAT);
}
}
break;
case SCRIPT_EVENT_BLOCK_CHAT_INPUT:
if (!typing)
{
int[] intStack = client.getIntStack();
int intStackSize = client.getIntStackSize();
intStack[intStackSize - 1] = 1;
}
break;
}
}
void lockChat()
{
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
if (chatboxParent != null && chatboxParent.getOnKeyListener() != null)
{
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null)
{
chatboxInput.setText(PRESS_ENTER_TO_CHAT);
}
}
}
void unlockChat()
{
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
if (chatboxParent != null)
{
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null)
{
if (client.getGameState() == GameState.LOGGED_IN)
{
final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1;
final Color textColor = isChatboxTransparent ? JagexColors.CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND : JagexColors.CHAT_TYPED_TEXT_OPAQUE_BACKGROUND;
chatboxInput.setText(getPlayerNameWithIcon() + ": " + ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor));
}
}
}
}
private String getPlayerNameWithIcon()
{
IconID icon;
switch (client.getAccountType())
{
case IRONMAN:
icon = IconID.IRONMAN;
break;
case ULTIMATE_IRONMAN:
icon = IconID.ULTIMATE_IRONMAN;
break;
case HARDCORE_IRONMAN:
icon = IconID.HARDCORE_IRONMAN;
break;
default:
return client.getLocalPlayer().getName();
}
return icon + client.getLocalPlayer().getName();
}
}

View File

@@ -82,6 +82,9 @@ import static net.runelite.api.NpcID.FISHING_SPOT_7733;
import static net.runelite.api.NpcID.FISHING_SPOT_7946;
import static net.runelite.api.NpcID.FISHING_SPOT_7947;
import static net.runelite.api.NpcID.FISHING_SPOT_8523;
import static net.runelite.api.NpcID.FISHING_SPOT_8525;
import static net.runelite.api.NpcID.FISHING_SPOT_8526;
import static net.runelite.api.NpcID.FISHING_SPOT_8527;
import static net.runelite.api.NpcID.ROD_FISHING_SPOT;
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1508;
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1509;
@@ -94,6 +97,7 @@ import static net.runelite.api.NpcID.ROD_FISHING_SPOT_7463;
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_7464;
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_7468;
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_7676;
import static net.runelite.api.NpcID.ROD_FISHING_SPOT_8524;
@Getter
enum FishingSpot
@@ -115,7 +119,8 @@ enum FishingSpot
FISHING_SPOT_1511, FISHING_SPOT_1520, FISHING_SPOT_3915,
FISHING_SPOT_4476, FISHING_SPOT_4477, FISHING_SPOT_5233,
FISHING_SPOT_5234, FISHING_SPOT_5821, FISHING_SPOT_7200,
FISHING_SPOT_7461, FISHING_SPOT_7466
FISHING_SPOT_7461, FISHING_SPOT_7466, FISHING_SPOT_8525,
FISHING_SPOT_8526, FISHING_SPOT_8527
),
MONKFISH("Monkfish", ItemID.RAW_MONKFISH,
FISHING_SPOT_4316
@@ -124,7 +129,7 @@ enum FishingSpot
ROD_FISHING_SPOT, ROD_FISHING_SPOT_1508, ROD_FISHING_SPOT_1509,
ROD_FISHING_SPOT_1513, ROD_FISHING_SPOT_1515, ROD_FISHING_SPOT_1526,
ROD_FISHING_SPOT_1527, ROD_FISHING_SPOT_7463, ROD_FISHING_SPOT_7464,
ROD_FISHING_SPOT_7468
ROD_FISHING_SPOT_7468, ROD_FISHING_SPOT_8524
),
BARB_FISH("Sturgeon, Salmon, Trout", ItemID.LEAPING_STURGEON,
FISHING_SPOT_1542, FISHING_SPOT_7323

View File

@@ -31,6 +31,7 @@ import com.google.inject.Provides;
import java.awt.Color;
import java.awt.Rectangle;
import static java.lang.Boolean.TRUE;
import static java.lang.Math.floor;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
@@ -104,11 +105,15 @@ public class GroundItemsPlugin extends Plugin
// items stay on the ground for 30 mins in an instance
private static final int INSTANCE_DURATION_MILLIS = 45 * 60 * 1000;
private static final int INSTANCE_DURATION_TICKS = (int) floor(30 * 60 / 0.6);
//untradeables stay on the ground for 150 seconds (http://oldschoolrunescape.wikia.com/wiki/Item#Dropping_and_Destroying)
private static final int UNTRADEABLE_DURATION_MILLIS = 150 * 1000;
private static final int UNTRADEABLE_DURATION_TICKS = (int) floor(150 / 0.6);
//items stay on the ground for 1 hour after death
private static final int DEATH_DURATION_MILLIS = 60 * 60 * 1000;
private static final int DEATH_DURATION_TICKS = (int) floor(60 * 60 / 0.6);
private static final int NORMAL_DURATION_MILLIS = 60 * 1000;
private static final int NORMAL_DURATION_TICKS = (int) floor(60 / 0.6);
// Ground item menu options
private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId();
@@ -495,21 +500,26 @@ public class GroundItemsPlugin extends Plugin
final int realItemId = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemId;
final int alchPrice = itemManager.getAlchValue(realItemId);
int durationMillis;
int durationTicks;
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
if (client.isInInstancedRegion())
{
durationMillis = INSTANCE_DURATION_MILLIS;
durationTicks = INSTANCE_DURATION_TICKS;
}
else if (!itemComposition.isTradeable() && realItemId != COINS)
{
durationMillis = UNTRADEABLE_DURATION_MILLIS;
durationTicks = UNTRADEABLE_DURATION_TICKS;
}
else
{
durationMillis = NORMAL_DURATION_MILLIS;
durationTicks = tile.getWorldLocation().equals(playerLocation) ? NORMAL_DURATION_TICKS * 2 : NORMAL_DURATION_TICKS;
}
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
final GroundItem groundItem = GroundItem.builder()
.id(itemId)
.location(tile.getWorldLocation())
@@ -523,7 +533,7 @@ public class GroundItemsPlugin extends Plugin
.durationMillis(durationMillis)
.isAlwaysPrivate(client.isInInstancedRegion() || (!itemComposition.isTradeable() && realItemId != COINS))
.isOwnedByPlayer(tile.getWorldLocation().equals(playerLocation))
.ticks(tile.getWorldLocation().equals(client.getLocalPlayer().getWorldLocation()) ? 200 : 100)
.ticks(durationTicks)
.build();
@@ -593,9 +603,9 @@ public class GroundItemsPlugin extends Plugin
{
if (config.itemHighlightMode() != OVERLAY
&& event.getOption().equals("Take")
&& event.getType() == THIRD_OPTION)
&& event.getIdentifier() == THIRD_OPTION)
{
int itemId = event.getIdentifier();
int itemId = event.getType();
Scene scene = client.getScene();
Tile tile = scene.getTiles()[client.getPlane()][event.getActionParam0()][event.getActionParam1()];
ItemLayer itemLayer = tile.getItemLayer();

View File

@@ -58,182 +58,182 @@ public interface HidePrayersConfig extends Config
@ConfigItem(
position = 1,
keyName = "HideTHICK_SKIN",
name = "Hide Thick Skin",
keyName = "ShowTHICK_SKIN",
name = "Show Thick Skin",
description = "Hide/Show Thick Skin",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideTHICK_SKIN()
default boolean ShowTHICK_SKIN()
{
return false;
}
@ConfigItem(
position = 2,
keyName = "HideBURST_OF_STRENGTH",
name = "Hide Burst of Strength",
keyName = "ShowBURST_OF_STRENGTH",
name = "Show Burst of Strength",
description = "Hide/Show Burst of Strength",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideBURST_OF_STRENGTH()
default boolean ShowBURST_OF_STRENGTH()
{
return false;
}
@ConfigItem(
position = 3,
keyName = "HideCLARITY_OF_THOUGHT",
name = "Hide Clarity of Thought",
keyName = "ShowCLARITY_OF_THOUGHT",
name = "Show Clarity of Thought",
description = "Hide/Show Clarity of Thought",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
unhide = "Showindividualprayers"
)
default boolean HideCLARITY_OF_THOUGHT()
default boolean ShowCLARITY_OF_THOUGHT()
{
return false;
}
@ConfigItem(
position = 4,
keyName = "HideSHARP_EYE",
name = "Hide Sharp Eye",
keyName = "ShowSHARP_EYE",
name = "Show Sharp Eye",
description = "Hide/Show Sharp Eye",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideSHARP_EYE()
default boolean ShowSHARP_EYE()
{
return false;
}
@ConfigItem(
position = 5,
keyName = "HideMYSTIC_WILL",
name = "Hide Mystic Will",
keyName = "ShowMYSTIC_WILL",
name = "Show Mystic Will",
description = "Hide/Show Mystic Will",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideMYSTIC_WILL()
default boolean ShowMYSTIC_WILL()
{
return false;
}
@ConfigItem(
position = 6,
keyName = "HideROCK_SKIN",
name = "Hide Rock Skin",
keyName = "ShowROCK_SKIN",
name = "Show Rock Skin",
description = "Hide/Show Rock Skin",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideROCK_SKIN()
default boolean ShowROCK_SKIN()
{
return false;
}
@ConfigItem(
position = 7,
keyName = "HideSUPERHUMAN_STRENGTH",
name = "Hide Super Human Strength",
keyName = "ShowSUPERHUMAN_STRENGTH",
name = "Show Super Human Strength",
description = "Hide/Show Super Human Strength",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideSUPERHUMAN_STRENGTH()
default boolean ShowSUPERHUMAN_STRENGTH()
{
return false;
}
@ConfigItem(
position = 8,
keyName = "HideIMPROVED_REFLEXES",
name = "Hide Improved_Reflexes",
keyName = "ShowIMPROVED_REFLEXES",
name = "Show Improved_Reflexes",
description = "Hide/Show Improved_Reflexes",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideIMPROVED_REFLEXES()
default boolean ShowIMPROVED_REFLEXES()
{
return false;
}
@ConfigItem(
position = 9,
keyName = "HideRapidRestore",
name = "Hide Rapid Restore",
keyName = "ShowRapidRestore",
name = "Show Rapid Restore",
description = "Hide/Show Rapid Restore",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideRapidRestore()
default boolean ShowRapidRestore()
{
return false;
}
@ConfigItem(
position = 10,
keyName = "HideRapidHeal",
name = "Hide Rapid Heal",
keyName = "ShowRapidHeal",
name = "Show Rapid Heal",
description = "Hide/Show Rapid Heal",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideRapidHeal()
default boolean ShowRapidHeal()
{
return false;
}
@ConfigItem(
position = 11,
keyName = "HideProtectItem",
name = "Hide Protect Item",
keyName = "ShowProtectItem",
name = "Show Protect Item",
description = "Hide/Show Protect Item",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideProtectItem()
default boolean ShowProtectItem()
{
return false;
}
@ConfigItem(
position = 12,
keyName = "HideHAWK_EYE",
name = "Hide Hawk Eye",
keyName = "ShowHAWK_EYE",
name = "Show Hawk Eye",
description = "Hide/Show Hawk Eye",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideHAWK_EYE()
default boolean ShowHAWK_EYE()
{
return false;
}
@ConfigItem(
position = 13,
keyName = "HideMYSTIC_LORE",
name = "Hide Mystic Lore",
keyName = "ShowMYSTIC_LORE",
name = "Show Mystic Lore",
description = "Hide/Show Mystic Lore",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideMYSTIC_LORE()
default boolean ShowMYSTIC_LORE()
{
return false;
}
@@ -241,224 +241,224 @@ public interface HidePrayersConfig extends Config
@ConfigItem(
position = 14,
keyName = "HideSteelSkin",
name = "Hide Steel Skin",
keyName = "ShowSteelSkin",
name = "Show Steel Skin",
description = "Hide/Show Steel skin",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideSteelSkin()
default boolean ShowSteelSkin()
{
return false;
}
@ConfigItem(
position = 15,
keyName = "HideUltimateStrength",
name = "Hide Ultimate Strength",
keyName = "ShowUltimateStrength",
name = "Show Ultimate Strength",
description = "Hide/Show Ultimate strength",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideUltimateStrength()
default boolean ShowUltimateStrength()
{
return false;
}
@ConfigItem(
position = 16,
keyName = "HideIncredibleReflex",
name = "Hide Incredible Reflex",
keyName = "ShowIncredibleReflex",
name = "Show Incredible Reflex",
description = "Hide/Show Incredible Reflex",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideIncredibleReflex()
default boolean ShowIncredibleReflex()
{
return false;
}
@ConfigItem(
position = 17,
keyName = "HidePTFMagic",
name = "Hide Protect From Magic",
keyName = "ShowPTFMagic",
name = "Show Protect From Magic",
description = "Hide/Show Protect From Magic",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HidePTFMagic()
default boolean ShowPTFMagic()
{
return false;
}
@ConfigItem(
position = 18,
keyName = "HidePTFRange",
name = "Hide Protect From Range",
keyName = "ShowPTFRange",
name = "Show Protect From Range",
description = "Hide/Show Protect from Range",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HidePTFRange()
default boolean ShowPTFRange()
{
return false;
}
@ConfigItem(
position = 19,
keyName = "HidePTFMelee",
name = "Hide Protect From Melee",
keyName = "ShowPTFMelee",
name = "Show Protect From Melee",
description = "Hide/Show Protect From Melee",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HidePTFMelee()
default boolean ShowPTFMelee()
{
return false;
}
@ConfigItem(
position = 20,
keyName = "HideEagle",
name = "Hide Eagle Eye",
keyName = "ShowEagle",
name = "Show Eagle Eye",
description = "Hide/Show Eagle Eye",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideEagle()
default boolean ShowEagle()
{
return false;
}
@ConfigItem(
position = 19,
keyName = "HideMystic",
name = "Hide Mystic Might",
keyName = "ShowMystic",
name = "Show Mystic Might",
description = "Hide/Show Mystic Might",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideMystic()
default boolean ShowMystic()
{
return false;
}
@ConfigItem(
position = 21,
keyName = "HideRETRIBUTION",
name = "Hide Retribution",
keyName = "ShowRETRIBUTION",
name = "Show Retribution",
description = "Hide/Show Retribution",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideRETRIBUTION()
default boolean ShowRETRIBUTION()
{
return false;
}
@ConfigItem(
position = 22,
keyName = "HideRedemption",
name = "Hide Redemption",
keyName = "ShowRedemption",
name = "Show Redemption",
description = "Hide/Show Redemption",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideRedemption()
default boolean ShowRedemption()
{
return false;
}
@ConfigItem(
position = 23,
keyName = "HideSmite",
name = "Hide Smite",
keyName = "ShowSmite",
name = "Show Smite",
description = "Hide/Show Smite",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideSmite()
default boolean ShowSmite()
{
return false;
}
@ConfigItem(
position = 24,
keyName = "HidePreserve",
name = "Hide Preserve",
keyName = "ShowPreserve",
name = "Show Preserve",
description = "Hide/Show Preserve",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HidePreserve()
default boolean ShowPreserve()
{
return false;
}
@ConfigItem(
position = 25,
keyName = "HideChivalry",
name = "Hide Chivalry",
keyName = "ShowChivalry",
name = "Show Chivalry",
description = "Hide/Show Chivalry",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideChivalry()
default boolean ShowChivalry()
{
return false;
}
@ConfigItem(
position = 26,
keyName = "HidePiety",
name = "Hide Piety",
keyName = "ShowPiety",
name = "Show Piety",
description = "Hide/Show Piety",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HidePiety()
default boolean ShowPiety()
{
return false;
}
@ConfigItem(
position = 27,
keyName = "HideRigour",
name = "Hide Rigour",
keyName = "ShowRigour",
name = "Show Rigour",
description = "Hide/Show Rigour",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideRigour()
default boolean ShowRigour()
{
return false;
}
@ConfigItem(
position = 28,
keyName = "HideAugury",
name = "Hide Augury",
keyName = "ShowAugury",
name = "Show Augury",
description = "Hide/Show Augury",
group = "Individual Prayers",
hidden = true,
unhide = "showindividualprayers"
)
default boolean HideAugury()
default boolean ShowAugury()
{
return false;
}
@@ -723,4 +723,4 @@ public interface HidePrayersConfig extends Config
{
return false;
}
}
}

View File

@@ -252,35 +252,35 @@ public class HidePrayersPlugin extends Plugin
if (config.showindividualprayers())
{
prayerWidgets.get(0).setHidden(!config.HideTHICK_SKIN()); // Thick Skin
prayerWidgets.get(1).setHidden(!config.HideBURST_OF_STRENGTH()); // Burst of Strength
prayerWidgets.get(2).setHidden(!config.HideCLARITY_OF_THOUGHT()); // Clarity of Thought
prayerWidgets.get(3).setHidden(!config.HideSHARP_EYE()); // Sharp Eye
prayerWidgets.get(4).setHidden(!config.HideMYSTIC_WILL()); // Mystic Will
prayerWidgets.get(5).setHidden(!config.HideROCK_SKIN()); // Rock Skin
prayerWidgets.get(6).setHidden(!config.HideSUPERHUMAN_STRENGTH()); // Super Human Strength
prayerWidgets.get(7).setHidden(!config.HideIMPROVED_REFLEXES()); // Improved_Reflexes
prayerWidgets.get(8).setHidden(!config.HideRapidRestore()); // Rapid Restore
prayerWidgets.get(9).setHidden(!config.HideRapidHeal()); // Rapid Heal
prayerWidgets.get(10).setHidden(!config.HideProtectItem()); // Protect Item
prayerWidgets.get(11).setHidden(!config.HideHAWK_EYE()); // Hawk Eye
prayerWidgets.get(12).setHidden(!config.HideMYSTIC_LORE()); // Mystic Lore
prayerWidgets.get(13).setHidden(!config.HideSteelSkin()); // Steel Skin
prayerWidgets.get(14).setHidden(!config.HideUltimateStrength()); // Ultimate Strength
prayerWidgets.get(15).setHidden(!config.HideIncredibleReflex()); // Incredible Reflexes
prayerWidgets.get(16).setHidden(!config.HidePTFMagic()); // Protect from Magic
prayerWidgets.get(17).setHidden(!config.HidePTFRange()); // Protect from Range
prayerWidgets.get(18).setHidden(!config.HidePTFMelee()); // Protect from Melee
prayerWidgets.get(19).setHidden(!config.HideEagle()); // eagle eye
prayerWidgets.get(20).setHidden(!config.HideMystic()); // Mystic Might
prayerWidgets.get(21).setHidden(!config.HideRETRIBUTION()); // Retribution
prayerWidgets.get(22).setHidden(!config.HideRedemption()); // Redemption
prayerWidgets.get(23).setHidden(!config.HideSmite()); // Smite
prayerWidgets.get(24).setHidden(!config.HidePreserve()); // Preserve
prayerWidgets.get(25).setHidden(!config.HideChivalry()); // Chivalry
prayerWidgets.get(26).setHidden(!config.HidePiety()); // Piety
prayerWidgets.get(27).setHidden(!config.HideRigour()); // Rigour
prayerWidgets.get(28).setHidden(!config.HideAugury()); // Augury
prayerWidgets.get(0).setHidden(!config.ShowTHICK_SKIN()); // Thick Skin
prayerWidgets.get(1).setHidden(!config.ShowBURST_OF_STRENGTH()); // Burst of Strength
prayerWidgets.get(2).setHidden(!config.ShowCLARITY_OF_THOUGHT()); // Clarity of Thought
prayerWidgets.get(3).setHidden(!config.ShowSHARP_EYE()); // Sharp Eye
prayerWidgets.get(4).setHidden(!config.ShowMYSTIC_WILL()); // Mystic Will
prayerWidgets.get(5).setHidden(!config.ShowROCK_SKIN()); // Rock Skin
prayerWidgets.get(6).setHidden(!config.ShowSUPERHUMAN_STRENGTH()); // Super Human Strength
prayerWidgets.get(7).setHidden(!config.ShowIMPROVED_REFLEXES()); // Improved_Reflexes
prayerWidgets.get(8).setHidden(!config.ShowRapidRestore()); // Rapid Restore
prayerWidgets.get(9).setHidden(!config.ShowRapidHeal()); // Rapid Heal
prayerWidgets.get(10).setHidden(!config.ShowProtectItem()); // Protect Item
prayerWidgets.get(11).setHidden(!config.ShowHAWK_EYE()); // Hawk Eye
prayerWidgets.get(12).setHidden(!config.ShowMYSTIC_LORE()); // Mystic Lore
prayerWidgets.get(13).setHidden(!config.ShowSteelSkin()); // Steel Skin
prayerWidgets.get(14).setHidden(!config.ShowUltimateStrength()); // Ultimate Strength
prayerWidgets.get(15).setHidden(!config.ShowIncredibleReflex()); // Incredible Reflexes
prayerWidgets.get(16).setHidden(!config.ShowPTFMagic()); // Protect from Magic
prayerWidgets.get(17).setHidden(!config.ShowPTFRange()); // Protect from Range
prayerWidgets.get(18).setHidden(!config.ShowPTFMelee()); // Protect from Melee
prayerWidgets.get(19).setHidden(!config.ShowEagle()); // eagle eye
prayerWidgets.get(20).setHidden(!config.ShowMystic()); // Mystic Might
prayerWidgets.get(21).setHidden(!config.ShowRETRIBUTION()); // Retribution
prayerWidgets.get(22).setHidden(!config.ShowRedemption()); // Redemption
prayerWidgets.get(23).setHidden(!config.ShowSmite()); // Smite
prayerWidgets.get(24).setHidden(!config.ShowPreserve()); // Preserve
prayerWidgets.get(25).setHidden(!config.ShowChivalry()); // Chivalry
prayerWidgets.get(26).setHidden(!config.ShowPiety()); // Piety
prayerWidgets.get(27).setHidden(!config.ShowRigour()); // Rigour
prayerWidgets.get(28).setHidden(!config.ShowAugury()); // Augury
}
else if (config.getarmadylprayers())
@@ -509,7 +509,7 @@ public class HidePrayersPlugin extends Plugin
prayerWidgets.get(9).setHidden(false); // Rapid Heal
}
if (WorldType.isHighRiskWorld(client.getWorldType()) || client.getRealSkillLevel(Skill.PRAYER) <= 24)
if (WorldType.isAllHighRiskWorld(client.getWorldType()) || client.getRealSkillLevel(Skill.PRAYER) <= 24)
{
prayerWidgets.get(10).setHidden(true); // Protect Item
}

View File

@@ -1,221 +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.plugins.keptondeath;
import java.util.HashSet;
import static net.runelite.api.ItemID.ADAMANT_FIRE_ARROWS;
import static net.runelite.api.ItemID.ADAMANT_FIRE_ARROWS_2539;
import static net.runelite.api.ItemID.AIR_RUNE_PACK;
import static net.runelite.api.ItemID.AMETHYST_FIRE_ARROWS;
import static net.runelite.api.ItemID.AMETHYST_FIRE_ARROWS_21330;
import static net.runelite.api.ItemID.AMULET_OF_GLORY1;
import static net.runelite.api.ItemID.AMULET_OF_GLORY2;
import static net.runelite.api.ItemID.AMULET_OF_GLORY3;
import static net.runelite.api.ItemID.AMULET_OF_GLORY5;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T1;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T2;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T3;
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T5;
import static net.runelite.api.ItemID.APPLES1;
import static net.runelite.api.ItemID.APPLES2;
import static net.runelite.api.ItemID.APPLES3;
import static net.runelite.api.ItemID.APPLES4;
import static net.runelite.api.ItemID.BANANAS1;
import static net.runelite.api.ItemID.BANANAS2;
import static net.runelite.api.ItemID.BANANAS3;
import static net.runelite.api.ItemID.BANANAS4;
import static net.runelite.api.ItemID.BASKET_PACK;
import static net.runelite.api.ItemID.BLACK_MASK_1;
import static net.runelite.api.ItemID.BLACK_MASK_2;
import static net.runelite.api.ItemID.BLACK_MASK_3;
import static net.runelite.api.ItemID.BLACK_MASK_4;
import static net.runelite.api.ItemID.BLACK_MASK_5;
import static net.runelite.api.ItemID.BLACK_MASK_6;
import static net.runelite.api.ItemID.BLACK_MASK_7;
import static net.runelite.api.ItemID.BLACK_MASK_8;
import static net.runelite.api.ItemID.BLACK_MASK_9;
import static net.runelite.api.ItemID.BLACK_SATCHEL;
import static net.runelite.api.ItemID.BRONZE_FIRE_ARROWS;
import static net.runelite.api.ItemID.BRONZE_FIRE_ARROWS_942;
import static net.runelite.api.ItemID.BURNING_AMULET1;
import static net.runelite.api.ItemID.BURNING_AMULET2;
import static net.runelite.api.ItemID.BURNING_AMULET3;
import static net.runelite.api.ItemID.BURNING_AMULET4;
import static net.runelite.api.ItemID.CAKE;
import static net.runelite.api.ItemID.CHAOS_RUNE_PACK;
import static net.runelite.api.ItemID.CHOCOLATE_CAKE;
import static net.runelite.api.ItemID.CHOCOLATE_SLICE;
import static net.runelite.api.ItemID.COMBAT_BRACELET1;
import static net.runelite.api.ItemID.COMBAT_BRACELET2;
import static net.runelite.api.ItemID.COMBAT_BRACELET3;
import static net.runelite.api.ItemID.COMBAT_BRACELET5;
import static net.runelite.api.ItemID.DRAGON_FIRE_ARROWS;
import static net.runelite.api.ItemID.DRAGON_FIRE_ARROWS_11222;
import static net.runelite.api.ItemID.EARTH_RUNE_PACK;
import static net.runelite.api.ItemID.FEATHER_PACK;
import static net.runelite.api.ItemID.FIRE_RUNE_PACK;
import static net.runelite.api.ItemID.GAMES_NECKLACE1;
import static net.runelite.api.ItemID.GAMES_NECKLACE2;
import static net.runelite.api.ItemID.GAMES_NECKLACE3;
import static net.runelite.api.ItemID.GAMES_NECKLACE4;
import static net.runelite.api.ItemID.GAMES_NECKLACE5;
import static net.runelite.api.ItemID.GAMES_NECKLACE6;
import static net.runelite.api.ItemID.GAMES_NECKLACE7;
import static net.runelite.api.ItemID.GOLD_SATCHEL;
import static net.runelite.api.ItemID.GREEN_SATCHEL;
import static net.runelite.api.ItemID.HALF_AN_ADMIRAL_PIE;
import static net.runelite.api.ItemID.HALF_AN_APPLE_PIE;
import static net.runelite.api.ItemID.HALF_A_BOTANICAL_PIE;
import static net.runelite.api.ItemID.HALF_A_FISH_PIE;
import static net.runelite.api.ItemID.HALF_A_GARDEN_PIE;
import static net.runelite.api.ItemID.HALF_A_MEAT_PIE;
import static net.runelite.api.ItemID.HALF_A_MUSHROOM_PIE;
import static net.runelite.api.ItemID.HALF_A_REDBERRY_PIE;
import static net.runelite.api.ItemID.HALF_A_SUMMER_PIE;
import static net.runelite.api.ItemID.HALF_A_WILD_PIE;
import static net.runelite.api.ItemID.IRON_FIRE_ARROWS;
import static net.runelite.api.ItemID.IRON_FIRE_ARROWS_2533;
import static net.runelite.api.ItemID.MIND_RUNE_PACK;
import static net.runelite.api.ItemID.MITHRIL_FIRE_ARROWS;
import static net.runelite.api.ItemID.MITHRIL_FIRE_ARROWS_2537;
import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE1;
import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE2;
import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE3;
import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE4;
import static net.runelite.api.ItemID.ORANGES1;
import static net.runelite.api.ItemID.ORANGES2;
import static net.runelite.api.ItemID.ORANGES3;
import static net.runelite.api.ItemID.ORANGES4;
import static net.runelite.api.ItemID.PLAIN_SATCHEL;
import static net.runelite.api.ItemID.PLANT_POT_PACK;
import static net.runelite.api.ItemID.RED_SATCHEL;
import static net.runelite.api.ItemID.RING_OF_DUELING1;
import static net.runelite.api.ItemID.RING_OF_DUELING2;
import static net.runelite.api.ItemID.RING_OF_DUELING3;
import static net.runelite.api.ItemID.RING_OF_DUELING4;
import static net.runelite.api.ItemID.RING_OF_DUELING5;
import static net.runelite.api.ItemID.RING_OF_DUELING6;
import static net.runelite.api.ItemID.RING_OF_DUELING7;
import static net.runelite.api.ItemID.RING_OF_WEALTH_1;
import static net.runelite.api.ItemID.RING_OF_WEALTH_2;
import static net.runelite.api.ItemID.RING_OF_WEALTH_3;
import static net.runelite.api.ItemID.RING_OF_WEALTH_4;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I1;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I2;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I3;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I4;
import static net.runelite.api.ItemID.RING_OF_WEALTH_I5;
import static net.runelite.api.ItemID.RUNE_FIRE_ARROWS;
import static net.runelite.api.ItemID.RUNE_FIRE_ARROWS_2541;
import static net.runelite.api.ItemID.RUNE_SATCHEL;
import static net.runelite.api.ItemID.SACK_PACK;
import static net.runelite.api.ItemID.SKILLS_NECKLACE1;
import static net.runelite.api.ItemID.SKILLS_NECKLACE2;
import static net.runelite.api.ItemID.SKILLS_NECKLACE3;
import static net.runelite.api.ItemID.SKILLS_NECKLACE5;
import static net.runelite.api.ItemID.SLICE_OF_CAKE;
import static net.runelite.api.ItemID.STEEL_FIRE_ARROWS;
import static net.runelite.api.ItemID.STEEL_FIRE_ARROWS_2535;
import static net.runelite.api.ItemID.STRAWBERRIES1;
import static net.runelite.api.ItemID.STRAWBERRIES2;
import static net.runelite.api.ItemID.STRAWBERRIES3;
import static net.runelite.api.ItemID.STRAWBERRIES4;
import static net.runelite.api.ItemID.TOMATOES1;
import static net.runelite.api.ItemID.TOMATOES2;
import static net.runelite.api.ItemID.TOMATOES3;
import static net.runelite.api.ItemID.TOMATOES4;
import static net.runelite.api.ItemID.TZHAAR_AIR_RUNE_PACK;
import static net.runelite.api.ItemID.TZHAAR_EARTH_RUNE_PACK;
import static net.runelite.api.ItemID.TZHAAR_FIRE_RUNE_PACK;
import static net.runelite.api.ItemID.TZHAAR_WATER_RUNE_PACK;
import static net.runelite.api.ItemID.UNFINISHED_BROAD_BOLT_PACK;
import static net.runelite.api.ItemID.WATER_RUNE_PACK;
import static net.runelite.api.ItemID._12_ANCHOVY_PIZZA;
import static net.runelite.api.ItemID._12_MEAT_PIZZA;
import static net.runelite.api.ItemID._12_PINEAPPLE_PIZZA;
import static net.runelite.api.ItemID._12_PLAIN_PIZZA;
import static net.runelite.api.ItemID._23_CAKE;
import static net.runelite.api.ItemID._23_CHOCOLATE_CAKE;
/**
* Certain items aren't tradeable via the GE but can be traded between players.
* The {@link net.runelite.api.ItemDefinition}'s `isTradeable` value is based on GE trade-ability so we need
* to account for these items. These items should only be kept if protected based on item value.
*/
public enum ActuallyTradeableItem
{
// Item Packs
RUNE_PACKS(AIR_RUNE_PACK, WATER_RUNE_PACK, EARTH_RUNE_PACK, FIRE_RUNE_PACK, CHAOS_RUNE_PACK, MIND_RUNE_PACK),
TZHAAR_PACKS(TZHAAR_AIR_RUNE_PACK, TZHAAR_WATER_RUNE_PACK, TZHAAR_EARTH_RUNE_PACK, TZHAAR_FIRE_RUNE_PACK),
OTHER_PACKS(BASKET_PACK, FEATHER_PACK, PLANT_POT_PACK, SACK_PACK, UNFINISHED_BROAD_BOLT_PACK),
// Equipment
BLACK_MASK(BLACK_MASK_1, BLACK_MASK_2, BLACK_MASK_3, BLACK_MASK_4, BLACK_MASK_5, BLACK_MASK_6, BLACK_MASK_7, BLACK_MASK_8, BLACK_MASK_9),
SATCHELS(BLACK_SATCHEL, GOLD_SATCHEL, GREEN_SATCHEL, PLAIN_SATCHEL, RED_SATCHEL, RUNE_SATCHEL),
FIRE_ARROWS(BRONZE_FIRE_ARROWS, IRON_FIRE_ARROWS, STEEL_FIRE_ARROWS, MITHRIL_FIRE_ARROWS, ADAMANT_FIRE_ARROWS, RUNE_FIRE_ARROWS, AMETHYST_FIRE_ARROWS, DRAGON_FIRE_ARROWS),
FIRE_ARROWS_2(BRONZE_FIRE_ARROWS_942, IRON_FIRE_ARROWS_2533, STEEL_FIRE_ARROWS_2535, MITHRIL_FIRE_ARROWS_2537, ADAMANT_FIRE_ARROWS_2539, RUNE_FIRE_ARROWS_2541, AMETHYST_FIRE_ARROWS_21330, DRAGON_FIRE_ARROWS_11222),
// Food Items
HALF_A(HALF_A_GARDEN_PIE, HALF_A_MEAT_PIE, HALF_A_MUSHROOM_PIE, HALF_A_REDBERRY_PIE, HALF_A_BOTANICAL_PIE, HALF_A_FISH_PIE, HALF_A_SUMMER_PIE, HALF_A_WILD_PIE, HALF_AN_ADMIRAL_PIE, HALF_AN_APPLE_PIE),
PIZZA(_12_ANCHOVY_PIZZA, _12_MEAT_PIZZA, _12_PINEAPPLE_PIZZA, _12_PLAIN_PIZZA),
CAKES(CAKE, _23_CAKE, SLICE_OF_CAKE, CHOCOLATE_CAKE, _23_CHOCOLATE_CAKE, CHOCOLATE_SLICE),
BASKETS(APPLES1, APPLES2, APPLES3, APPLES4, BANANAS1, BANANAS2, BANANAS3, BANANAS4, ORANGES1, ORANGES2, ORANGES3, ORANGES4, STRAWBERRIES1, STRAWBERRIES2, STRAWBERRIES3, STRAWBERRIES4, TOMATOES1, TOMATOES2, TOMATOES3, TOMATOES4),
// Charged Jewelery
BURNING_AMULET(BURNING_AMULET1, BURNING_AMULET2, BURNING_AMULET3, BURNING_AMULET4),
NECKLACE_OF_PASSAGE(NECKLACE_OF_PASSAGE1, NECKLACE_OF_PASSAGE2, NECKLACE_OF_PASSAGE3, NECKLACE_OF_PASSAGE4),
RING_OF_DUELING(RING_OF_DUELING1, RING_OF_DUELING2, RING_OF_DUELING3, RING_OF_DUELING4, RING_OF_DUELING5, RING_OF_DUELING6, RING_OF_DUELING7),
GAMES_NECKLACE(GAMES_NECKLACE1, GAMES_NECKLACE2, GAMES_NECKLACE3, GAMES_NECKLACE4, GAMES_NECKLACE5, GAMES_NECKLACE6, GAMES_NECKLACE7),
COMBAT_BRACELET(COMBAT_BRACELET1, COMBAT_BRACELET2, COMBAT_BRACELET3, COMBAT_BRACELET5),
RING_OF_WEALTH(RING_OF_WEALTH_I, RING_OF_WEALTH_1, RING_OF_WEALTH_I1, RING_OF_WEALTH_2, RING_OF_WEALTH_I2, RING_OF_WEALTH_3, RING_OF_WEALTH_I3, RING_OF_WEALTH_4, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5),
AMULET_OF_GLORY(AMULET_OF_GLORY1, AMULET_OF_GLORY2, AMULET_OF_GLORY3, AMULET_OF_GLORY5),
AMULET_OF_GLORY_T(AMULET_OF_GLORY_T1, AMULET_OF_GLORY_T2, AMULET_OF_GLORY_T3, AMULET_OF_GLORY_T5),
SKILLS_NECKLACE(SKILLS_NECKLACE1, SKILLS_NECKLACE2, SKILLS_NECKLACE3, SKILLS_NECKLACE5),
;
private final int[] ids;
private static final HashSet<Integer> ID_SET;
static
{
ID_SET = new HashSet<>();
for (ActuallyTradeableItem p : values())
{
for (int id : p.ids)
{
ID_SET.add(id);
}
}
}
ActuallyTradeableItem(int... ids)
{
this.ids = ids;
}
public static Boolean check(int id)
{
return ID_SET.contains(id);
}
}

View File

@@ -1,113 +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.plugins.keptondeath;
import java.util.HashSet;
import net.runelite.api.ItemID;
/**
* Some non tradeable items are kept on death inside low level wilderness (1-20) but are turned into a broken variant.
* <p>
* The non-broken variant will be shown inside the interface.
*/
public enum BrokenOnDeathItem
{
// Capes
FIRE_CAPE(ItemID.FIRE_CAPE),
FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE),
INFERNAL_CAPE(ItemID.INFERNAL_CAPE),
INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE),
AVAS_ASSEMBLER(ItemID.AVAS_ASSEMBLER),
ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE),
// Defenders
BRONZE_DEFENDER(ItemID.BRONZE_DEFENDER),
IRON_DEFENDER(ItemID.IRON_DEFENDER),
STEEL_DEFENDER(ItemID.STEEL_DEFENDER),
BLACK_DEFENDER(ItemID.BLACK_DEFENDER),
MITHRIL_DEFENDER(ItemID.MITHRIL_DEFENDER),
ADAMANT_DEFENDER(ItemID.ADAMANT_DEFENDER),
RUNE_DEFENDER(ItemID.RUNE_DEFENDER),
DRAGON_DEFENDER(ItemID.DRAGON_DEFENDER),
AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER),
// Void
VOID_MAGE_HELM(ItemID.VOID_MAGE_HELM),
VOID_RANGER_HELM(ItemID.VOID_RANGER_HELM),
VOID_MELEE_HELM(ItemID.VOID_MELEE_HELM),
VOID_KNIGHT_TOP(ItemID.VOID_KNIGHT_TOP),
VOID_KNIGHT_ROBE(ItemID.VOID_KNIGHT_ROBE),
VOID_KNIGHT_GLOVES(ItemID.VOID_KNIGHT_GLOVES),
VOID_KNIGHT_MACE(ItemID.VOID_KNIGHT_MACE),
ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP),
ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE),
// Barb Assault
FIGHTER_HAT(ItemID.FIGHTER_HAT),
RANGER_HAT(ItemID.RANGER_HAT),
HEALER_HAT(ItemID.HEALER_HAT),
FIGHTER_TORSO(ItemID.FIGHTER_TORSO),
PENANCE_SKIRT(ItemID.PENANCE_SKIRT),
// Castle Wars
SARADOMIN_HALO(ItemID.SARADOMIN_HALO),
ZAMORAK_HALO(ItemID.ZAMORAK_HALO),
GUTHIX_HALO(ItemID.GUTHIX_HALO),
DECORATIVE_MAGIC_HAT(ItemID.DECORATIVE_ARMOUR_11898),
DECORATIVE_MAGIC_ROBE_TOP(ItemID.DECORATIVE_ARMOUR_11896),
DECORATIVE_MAGIC_ROBE_LEGS(ItemID.DECORATIVE_ARMOUR_11897),
DECORATIVE_RANGE_TOP(ItemID.DECORATIVE_ARMOUR_11899),
DECORATIVE_RANGE_BOTTOM(ItemID.DECORATIVE_ARMOUR_11900),
DECORATIVE_RANGE_QUIVER(ItemID.DECORATIVE_ARMOUR_11901),
GOLD_DECORATIVE_HELM(ItemID.DECORATIVE_HELM_4511),
GOLD_DECORATIVE_BODY(ItemID.DECORATIVE_ARMOUR_4509),
GOLD_DECORATIVE_LEGS(ItemID.DECORATIVE_ARMOUR_4510),
GOLD_DECORATIVE_SKIRT(ItemID.DECORATIVE_ARMOUR_11895),
GOLD_DECORATIVE_SHIELD(ItemID.DECORATIVE_SHIELD_4512),
GOLD_DECORATIVE_SWORD(ItemID.DECORATIVE_SWORD_4508);
private final int itemID;
private static final HashSet<Integer> ID_SET;
static
{
ID_SET = new HashSet<>();
for (BrokenOnDeathItem p : values())
{
ID_SET.add(p.itemID);
}
}
BrokenOnDeathItem(int itemID)
{
this.itemID = itemID;
}
public static boolean check(int itemID)
{
return ID_SET.contains(itemID);
}
}

View File

@@ -1,592 +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.plugins.keptondeath;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
@PluginDescriptor(
name = "Kept on Death",
description = "Reworks the Items Kept on Death interface to be more accurate",
type = PluginType.UTILITY,
enabledByDefault = false
)
@Slf4j
public class KeptOnDeathPlugin extends Plugin
{
}
//todo once bytecodes work again, re-enable
/*
{
// Handles Clicking on items in Kept on Death Interface
private static final int SCRIPT_ID = ScriptID.KEPT_LOST_ITEM_EXAMINE;
private static final double HIGH_ALCH = 0.6;
// Item Container helpers
private static final int MAX_ROW_ITEMS = 8;
private static final int STARTING_X = 5;
private static final int STARTING_Y = 25;
private static final int X_INCREMENT = 40;
private static final int Y_INCREMENT = 38;
private static final int ORIGINAL_WIDTH = 36;
private static final int ORIGINAL_HEIGHT = 32;
private static final int ORIGINAL_LOST_HEIGHT = 209;
private static final int ORIGINAL_LOST_Y = 107;
// Information panel text helpers
private static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("#,###");
private static final String MAX_KEPT_ITEMS_FORMAT = "<col=ffcc33>Max items kept on death :<br><br><col=ffcc33>~ %s ~";
private static final String ACTION_TEXT = "Item: <col=ff981f>%s";
private static final String DEFAULT = "<col=FFFFFF>3<col=FF981F> items protected by default";
private static final String IS_SKULLED = "<col=ff3333>PK skull<col=ff981f> -3";
private static final String PROTECTING_ITEM = "<col=ff3333>Protect Item prayer<col=ff981f> +1";
private static final String ACTUAL = "Actually protecting <col=FFFFFF>%s<col=FF981F> items";
private static final String WHITE_OUTLINE = "Items with a <col=ffffff>white outline<col=ff981f> will always be lost.";
private static final String CHANGED_MECHANICS = "Untradeable items are kept on death in non-pvp scenarios.";
private static final String NON_PVP = "You will have 1 hour to retrieve your lost items.";
private static final String LINE_BREAK = "<br>";
private static final String UIM_DEFAULT = "You are an <col=FFFFFF>UIM<col=FF981F> which means <col=FFFFFF>0<col=FF981F> items are protected by default";
private static final int ORIGINAL_INFO_HEIGHT = 183;
private static final int FONT_COLOR = 0xFF981F;
// Button Names and Images
private static final String PROTECT_ITEM_BUTTON_NAME = "Protect Item Prayer";
private static final String SKULLED_BUTTON_NAME = "Skulled";
private static final String LOW_WILDY_BUTTON_NAME = "Low Wildy (1-20)";
private static final String DEEP_WILDY_BUTTON_NAME = "Deep Wildy (21+)";
private static final int PROTECT_ITEM_SPRITE_ID = SpriteID.PRAYER_PROTECT_ITEM;
private static final int SKULL_SPRITE_ID = SpriteID.PLAYER_KILLER_SKULL_523;
private static final int SWORD_SPRITE_ID = SpriteID.MULTI_COMBAT_ZONE_CROSSED_SWORDS;
private static final int SKULL_2_SPRITE_ID = SpriteID.FIGHT_PITS_WINNER_SKULL_RED;
@Inject
private Client client;
@Inject
private ItemManager itemManager;
@Getter
private boolean widgetVisible = false;
private LinkedHashMap<String, WidgetButton> buttonMap = new LinkedHashMap<>();
private boolean isSkulled = false;
private boolean protectingItem = false;
private boolean hasAlwaysLost = false;
private int wildyLevel = -1;
@Subscribe
protected void onScriptCallbackEvent(ScriptCallbackEvent event)
{
if (event.getEventName().equals("deathKeepBuild"))
{
// The script in charge of building the Items Kept on Death interface has finished running.
// Make all necessary changes now.
// Players inside Safe Areas (POH/Clan Wars) & playing DMM see the default interface
if (isInSafeArea() || client.getWorldType().contains(WorldType.DEADMAN))
{
return;
}
syncSettings();
createWidgetButtons();
recreateItemsKeptOnDeathWidget();
}
}
// Sync user settings
private void syncSettings()
{
SkullIcon s = client.getLocalPlayer().getSkullIcon();
// Ultimate iron men deaths are treated like they are always skulled
isSkulled = (s != null && s.equals(SkullIcon.SKULL)) || isUltimateIronman();
protectingItem = client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1;
syncCurrentWildyLevel();
}
private void syncCurrentWildyLevel()
{
if (client.getVar(Varbits.IN_WILDERNESS) != 1)
{
// if they are in a PvP world and not in a safe zone act like in lvl 1 wildy
if (isInPvpWorld() && !isInPvPSafeZone())
{
wildyLevel = 1;
return;
}
wildyLevel = -1;
return;
}
int y = client.getLocalPlayer().getWorldLocation().getY();
// Credits to atomicint_#5069 (Discord)
int underLevel = ((y - 9920) / 8) + 1;
int upperLevel = ((y - 3520) / 8) + 1;
wildyLevel = (y > 6400 ? underLevel : upperLevel);
}
private boolean isInPvpWorld()
{
EnumSet<WorldType> world = client.getWorldType();
return world.contains(WorldType.PVP) || world.contains(WorldType.HIGH_RISK);
}
private boolean isInPvPSafeZone()
{
Widget w = client.getWidget(WidgetInfo.PVP_WORLD_SAFE_ZONE);
return w != null && !w.isHidden();
}
private boolean isInSafeArea()
{
Widget w = client.getWidget(WidgetInfo.ITEMS_KEPT_SAFE_ZONE_CONTAINER);
return w != null && !w.isHidden();
}
private boolean isUltimateIronman()
{
return client.getAccountType().equals(AccountType.ULTIMATE_IRONMAN);
}
private int getDefaultItemsKept()
{
int count = isSkulled ? 0 : 3;
if (protectingItem)
{
count++;
}
return count;
}
private void recreateItemsKeptOnDeathWidget()
{
// Text flags based on items should be reset everytime the widget is recreated
hasAlwaysLost = false;
Widget lost = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_CONTAINER);
Widget kept = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_CONTAINER);
if (lost != null && kept != null)
{
// Grab all items on player and sort by price.
List<Item> items = new ArrayList<>();
ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
Item[] inv = inventory == null ? new Item[0] : inventory.getItems();
ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
Item[] equip = equipment == null ? new Item[0] : equipment.getItems();
Collections.addAll(items, inv);
Collections.addAll(items, equip);
// Sort by item price
items.sort((o1, o2) ->
{
int o1ID = ItemVariationMapping.map(itemManager.canonicalize(o1.getId()));
int o2ID = ItemVariationMapping.map(itemManager.canonicalize(o2.getId()));
ItemDefinition c1 = itemManager.getItemDefinition(o1ID);
ItemDefinition c2 = itemManager.getItemDefinition(o2ID);
int exchangePrice1 = c1.isTradeable() ? itemManager.getItemPrice(c1.getId()) : c1.getPrice();
int exchangePrice2 = c2.isTradeable() ? itemManager.getItemPrice(c2.getId()) : c2.getPrice();
return exchangePrice2 - exchangePrice1;
});
int keepCount = getDefaultItemsKept();
List<Widget> keptItems = new ArrayList<>();
List<Widget> lostItems = new ArrayList<>();
for (Item i : items)
{
int id = i.getId();
if (id == -1)
{
continue;
}
ItemDefinition c = itemManager.getItemDefinition(i.getId());
Widget itemWidget = createItemWidget(i.getQuantity(), c);
// Bonds are always kept and do not count towards the limit.
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
{
keptItems.add(itemWidget);
continue;
}
// Certain items are always lost on death and have a white outline which we need to readd
AlwaysLostItem item = AlwaysLostItem.getByItemID(i.getId());
if (item != null)
{
// Some of these items are kept on death (outside wildy), like the Rune pouch. Ignore them
if (!item.isKept() || wildyLevel > 0)
{
itemWidget.setOnOpListener(SCRIPT_ID, 0, i.getQuantity(), c.getName());
itemWidget.setBorderType(2);
lostItems.add(itemWidget);
hasAlwaysLost = true;
continue;
}
}
// Keep most valuable items regardless of trade-ability.
if (keepCount > 0)
{
if (i.getQuantity() > keepCount)
{
keptItems.add(createItemWidget(keepCount, c));
itemWidget.setItemQuantity(i.getQuantity() - keepCount);
keepCount = 0;
}
else
{
keptItems.add(itemWidget);
keepCount -= i.getQuantity();
continue;
}
}
if (!checkTradeable(i.getId(), c) && wildyLevel < 21)
{
// Certain items are turned into broken variants inside the wilderness.
if (BrokenOnDeathItem.check(i.getId()))
{
keptItems.add(itemWidget);
continue;
}
// Ignore all non tradeables in wildy except for the above case(s).
if (wildyLevel > 0)
{
lostItems.add(itemWidget);
continue;
}
keptItems.add(itemWidget);
}
else
{
itemWidget.setOnOpListener(SCRIPT_ID, 0, i.getQuantity(), c.getName());
lostItems.add(itemWidget);
}
}
int rows = keptItems.size() > MAX_ROW_ITEMS ? keptItems.size() / MAX_ROW_ITEMS : 0;
// Adjust items lost container position if new rows were added to kept items container
lost.setOriginalY(ORIGINAL_LOST_Y + (rows * Y_INCREMENT));
lost.setOriginalHeight(ORIGINAL_LOST_HEIGHT - (rows * Y_INCREMENT));
setWidgetChildren(kept, keptItems);
setWidgetChildren(lost, lostItems);
updateKeptWidgetInfoText();
}
}
*/
/**
* Wrapper for widget.setChildren() but updates the child index and original positions
* Used for Items Kept and Lost containers
*
* @param parent Widget to override children
* @param widgets Children to set on parent
* <p>
* Creates the text to be displayed in the right side of the interface based on current selections
* <p>
* Corrects the Information panel based on the item containers
* <p>
* Creates an Item Widget for use inside the Kept on Death Interface
* @param qty Amount of item
* @param c Items Composition
* @return
*//*
private void setWidgetChildren(Widget parent, List<Widget> widgets)
{
Widget[] children = parent.getChildren();
if (children == null)
{
// Create a child so we can copy the returned Widget[] and avoid hn casting issues from creating a new Widget[]
parent.createChild(0, WidgetType.GRAPHIC);
children = parent.getChildren();
}
Widget[] itemsArray = Arrays.copyOf(children, widgets.size());
int parentId = parent.getId();
int startingIndex = 0;
for (Widget w : widgets)
{
int originalX = STARTING_X + ((startingIndex % MAX_ROW_ITEMS) * X_INCREMENT);
int originalY = STARTING_Y + ((startingIndex / MAX_ROW_ITEMS) * Y_INCREMENT);
w.setParentId(parentId);
w.setId(parentId);
w.setIndex(startingIndex);
w.setOriginalX(originalX);
w.setOriginalY(originalY);
w.revalidate();
itemsArray[startingIndex] = w;
startingIndex++;
}
parent.setChildren(itemsArray);
parent.revalidate();
}
*/
/**
* Creates the text to be displayed in the right side of the interface based on current selections
*//*
private String getUpdatedInfoText()
{
String textToAdd = DEFAULT;
if (isUltimateIronman())
{
textToAdd = UIM_DEFAULT;
}
else
{
if (isSkulled)
{
textToAdd += LINE_BREAK + IS_SKULLED;
}
if (protectingItem)
{
textToAdd += LINE_BREAK + PROTECTING_ITEM;
}
textToAdd += LINE_BREAK + String.format(ACTUAL, getDefaultItemsKept());
}
if (wildyLevel < 1)
{
textToAdd += LINE_BREAK + LINE_BREAK + NON_PVP;
}
if (hasAlwaysLost)
{
textToAdd += LINE_BREAK + LINE_BREAK + WHITE_OUTLINE;
}
textToAdd += LINE_BREAK + LINE_BREAK + CHANGED_MECHANICS;
return textToAdd;
}
*/
/**
* Corrects the Information panel based on the item containers
*//*
private void updateKeptWidgetInfoText()
{
// Add Information text widget
createNewTextWidget();
// Update Items lost total value
Widget lost = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_CONTAINER);
double total = 0;
for (Widget w : lost.getChildren())
{
if (w.getItemId() == -1)
{
continue;
}
double price = itemManager.getItemPrice(w.getItemId());
if (price == 0)
{
// Default to alch price
price = itemManager.getItemDefinition(w.getItemId()).getPrice() * HIGH_ALCH;
}
total += price;
}
Widget lostValue = client.getWidget(WidgetInfo.ITEMS_LOST_VALUE);
lostValue.setText(NUMBER_FORMAT.format(total) + " gp");
// Update Max items kept
Widget kept = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_CONTAINER);
Widget max = client.getWidget(WidgetInfo.ITEMS_KEPT_MAX);
max.setText(String.format(MAX_KEPT_ITEMS_FORMAT, kept.getChildren().length));
}
// isTradeable checks if they are traded on the grand exchange, some items are trade-able but not via GE
private boolean checkTradeable(int id, ItemDefinition c)
{
// If the item is a note check the unnoted variants trade ability
if (c.getNote() != -1)
{
return checkTradeable(c.getLinkedNoteId(), itemManager.getItemDefinition(c.getLinkedNoteId()));
}
switch (id)
{
case ItemID.COINS_995:
case ItemID.PLATINUM_TOKEN:
return true;
default:
if (ActuallyTradeableItem.check(id))
{
return true;
}
}
return c.isTradeable();
}
private void createNewTextWidget()
{
// The text use to be put inside this container but since we can't create LAYER widgets
// We needed to edit this to be a layer for adding buttons
Widget old = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
// Update the existing TEXT container if it exists. It should be the last child of the old text widget
// client.getWidget() seems to not find indexed child widgets
Widget[] children = old.getChildren();
if (children != null && children.length > 0)
{
Widget x = old.getChild(children.length - 1);
if (x.getId() == WidgetInfo.ITEMS_KEPT_CUSTOM_TEXT_CONTAINER.getId())
{
x.setText(getUpdatedInfoText());
x.revalidate();
return;
}
}
Widget w = old.createChild(-1, WidgetType.TEXT);
// Position under buttons taking remaining space
w.setOriginalWidth(old.getOriginalWidth());
w.setOriginalHeight(ORIGINAL_INFO_HEIGHT - old.getOriginalHeight());
w.setOriginalY(old.getOriginalHeight());
w.setFontId(FontID.PLAIN_11);
w.setTextShadowed(true);
w.setTextColor(FONT_COLOR);
w.setText(getUpdatedInfoText());
w.setId(WidgetInfo.ITEMS_KEPT_CUSTOM_TEXT_CONTAINER.getId());
w.revalidate();
// Need to reset height so text is visible?
old.setOriginalHeight(ORIGINAL_INFO_HEIGHT);
old.revalidate();
}
private void createWidgetButtons()
{
buttonMap.clear();
// Ultimate Iron men are always skulled and can't use the protect item prayer
if (!isUltimateIronman())
{
createButton(PROTECT_ITEM_BUTTON_NAME, PROTECT_ITEM_SPRITE_ID, protectingItem);
createButton(SKULLED_BUTTON_NAME, SKULL_SPRITE_ID, isSkulled);
}
createButton(LOW_WILDY_BUTTON_NAME, SWORD_SPRITE_ID, wildyLevel > 0 && wildyLevel <= 20);
createButton(DEEP_WILDY_BUTTON_NAME, SKULL_2_SPRITE_ID, wildyLevel > 20);
Widget parent = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
parent.setType(WidgetType.LAYER);
parent.revalidate();
WidgetButton.addButtonsToContainerWidget(parent, buttonMap.values());
}
private void createButton(String name, int spriteID, boolean startingFlag)
{
WidgetButton button = new WidgetButton(name, spriteID, startingFlag, this::buttonCallback, client);
buttonMap.put(name, button);
}
private void buttonCallback(String name, boolean selected)
{
log.debug("Clicked Widget Button {}. New value: {}", name, selected);
switch (name)
{
case PROTECT_ITEM_BUTTON_NAME:
protectingItem = selected;
break;
case SKULLED_BUTTON_NAME:
isSkulled = selected;
break;
case LOW_WILDY_BUTTON_NAME:
if (!selected)
{
syncCurrentWildyLevel();
break;
}
wildyLevel = 1;
buttonMap.get(DEEP_WILDY_BUTTON_NAME).setSelected(false);
break;
case DEEP_WILDY_BUTTON_NAME:
if (!selected)
{
syncCurrentWildyLevel();
break;
}
wildyLevel = 21;
buttonMap.get(LOW_WILDY_BUTTON_NAME).setSelected(false);
break;
default:
log.warn("Unhandled Button Name: {}", name);
return;
}
recreateItemsKeptOnDeathWidget();
}
*/
/**
* Creates an Item Widget for use inside the Kept on Death Interface
*
* @param qty Amount of item
* @param c Items Composition
* @return
*//*
private Widget createItemWidget(int qty, ItemDefinition c)
{
Widget itemWidget = client.createWidget();
itemWidget.setType(WidgetType.GRAPHIC);
itemWidget.setItemId(c.getId());
itemWidget.setItemQuantity(qty);
itemWidget.setHasListener(true);
itemWidget.setIsIf3(true);
itemWidget.setOriginalWidth(ORIGINAL_WIDTH);
itemWidget.setOriginalHeight(ORIGINAL_HEIGHT);
itemWidget.setBorderType(1);
itemWidget.setAction(1, String.format(ACTION_TEXT, c.getName()));
itemWidget.setOnOpListener(SCRIPT_ID, 1, qty, c.getName());
return itemWidget;
}
}*/

View File

@@ -1,176 +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.plugins.keptondeath;
import java.util.Arrays;
import java.util.Collection;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.SpriteID;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetType;
@Slf4j
public class WidgetButton
{
private static final int ICON_HEIGHT = 26;
private static final int ICON_WIDTH = 26;
private static final int BACKGROUND_HEIGHT = 32;
private static final int BACKGROUND_WIDTH = 32;
private static final int PADDING = 5;
private static final int ICON_PADDING = (BACKGROUND_HEIGHT - ICON_HEIGHT) / 2;
private static final int BACKGROUND_SPRITE_ID = SpriteID.EQUIPMENT_SLOT_TILE;
private static final int SELECTED_BACKGROUND_SPRITE_ID = SpriteID.EQUIPMENT_SLOT_SELECTED;
public interface WidgetButtonCallback
{
void run(String name, boolean newState);
}
private String name;
private int spriteID;
@Getter
private Widget icon;
@Getter
private Widget background;
private boolean selected;
private WidgetButtonCallback callback;
WidgetButton(String name, int spriteID, boolean selectedStartState, WidgetButtonCallback callback, Client client)
{
this.name = name;
this.spriteID = spriteID;
this.selected = selectedStartState;
this.callback = callback;
createBackgroundWidget(client);
createIconWidget(client);
}
private void createBackgroundWidget(Client client)
{
background = createWidget(client);
background.setOriginalWidth(BACKGROUND_WIDTH);
background.setOriginalHeight(BACKGROUND_HEIGHT);
syncBackgroundSprite();
}
private void createIconWidget(Client client)
{
icon = createWidget(client);
icon.setAction(1, "Toggle:");
icon.setOnOpListener((JavaScriptCallback) ev -> onButtonClicked());
icon.setHasListener(true);
icon.setSpriteId(spriteID);
}
private Widget createWidget(Client client)
{
Widget w = client.createWidget();
w.setType(WidgetType.GRAPHIC);
w.setOriginalWidth(ICON_WIDTH);
w.setOriginalHeight(ICON_HEIGHT);
w.setName("<col=ff981f>" + this.name);
w.setIsIf3(true);
return w;
}
public void setSelected(boolean selected)
{
this.selected = selected;
syncBackgroundSprite();
}
private void syncBackgroundSprite()
{
background.setSpriteId(selected ? SELECTED_BACKGROUND_SPRITE_ID : BACKGROUND_SPRITE_ID);
}
/**
* Adds the collection of WidgetButtons to the container overriding any existing children.
*
* @param container Widget to add buttons too
* @param buttons buttons to add
*/
static void addButtonsToContainerWidget(Widget container, Collection<WidgetButton> buttons)
{
Widget[] children = container.getChildren();
if (children == null)
{
// Create a child so we can copy the returned Widget[] and avoid hn casting issues from creating a new Widget[]
container.createChild(0, WidgetType.GRAPHIC);
children = container.getChildren();
}
// Each button has two widgets, Icon and Background
Widget[] itemsArray = Arrays.copyOf(children, buttons.size() * 2);
int parentId = container.getId();
int xIncrement = BACKGROUND_WIDTH + PADDING;
int yIncrement = BACKGROUND_HEIGHT + PADDING;
int maxRowItems = container.getWidth() / xIncrement;
// Ensure at least 1 button per row
maxRowItems = maxRowItems < 1 ? 1 : maxRowItems;
int startingIndex = 0;
for (WidgetButton w : buttons)
{
int originalX = (((startingIndex / 2) % maxRowItems) * xIncrement);
int originalY = (((startingIndex / 2) / maxRowItems) * yIncrement);
Widget background = updateWidgetPosition(w.getBackground(), parentId, startingIndex, originalX, originalY);
itemsArray[startingIndex] = background;
startingIndex++;
// Icon must be padded to center inside image
Widget icon = updateWidgetPosition(w.getIcon(), parentId, startingIndex, originalX + ICON_PADDING, originalY + ICON_PADDING);
itemsArray[startingIndex] = icon;
startingIndex++;
}
int rows = 1 + (buttons.size() > maxRowItems ? buttons.size() / maxRowItems : 0);
container.setOriginalHeight(yIncrement * rows);
container.setChildren(itemsArray);
container.revalidate();
}
private static Widget updateWidgetPosition(Widget w, int id, int index, int originalX, int originalY)
{
w.setParentId(id);
w.setId(id);
w.setIndex(index);
w.setOriginalX(originalX);
w.setOriginalY(originalY);
w.revalidate();
return w;
}
private void onButtonClicked()
{
setSelected(!selected);
callback.run(name, selected);
}
}

View File

@@ -33,6 +33,17 @@ import net.runelite.client.config.ModifierlessKeybind;
@ConfigGroup("keyremapping")
public interface KeyRemappingConfig extends Config
{
@ConfigItem(
position = 0,
keyName = "hideDisplayName",
name = "Hide display name",
description = "Hides the display name from showing before \"Press Enter to Chat...\""
)
default boolean hideDisplayName()
{
return false;
}
@ConfigItem(
position = 1,
keyName = "cameraRemap",

View File

@@ -37,6 +37,7 @@ import net.runelite.api.IconID;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr;
import net.runelite.api.Varbits;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
@@ -68,7 +69,7 @@ public class KeyRemappingPlugin extends Plugin
private ClientThread clientThread;
@Inject
private ConfigManager configManager;
private KeyRemappingConfig config;
@Inject
private KeyManager keyManager;
@@ -83,7 +84,6 @@ public class KeyRemappingPlugin extends Plugin
@Override
protected void startUp() throws Exception
{
configManager.setConfiguration("runelite", "entertochatplugin", false);
typing = false;
keyManager.registerKeyListener(inputListener);
@@ -150,6 +150,25 @@ public class KeyRemappingPlugin extends Plugin
return w == null || w.isSelfHidden();
}
@Subscribe
public void onConfigChanged(ConfigChanged configChanged)
{
if (!configChanged.getGroup().equals("keyremapping") || !configChanged.getKey().equals("hideDisplayName"))
{
return;
}
clientThread.invoke(() ->
{
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null && chatboxInput.getText().endsWith(PRESS_ENTER_TO_CHAT))
{
chatboxInput.setText(getWaitingText());
}
}
);
}
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
{
@@ -161,7 +180,7 @@ public class KeyRemappingPlugin extends Plugin
{
if (chatboxFocused() && !typing)
{
chatboxInput.setText(getPlayerNameWithIcon() + ": " + PRESS_ENTER_TO_CHAT);
chatboxInput.setText(getWaitingText());
}
}
break;
@@ -181,7 +200,7 @@ public class KeyRemappingPlugin extends Plugin
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null)
{
chatboxInput.setText(getPlayerNameWithIcon() + ": " + PRESS_ENTER_TO_CHAT);
chatboxInput.setText(getWaitingText());
// Typed text can be non-empty on plugin start, so clear it now
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
}
@@ -220,4 +239,16 @@ public class KeyRemappingPlugin extends Plugin
}
return icon + client.getLocalPlayer().getName();
}
private String getWaitingText()
{
if (config.hideDisplayName())
{
return PRESS_ENTER_TO_CHAT;
}
else
{
return getPlayerNameWithIcon() + ": " + PRESS_ENTER_TO_CHAT;
}
}
}

View File

@@ -158,5 +158,15 @@ public interface LootTrackerConfig extends Config
return "";
}
@ConfigItem(
keyName = "lootValueMessage",
name = "Loot Value Messages",
description = "Sends a game message with the total value you of your loot when you get a kill",
position = 5
)
default boolean sendLootValueMessages()
{
return true;
}
}

View File

@@ -133,10 +133,6 @@ public class LootTrackerPlugin extends Plugin
5179, "Brimstone Chest",
11573, "Crystal Chest"
);
// Player deaths
public static HashSet<String> usernameSet = new HashSet<String>(Arrays.stream(new String[]{"All Records"}).collect(Collectors.toList()));
private static final File LOOT_RECORDS_FILE = new File(RuneLite.RUNELITE_DIR, "lootRecords.json");
private static final Set<Integer> RESPAWN_REGIONS = ImmutableSet.of(
12850, // Lumbridge
@@ -144,49 +140,38 @@ public class LootTrackerPlugin extends Plugin
12342, // Edgeville
11062 // Camelot
);
private boolean pvpDeath = false;
@Inject
private ClientToolbar clientToolbar;
@Inject
private ItemManager itemManager;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private SpriteManager spriteManager;
@Inject
private LootTrackerConfig config;
// Player deaths
public static HashSet<String> usernameSet = new HashSet<String>(Arrays.stream(new String[]{"All Records"}).collect(Collectors.toList()));
@Inject
public Client client;
@VisibleForTesting
public Collection<LootRecord> lootRecords = new ArrayList<>();
private boolean pvpDeath = false;
@Inject
private ClientToolbar clientToolbar;
@Inject
private ItemManager itemManager;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private SpriteManager spriteManager;
@Inject
private LootTrackerConfig config;
@Inject
private ClientThread clientThread;
@Inject
private SessionManager sessionManager;
@Inject
private ScheduledExecutorService executor;
private LootTrackerPanel panel;
private NavigationButton navButton;
private String eventType;
private List<String> ignoredItems = new ArrayList<>();
private Multiset<Integer> inventorySnapshot;
@Getter(AccessLevel.PACKAGE)
private LootTrackerClient lootTrackerClient;
private BufferedReader bufferedReader;
private JsonStreamParser jsonStreamParser;
@VisibleForTesting
public Collection<LootRecord> lootRecords = new ArrayList<>();
private static Collection<ItemStack> stack(Collection<ItemStack> items)
{
@@ -217,6 +202,13 @@ public class LootTrackerPlugin extends Plugin
return list;
}
private static Collection<GameItem> toGameItems(Collection<ItemStack> items)
{
return items.stream()
.map(item -> new GameItem(item.getId(), item.getQuantity()))
.collect(Collectors.toList());
}
@Provides
LootTrackerConfig provideConfig(ConfigManager configManager)
{
@@ -405,7 +397,6 @@ public class LootTrackerPlugin extends Plugin
}
}
@Subscribe
public void onPlayerSpawned(PlayerSpawned event)
{
@@ -418,6 +409,18 @@ public class LootTrackerPlugin extends Plugin
@Subscribe
public void onPlayerLootReceived(final PlayerLootReceived playerLootReceived)
{
if (config.sendLootValueMessages())
{
if (WorldType.isDeadmanWorld(client.getWorldType()) || WorldType.isHighRiskWorld(client.getWorldType()) || WorldType.isPvpWorld(client.getWorldType()) || client.getVar(Varbits.IN_WILDERNESS) == 1)
{
final String totalValue = StackFormatter.quantityToRSStackSize(playerLootReceived.getItems().stream()
.mapToInt(itemStack -> itemManager.getItemPrice(itemStack.getId()) * itemStack.getQuantity()).sum());
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.CONSOLE).runeLiteFormattedMessage(
new ChatMessageBuilder().append("The total value of your loot is " + totalValue + " GP.")
.build()).build());
}
}
final Player player = playerLootReceived.getPlayer();
final Collection<ItemStack> items = playerLootReceived.getItems();
final String name = player.getName();
@@ -806,13 +809,6 @@ public class LootTrackerPlugin extends Plugin
.toArray(LootTrackerItem[]::new);
}
private static Collection<GameItem> toGameItems(Collection<ItemStack> items)
{
return items.stream()
.map(item -> new GameItem(item.getId(), item.getQuantity()))
.collect(Collectors.toList());
}
public Collection<LootTrackerRecord> convertToLootTrackerRecord(final Collection<LootRecord> records)
{
Collection<LootTrackerRecord> trackerRecords = new ArrayList<>();

View File

@@ -53,6 +53,7 @@ import static net.runelite.api.MenuAction.WALK;
import net.runelite.api.MenuEntry;
import net.runelite.api.NPC;
import net.runelite.api.Player;
import net.runelite.api.Varbits;
import static net.runelite.api.Varbits.BUILDING_MODE;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ConfigChanged;
@@ -81,6 +82,7 @@ import net.runelite.client.plugins.menuentryswapper.util.FairyRingMode;
import net.runelite.client.plugins.menuentryswapper.util.HouseMode;
import net.runelite.client.plugins.menuentryswapper.util.ObeliskMode;
import net.runelite.client.plugins.menuentryswapper.util.OccultAltarMode;
import net.runelite.client.plugins.menuentryswapper.util.CharterOption;
import static net.runelite.client.util.MenuUtil.swap;
import net.runelite.client.util.MiscUtils;
import net.runelite.client.util.Text;
@@ -104,9 +106,17 @@ public class MenuEntrySwapperPlugin extends Plugin
private static final String CONFIG_GROUP = "shiftclick";
private static final String ITEM_KEY_PREFIX = "item_";
private static final int PURO_PURO_REGION_ID = 10307;
private static final String WALK_HERE = "WALK HERE";
private static final String CANCEL = "CANCEL";
private static final String CAST_OPTIONS_ATTACK = "CAST";
public static final HashSet<String> CAST_OPTIONS_KEYWORDS = new HashSet<>();
static
{
CAST_OPTIONS_KEYWORDS.add(CAST_OPTIONS_ATTACK);
}
private MenuEntry[] entries;
private final Set<Integer> leftClickConstructionIDs = new HashSet<>();
private final Set<String> leftClickConstructionItems = new HashSet<>();
private boolean buildingMode;
private static final WidgetMenuOption FIXED_INVENTORY_TAB_CONFIGURE = new WidgetMenuOption(CONFIGURE,
@@ -182,8 +192,7 @@ public class MenuEntrySwapperPlugin extends Plugin
public void startUp()
{
addSwaps();
//todo re-enable when fixed.
/*loadConstructionIDs(config.getConstructionItems());*/
loadConstructionItems(config.getEasyConstructionItems());
if (config.shiftClickCustomization())
{
@@ -197,8 +206,7 @@ public class MenuEntrySwapperPlugin extends Plugin
public void shutDown()
{
disableCustomization();
//todo re-enable when fixed.
/*loadConstructionIDs("");*/
loadConstructionItems("");
loadCustomSwaps(""); // Removes all custom swaps
removeSwaps();
}
@@ -210,9 +218,8 @@ public class MenuEntrySwapperPlugin extends Plugin
{
return;
}
//todo re-enable when fixed.
/*loadConstructionIDs(config.getConstructionItems());*/
loadConstructionItems(config.getEasyConstructionItems());
removeSwaps();
addSwaps();
@@ -307,9 +314,8 @@ public class MenuEntrySwapperPlugin extends Plugin
{
return;
}
//todo re-enable when fixed.
/*loadConstructionIDs(config.getConstructionItems());*/
loadConstructionItems(config.getEasyConstructionItems());
}
@Subscribe
@@ -536,6 +542,7 @@ public class MenuEntrySwapperPlugin extends Plugin
return;
}
final String pOptionToReplace = Text.removeTags(event.getOption()).toUpperCase();
final int eventId = event.getIdentifier();
final String option = Text.standardize(event.getOption());
final String target = Text.standardize(event.getTarget());
@@ -899,26 +906,50 @@ public class MenuEntrySwapperPlugin extends Plugin
}
}
}
Player[] players = client.getCachedPlayers();
Player player = null;
int identifier = event.getIdentifier();
if (identifier >= 0 && identifier < players.length)
{
player = players[identifier];
}
if (player == null)
{
return;
}
//If the option is already to walk there, or cancel we don't need to swap it with anything
if (pOptionToReplace.equals(CANCEL) || pOptionToReplace.equals(WALK_HERE))
{
return;
}
if (((config.getRemoveFreezePlayerCoX() && client.getVar(Varbits.IN_RAID) == 1)
|| (config.getRemoveFreezePlayerToB() && client.getVar(Varbits.THEATRE_OF_BLOOD) == 2))
&& (player.isFriend() || player.isClanMember())
&& CAST_OPTIONS_KEYWORDS.contains(pOptionToReplace))
{
addswap(pOptionToReplace);
}
if (option.equals("talk-to"))
{
if (config.swapPickpocket() && target.contains("h.a.m."))
if (config.swapPickpocket())
{
swap(client, "pickpocket", option, target, true);
}
if (config.swapAbyssTeleport() && target.contains("mage of zamorak"))
{
swap(client, "teleport", option, target, true);
}
if (config.swapHardWoodGrove() && target.contains("rionasta"))
{
swap(client, "send-parcel", option, target, true);
}
if (config.swapBank())
if (config.swapBankExchange())
{
swap(client, "bank", option, target, true);
swap(client, "exchange", option, target, true);
}
if (config.swapContract())
@@ -926,14 +957,14 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "contract", option, target, true);
}
if (config.swapExchange())
{
swap(client, "exchange", option, target, true);
}
if (config.swapDarkMage())
if (config.swapInteract())
{
swap(client, "repairs", option, target, true);
swap(client, "claim-slime", option, target, true);
swap(client, "decant", option, target, true);
swap(client, "claim", option, target, true);
swap(client, "heal", option, target, true);
swap(client, "help", option, target, true);
}
// make sure assignment swap is higher priority than trade swap for slayer masters
@@ -947,21 +978,19 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "buy-plank", option, target, true);
}
if (config.claimDynamite() && target.equals("thirus"))
{
swap(client, "claim", option, target, true);
}
if (config.swapTrade())
if (config.swapTrade() && (!(target.equals("trader crewmember") || target.equals("trader stan")) || config.charterOption().equals(CharterOption.TRADE)))
{
swap(client, "trade", option, target, true);
swap(client, "trade-with", option, target, true);
swap(client, "shop", option, target, true);
}
if (config.claimSlime() && target.equals("robin"))
if (config.swapMinigame())
{
swap(client, "claim-slime", option, target, true);
swap(client, "story", option, target, true);
swap(client, "escort", option, target, true);
swap(client, "dream", option, target, true);
swap(client, "start-minigame", option, target, true);
}
if (config.swapTravel())
@@ -976,6 +1005,16 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "rellekka", option, target, true);
swap(client, "follow", option, target, true);
swap(client, "transport", option, target, true);
if (config.swapAbyssTeleport() && target.contains("mage of zamorak"))
{
swap(client, "teleport", option, target, true);
}
if (!(target.equals("trader crewmember") || target.equals("trader stan")) || config.charterOption().equals(CharterOption.CHARTER))
{
swap(client, "charter", option, target, true);
}
}
if (config.swapPay())
@@ -984,30 +1023,16 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "pay (", option, target, false);
}
if (config.swapDream())
{
swap(client, "dream", option, target, true);
}
if (config.swapDecant())
{
swap(client, "decant", option, target, true);
}
if (config.swapQuick())
{
swap(client, "quick-travel", option, target, true);
}
if (config.swapStory())
if (config.swapEnchant())
{
swap(client, "story", option, target, true);
swap(client, "enchant", option, target, true);
}
if (config.swapEscort())
{
swap(client, "escort", option, target, true);
}
}
else if (config.swapWildernessLever() && target.equals("lever") && option.equals("ardougne"))
@@ -1025,18 +1050,9 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "stun", option, target, true);
}
else if (config.swapTravel() && option.equals("pass") && target.equals("energy barrier"))
else if (config.swapTravel() && (option.equals("pass") || option.equals("open")))
{
swap(client, "pay-toll(2-ecto)", option, target, true);
}
else if (config.swapTravel() && option.equals("open") && target.equals("gate"))
{
swap(client, "pay-toll(10gp)", option, target, true);
}
else if (config.swapHardWoodGrove() && option.equals("open") && target.equals("hardwood grove doors"))
{
swap(client, "quick-pay(100)", option, target, true);
swap(client, "pay-toll", option, target, false);
}
else if (config.swapTravel() && option.equals("inspect") && target.equals("trapdoor"))
{
@@ -1157,7 +1173,14 @@ public class MenuEntrySwapperPlugin extends Plugin
{
swap(client, "quick-open", option, target, true);
}
else if (config.swapQuick() && option.equals("enter"))
{
swap(client, "quick-enter", option, target, true);
}
else if (config.swapQuick() && option.equals("leave tomb"))
{
swap(client, "quick-leave", option, target, true);
}
else if (config.swapAdmire() && option.equals("admire"))
{
swap(client, "teleport", option, target, true);
@@ -1202,17 +1225,14 @@ public class MenuEntrySwapperPlugin extends Plugin
}
// Put all item-related swapping after shift-click
else if (config.swapTeleportItem() && option.equals("wear"))
else if (config.swapTeleportItem() && (option.equals("wear") || option.equals("wield")))
{
swap(client, "rub", option, target, true);
swap(client, "teleport", option, target, true);
}
else if (option.equals("wield"))
else if (config.swapCoalBag() && option.contains("deposit") && target.equals("coal bag"))
{
if (config.swapTeleportItem())
{
swap(client, "teleport", option, target, true);
}
swap(client, "empty", option, target, true);
}
else if (config.swapBones() && option.equals("bury"))
{
@@ -1222,37 +1242,6 @@ public class MenuEntrySwapperPlugin extends Plugin
{
swap(client, "teleport menu", option, target, true);
}
if (config.getTempConstruction() && buildingMode && !Strings.isNullOrEmpty(config.getTempConstructionItems()))
{
if (event.getType() == WALK.getId())
{
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry menuEntry = menuEntries[menuEntries.length - 1];
menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET);
client.setMenuEntries(menuEntries);
}
swap(client, "Build", option, target);
MenuEntry[] entries = client.getMenuEntries();
for (int i = entries.length - 1; i >= 0; i--)
{
for (String temp : config.getTempConstructionItems().split(","))
{
if (temp.equalsIgnoreCase(Text.removeTags(entries[i].getTarget())))
{
if (!entries[i].getOption().equalsIgnoreCase("remove"))
{
entries = ArrayUtils.remove(entries, i);
i--;
}
}
}
}
client.setMenuEntries(entries);
}
}
@Subscribe
@@ -1382,6 +1371,12 @@ public class MenuEntrySwapperPlugin extends Plugin
menuManager.addSwap("remove", "burning amulet", config.getBurningAmuletMode().toString());
}
if (config.teleEquippedCape())
{
menuManager.addSwap("remove", "tele to poh", config.telecapeMode().toString());
menuManager.addSwap("remove", "teleport", config.telecapeMode().toString());
}
if (config.getCombatBracelet())
{
menuManager.addSwap("remove", "combat bracelet", config.getCombatBraceletMode().toString());
@@ -1490,25 +1485,24 @@ public class MenuEntrySwapperPlugin extends Plugin
return location.getRegionID() == PURO_PURO_REGION_ID;
}
}
//todo re-enable when fixed.
/* private void loadConstructionIDs(String from)
private void loadConstructionItems(String from)
{
if (client.getGameState() != GameState.LOGGED_IN
|| Strings.isNullOrEmpty(from) && leftClickConstructionIDs.isEmpty())
|| Strings.isNullOrEmpty(from) && leftClickConstructionItems.isEmpty())
{
return;
}
if (!leftClickConstructionIDs.isEmpty())
if (!leftClickConstructionItems.isEmpty())
{
for (int i : leftClickConstructionIDs)
for (String s : leftClickConstructionItems)
{
menuManager.toggleLeftClick("build", i, true);
menuManager.toggleLeftClick("remove", i, true);
menuManager.removePriorityEntry("build", s);
menuManager.removePriorityEntry("remove", s);
}
leftClickConstructionIDs.clear();
leftClickConstructionItems.clear();
}
if (config.getEasyConstruction() &&
@@ -1517,21 +1511,18 @@ public class MenuEntrySwapperPlugin extends Plugin
{
for (String s : Text.fromCSV(from))
{
int id = Integer.parseInt(s.replaceAll("[^0-9]", ""));
if (leftClickConstructionIDs.contains(id))
if (leftClickConstructionItems.contains(s))
{
continue;
}
if (menuManager.toggleLeftClick("build", id, false)
|| menuManager.toggleLeftClick("remove", id, false))
{
leftClickConstructionIDs.add(id);
}
menuManager.addPriorityEntry("build", s);
menuManager.addPriorityEntry("remove", s);
leftClickConstructionItems.add(s);
}
}
}*/
}
void startShift()
{
@@ -1562,4 +1553,47 @@ public class MenuEntrySwapperPlugin extends Plugin
{
menuManager.removePriorityEntry("climb-down");
}
/**
* Swaps menu entries if the entries could be found. This places Walk Here where the top level menu option was.
* @param pOptionToReplace The String containing the Menu Option that needs to be replaced. IE: "Attack", "Chop Down".
*/
private void addswap(String pOptionToReplace)
{
MenuEntry[] entries = client.getMenuEntries();
Integer walkHereEntry = searchIndex(entries, WALK_HERE);
Integer entryToReplace = searchIndex(entries, pOptionToReplace);
if (walkHereEntry != null
&& entryToReplace != null)
{
MenuEntry walkHereMenuEntry = entries[walkHereEntry];
entries[walkHereEntry] = entries[entryToReplace];
entries[entryToReplace] = walkHereMenuEntry;
client.setMenuEntries(entries);
}
}
/**
* Finds the index of the menu that contains the verbiage we are looking for.
* @param pMenuEntries The list of {@link MenuEntry}s.
* @param pMenuEntryToSearchFor The Option in the menu to search for.
* @return The index location or null if it was not found.
*/
private Integer searchIndex(MenuEntry[] pMenuEntries, String pMenuEntryToSearchFor)
{
Integer indexLocation = 0;
for (MenuEntry menuEntry : pMenuEntries)
{
String entryOption = Text.removeTags(menuEntry.getOption()).toUpperCase();
if (entryOption.equals(pMenuEntryToSearchFor))
{
return indexLocation;
}
indexLocation++;
}
return null;
}
}

View File

@@ -0,0 +1,20 @@
package net.runelite.client.plugins.menuentryswapper.util;
public enum CharterOption
{
TRADE("Trade"),
CHARTER("Charter");
private final String name;
CharterOption(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}

View File

@@ -0,0 +1,20 @@
package net.runelite.client.plugins.menuentryswapper.util;
public enum teleEquippedMode
{
TELE_TO_POH("Tele to POH"),
TELEPORT("teleport");
private final String name;
teleEquippedMode(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}

View File

@@ -27,6 +27,7 @@ package net.runelite.client.plugins.metronome;
import com.google.inject.Provides;
import javax.inject.Inject;
import net.runelite.api.SoundEffectVolume;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
@@ -164,7 +165,7 @@ public class MetronomePlugin extends Plugin
{
if (tockClip == null)
{
client.playSoundEffect(SoundEffectID.GE_INCREMENT_PLOP);
client.playSoundEffect(SoundEffectID.GE_DECREMENT_PLOP, SoundEffectVolume.MEDIUM_HIGH);
}
else
{
@@ -180,7 +181,7 @@ public class MetronomePlugin extends Plugin
{
if (tickClip == null)
{
client.playSoundEffect(SoundEffectID.GE_DECREMENT_PLOP);
client.playSoundEffect(SoundEffectID.GE_DECREMENT_PLOP, SoundEffectVolume.MEDIUM_HIGH);
}
else
{

View File

@@ -1,70 +1,63 @@
/*
* 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.plugins.keptondeath;
import com.google.common.collect.ImmutableMap;
import lombok.Getter;
import net.runelite.api.ItemID;
/**
* Certain Items receive a white outline by Jagex as they are always lost on death. This is sometimes incorrectly
* added to Items by Jagex as the item is actually kept in non-pvp areas of the game, such as the Rune Pouch.
* <p>
* The white outline will be added to these items when they are lost on death.
*/
public enum AlwaysLostItem
{
RUNE_POUCH(ItemID.RUNE_POUCH, true),
LOOTING_BAG(ItemID.LOOTING_BAG, false),
LOOTING_BAG_22586(ItemID.LOOTING_BAG_22586, false),
CLUE_BOX(ItemID.CLUE_BOX, false);
private final int itemID;
@Getter
private final boolean kept;
private static final ImmutableMap<Integer, AlwaysLostItem> ID_MAP;
static
{
ImmutableMap.Builder<Integer, AlwaysLostItem> map = ImmutableMap.builder();
for (AlwaysLostItem p : values())
{
map.put(p.itemID, p);
}
ID_MAP = map.build();
}
AlwaysLostItem(int itemID, boolean kept)
{
this.itemID = itemID;
this.kept = kept;
}
public static AlwaysLostItem getByItemID(int itemID)
{
return ID_MAP.get(itemID);
}
}
/*
* Copyright 2019 Jarred Vardy <jarredvardy@gmail.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.mining;
import java.awt.Color;
import java.awt.Graphics2D;
import javax.inject.Inject;
import net.runelite.api.ItemID;
import net.runelite.api.Point;
import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.WidgetItemOverlay;
public class MiningCoalBagOverlay extends WidgetItemOverlay
{
private final MiningPlugin plugin;
private final MiningConfig config;
@Inject
MiningCoalBagOverlay(MiningPlugin plugin, MiningConfig config)
{
showOnInventory();
this.plugin = plugin;
this.config = config;
}
@Override
public void renderItemOverlay(Graphics2D graphics, int itemId, WidgetItem itemWidget)
{
if (!config.showCoalBagOverlay() || (itemId != ItemID.COAL_BAG && itemId != ItemID.COAL_BAG_12019))
{
return;
}
graphics.setFont(FontManager.getRunescapeSmallFont());
graphics.setColor(Color.WHITE);
Point location = itemWidget.getCanvasLocation();
graphics.drawString(config.amountOfCoalInCoalBag() + "", location.getX(), location.getY() + 14);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2019 Jarred Vardy <jarredvardy@gmail.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.mining;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("mining")
public interface MiningConfig extends Config
{
@ConfigItem(
keyName = "showCoalBagOverlay",
name = "Show coal bag overlay",
description = "Overlays how much coal is inside of your coal bag"
)
default boolean showCoalBagOverlay()
{
return true;
}
@ConfigItem(
keyName = "amountOfCoalInCoalBag",
name = "",
description = "To store coal amount between sessions",
hidden = true
)
default int amountOfCoalInCoalBag()
{
return 0;
}
@ConfigItem(
keyName = "amountOfCoalInCoalBag",
name = "",
description = "Overload to set coal amount",
hidden = true
)
void amountOfCoalInCoalBag(int amount);
}

View File

@@ -1,5 +1,7 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Anthony <cvballa3g0@gmail.com>
* Copyright (c) 2019, Jarred Vardy <jarred.vardy@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,16 +26,26 @@
*/
package net.runelite.client.plugins.mining;
import com.google.inject.Provides;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.GameState;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
import net.runelite.api.ItemID;
import net.runelite.api.MenuAction;
import static net.runelite.api.ObjectID.DEPLETED_VEIN_26665;
import static net.runelite.api.ObjectID.DEPLETED_VEIN_26666;
import static net.runelite.api.ObjectID.DEPLETED_VEIN_26667;
@@ -45,10 +57,9 @@ import static net.runelite.api.ObjectID.ORE_VEIN_26663;
import static net.runelite.api.ObjectID.ORE_VEIN_26664;
import net.runelite.api.WallObject;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.GameObjectDespawned;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.WallObjectSpawned;
import net.runelite.api.events.*;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
@@ -57,8 +68,8 @@ import net.runelite.client.ui.overlay.OverlayManager;
@Slf4j
@PluginDescriptor(
name = "Mining",
description = "Show ore respawn timers",
tags = {"overlay", "skilling", "timers"},
description = "Show ore respawn timers and coal bag overlay",
tags = {"overlay", "skilling", "timers", "coal", "coalbag", "coal bag"},
enabledByDefault = false
)
public class MiningPlugin extends Plugin
@@ -66,6 +77,17 @@ public class MiningPlugin extends Plugin
private static final int ROCK_DISTANCE = 14;
private static final int MINING_GUILD_REGION = 12183;
private static final Pattern COAL_BAG_EMPTY_MESSAGE = Pattern.compile("^The coal bag is (now )?empty\\.$");
private static final Pattern COAL_BAG_ONE_MESSAGE = Pattern.compile("^The coal bag contains one piece of coal\\.$");
private static final Pattern COAL_BAG_AMOUNT_MESSAGE = Pattern.compile("^The coal bag contains (\\d+) pieces of coal\\.$");
private static final int MAX_INVENTORY_SPACE = 28;
private static final int FULL_COAL_BAG_AMOUNT = 27;
private static final String FILL_OPTION = "fill";
private static final String EMPTY_OPTION = "empty";
@Inject
private Client client;
@@ -73,7 +95,13 @@ public class MiningPlugin extends Plugin
private OverlayManager overlayManager;
@Inject
private MiningOverlay overlay;
private MiningOverlay miningOverlay;
@Inject
private MiningCoalBagOverlay coalBagOverlay;
@Inject
private MiningConfig config;
@Getter(AccessLevel.PACKAGE)
private final List<RockRespawn> respawns = new ArrayList<>();
@@ -82,16 +110,24 @@ public class MiningPlugin extends Plugin
@Override
protected void startUp()
{
overlayManager.add(overlay);
overlayManager.add(miningOverlay);
overlayManager.add(coalBagOverlay);
}
@Override
protected void shutDown() throws Exception
{
overlayManager.remove(overlay);
overlayManager.remove(miningOverlay);
overlayManager.remove(coalBagOverlay);
respawns.clear();
}
@Provides
MiningConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(MiningConfig.class);
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
@@ -176,6 +212,73 @@ public class MiningPlugin extends Plugin
}
}
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
//TODO: should work hopefully
if (event.getMenuAction() != MenuAction.RUNELITE || event.getActionParam1() != WidgetInfo.INVENTORY.getId())
{
return;
}
ItemContainer inventoryItemContainer = client.getItemContainer(InventoryID.INVENTORY);
Item[] inventoryItems = inventoryItemContainer.getItems();
switch (event.getOption().toLowerCase())
{
case FILL_OPTION:
int coalInInventoryCount = (int) Arrays.stream(inventoryItems).filter(i -> i.getId() == ItemID.COAL).count();
updateAmountOfCoalInBag(coalInInventoryCount);
break;
case EMPTY_OPTION:
int emptyInventorySpaceCount = (int) Arrays.stream(inventoryItems).filter(i -> i.getId() != -1).count();
int difference = MAX_INVENTORY_SPACE - emptyInventorySpaceCount;
updateAmountOfCoalInBag(-difference);
break;
}
}
@Subscribe
public void onChatMessage(ChatMessage event)
{
if (event.getType() != ChatMessageType.GAMEMESSAGE)
{
return;
}
String chatMsg = event.getMessage();
if (COAL_BAG_EMPTY_MESSAGE.matcher(chatMsg).find())
{
updateAmountOfCoalInBag(0);
}
else if (COAL_BAG_ONE_MESSAGE.matcher(chatMsg).find())
{
updateAmountOfCoalInBag(1);
}
else
{
Matcher matcher = COAL_BAG_AMOUNT_MESSAGE.matcher(chatMsg);
if (matcher.find())
{
updateAmountOfCoalInBag(Integer.parseInt(matcher.group(1)) - config.amountOfCoalInCoalBag());
}
}
}
/**
* Update the player's count of coal in their Coal Bag
*
* @param delta How much to add/subtract from the amount.
* Supply a negative number to subtract, or positive number to add.
*/
protected void updateAmountOfCoalInBag(int delta)
{
// check for upper/lower bounds of amount of coal in a bag
// 0 <= X <= 27
config.amountOfCoalInCoalBag(Math.max(0, Math.min(FULL_COAL_BAG_AMOUNT, config.amountOfCoalInCoalBag() + delta)));
}
private boolean inMiningGuild()
{
return client.getLocalPlayer().getWorldLocation().getRegionID() == MINING_GUILD_REGION;

View File

@@ -194,7 +194,7 @@ public class NpcSceneOverlay extends Overlay
break;
}
if (config.drawNames())
if (config.drawNames() && actor.getName() != null)
{
String npcName = Text.removeTags(actor.getName());
Point textLocation = actor.getCanvasTextLocation(graphics, npcName, actor.getLogicalHeight() + 40);

View File

@@ -1,4 +1,5 @@
/*
* Copyright (c) 2019, Owain van Brakel <https://github.com/Owain94>
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* All rights reserved.
*
@@ -30,48 +31,85 @@ import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Range;
import net.runelite.client.config.Stub;
@ConfigGroup("objectindicators")
public interface ObjectIndicatorsConfig extends Config
{
@ConfigItem(
position = 0,
keyName = "overlayStub",
name = "Overlay Style",
description = "",
position = 0
)
default Stub overlayStub()
{
return new Stub();
}
@ConfigItem(
position = 1,
keyName = "objectMarkerRenderStyle",
name = "Highlight Style",
description = "Highlight setting",
parent = "overlayStub"
)
default RenderStyle objectMarkerRenderStyle()
{
return RenderStyle.OUTLINE;
}
@ConfigItem(
position = 2,
keyName = "objectMarkerOutlineRenderStyle",
name = "Outline Style",
description = "Highlight outline setting",
parent = "overlayStub",
hidden = true,
unhide = "objectMarkerRenderStyle",
unhideValue = "OUTLINE"
)
default OutlineRenderStyle objectMarkerOutlineRenderStyle()
{
return OutlineRenderStyle.NORMAL_OUTLINE;
}
@ConfigItem(
keyName = "colorStub",
name = "Colors",
description = "",
position = 3
)
default Stub colorStub()
{
return new Stub();
}
@ConfigItem(
position = 4,
keyName = "markerColor",
name = "Marker color",
description = "Configures the color of object marker"
description = "Configures the outer color of object marker",
parent = "colorStub"
)
default Color markerColor()
default Color objectMarkerColor()
{
return Color.YELLOW;
}
@Range(
min = 0,
max = 10
max = 100
)
@ConfigItem(
position = 1,
keyName = "stroke",
name = "Stroke Size",
description = "Configures the stroke size of object marker"
)
default int stroke()
{
return 2;
}
@Range(
min = 0,
max = 255
)
@ConfigItem(
position = 2,
keyName = "alpha",
position = 5,
keyName = "objectMarkerAlpha",
name = "Alpha",
description = "Configures the opacity/alpha of object marker"
description = "Configures the opacity/alpha of object marker",
parent = "colorStub"
)
default int alpha()
default int objectMarkerAlpha()
{
return 20;
return 100;
}
}
}

View File

@@ -1,4 +1,5 @@
/*
* Copyright (c) 2019, Owain van Brakel <https://github.com/Owain94>
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* All rights reserved.
*
@@ -24,33 +25,40 @@
*/
package net.runelite.client.plugins.objectindicators;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.Area;
import static java.lang.Math.floor;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.DecorativeObject;
import net.runelite.api.GameObject;
import net.runelite.api.TileObject;
import net.runelite.client.graphics.ModelOutlineRenderer;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil;
class ObjectIndicatorsOverlay extends Overlay
{
private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
private final Client client;
private final ObjectIndicatorsConfig config;
private final ObjectIndicatorsPlugin plugin;
private final ModelOutlineRenderer modelOutliner;
@Inject
private ObjectIndicatorsOverlay(Client client, ObjectIndicatorsConfig config, ObjectIndicatorsPlugin plugin)
private ObjectIndicatorsOverlay(Client client, ObjectIndicatorsConfig config, ObjectIndicatorsPlugin plugin, ModelOutlineRenderer modelOutliner)
{
this.client = client;
this.config = config;
this.plugin = plugin;
this.modelOutliner = modelOutliner;
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.LOW);
setLayer(OverlayLayer.ABOVE_SCENE);
@@ -66,46 +74,70 @@ class ObjectIndicatorsOverlay extends Overlay
continue;
}
final Polygon polygon;
Polygon polygon2 = null;
Color color = config.objectMarkerColor();
int opacity = (int) floor(config.objectMarkerAlpha() * 2.55);
Color objectColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), opacity);
if (object instanceof GameObject)
switch (config.objectMarkerRenderStyle())
{
polygon = ((GameObject) object).getConvexHull();
}
else if (object instanceof DecorativeObject)
{
polygon = ((DecorativeObject) object).getConvexHull();
polygon2 = ((DecorativeObject) object).getConvexHull2();
}
else
{
polygon = object.getCanvasTilePoly();
}
case OUTLINE:
switch (config.objectMarkerOutlineRenderStyle())
{
case THIN_OUTLINE:
modelOutliner.drawOutline(object, 1, objectColor);
break;
if (polygon != null)
{
renderPoly(graphics, polygon, config.markerColor(), config.stroke(), config.alpha());
}
case NORMAL_OUTLINE:
modelOutliner.drawOutline(object, 2, objectColor);
break;
if (polygon2 != null)
{
renderPoly(graphics, polygon2, config.markerColor(), config.stroke(), config.alpha());
case THIN_GLOW:
modelOutliner.drawOutline(object, 4, objectColor, TRANSPARENT);
break;
case GLOW:
modelOutliner.drawOutline(object, 8, objectColor, TRANSPARENT);
break;
}
break;
case HULL:
final Polygon polygon;
Polygon polygon2 = null;
if (object instanceof GameObject)
{
polygon = ((GameObject) object).getConvexHull();
}
else if (object instanceof DecorativeObject)
{
polygon = ((DecorativeObject) object).getConvexHull();
polygon2 = ((DecorativeObject) object).getConvexHull2();
}
else
{
polygon = object.getCanvasTilePoly();
}
if (polygon != null)
{
OverlayUtil.renderPolygon(graphics, polygon, objectColor);
}
if (polygon2 != null)
{
OverlayUtil.renderPolygon(graphics, polygon2, objectColor);
}
break;
case CLICKBOX:
Area clickbox = object.getClickbox();
if (clickbox != null)
{
OverlayUtil.renderHoverableArea(graphics, object.getClickbox(), client.getMouseCanvasPosition(), TRANSPARENT, objectColor, objectColor.darker());
}
break;
}
}
return null;
}
private void renderPoly(Graphics2D graphics, Polygon polygon, Color color, int stroke, int alpha)
{
if (polygon != null)
{
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 255));
graphics.setStroke(new BasicStroke(stroke));
graphics.draw(polygon);
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha));
graphics.fill(polygon);
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2019, Owain van Brakel <https://github.com/Owain94>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,16 +22,13 @@
* (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.batools;
import java.awt.image.BufferedImage;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.ui.overlay.infobox.Counter;
package net.runelite.client.plugins.objectindicators;
class CycleCounter extends Counter
public enum OutlineRenderStyle
{
CycleCounter(BufferedImage img, Plugin plugin, int tick)
{
super(img, plugin, tick);
}
THIN_OUTLINE,
NORMAL_OUTLINE,
THIN_GLOW,
GLOW
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, whartd <github.com/whartd>
* Copyright (c) 2019, Owain van Brakel <https://github.com/Owain94>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,23 +22,12 @@
* (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.barbarianassault;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.Point;
import net.runelite.api.widgets.WidgetInfo;
package net.runelite.client.plugins.objectindicators;
@Getter
@AllArgsConstructor
enum HealerTeam
public enum RenderStyle
{
TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115),
TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115),
TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115),
TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115);
private WidgetInfo teammate;
private Point offset;
private int width;
}
CLICKBOX,
HULL,
OUTLINE
}

View File

@@ -65,7 +65,7 @@ class OpponentInfoOverlay extends Overlay
private final PanelComponent panelComponent = new PanelComponent();
private Integer lastMaxHealth;
private int lastMaxHealth;
private int lastRatio = 0;
private int lastHealthScale = 0;
private String opponentName;
@@ -111,7 +111,7 @@ class OpponentInfoOverlay extends Overlay
lastHealthScale = opponent.getHealth();
opponentName = Text.removeTags(opponent.getName());
lastMaxHealth = null;
lastMaxHealth = -1;
if (opponent instanceof NPC)
{
lastMaxHealth = npcManager.getHealth(((NPC) opponent).getId());
@@ -167,7 +167,7 @@ class OpponentInfoOverlay extends Overlay
final HitpointsDisplayStyle displayStyle = opponentInfoConfig.hitpointsDisplayStyle();
if ((displayStyle == HitpointsDisplayStyle.HITPOINTS || displayStyle == HitpointsDisplayStyle.BOTH)
&& lastMaxHealth != null)
&& lastMaxHealth != -1)
{
// This is the reverse of the calculation of healthRatio done by the server
// which is: healthRatio = 1 + (healthScale - 1) * health / maxHealth (if health > 0, 0 otherwise)

View File

@@ -32,7 +32,6 @@ import java.util.Iterator;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.client.plugins.party.data.PartyTilePingData;
import net.runelite.client.ui.overlay.Overlay;
@@ -60,18 +59,6 @@ class PartyPingOverlay extends Overlay
return null;
}
// Update selected scene tile
if (!client.isMenuOpen())
{
Point p = client.getMouseCanvasPosition();
p = new Point(
p.getX() - client.getViewportXOffset(),
p.getY() - client.getViewportYOffset());
client.setCheckClick(true);
client.setMouseCanvasHoverPosition(p);
}
synchronized (plugin.getPendingTilePings())
{
final Iterator<PartyTilePingData> iterator = plugin.getPendingTilePings().iterator();

View File

@@ -396,7 +396,7 @@ public class PestControlPlugin extends Plugin
}
// Get points from dialog after purchase
Widget pestControlDialog = client.getWidget(WidgetInfo.PEST_CONTROL_DIALOG_TEXT);
Widget pestControlDialog = client.getWidget(WidgetInfo.MINIGAME_DIALOG_TEXT);
if (pestControlDialog != null)
{
String pestControlDialogText = Text.sanitizeMultilineText(pestControlDialog.getText());

View File

@@ -1,10 +1,12 @@
/*
* Copyright (c) 2019. PKLite - All Rights Reserved
* Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited.
* Proprietary and confidential. Refer to PKLite License file for more information on
* full terms of this copyright and to determine what constitutes authorized use.
* Written by PKLite(ST0NEWALL, others) <stonewall@thots.cc.usa>, 2019
*
* ******************************************************************************
* * Copyright (c) 2019 RuneLitePlus
* * Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file.
* * If there are any questions comments, or feedback about this software, please direct all inquiries directly to the file authors:
* * ST0NEWALL#9112
* * RuneLitePlus Discord: https://discord.gg/Q7wFtCe
* * RuneLitePlus website: https://runelitepl.us
* *****************************************************************************
*/
package net.runelite.client.plugins.pvptools;
@@ -44,6 +46,7 @@ import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOpened;
import net.runelite.api.events.PlayerDespawned;
import net.runelite.api.events.PlayerSpawned;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.AsyncBufferedImage;
@@ -104,6 +107,9 @@ public class PvpToolsPlugin extends Plugin
@Inject
private ItemManager itemManager;
@Inject
private ChatMessageManager chatMessageManager;
private PvpToolsPlugin uhPvpToolsPlugin = this;
private static final String WALK_HERE = "WALK HERE";
@@ -510,6 +516,7 @@ public class PvpToolsPlugin extends Plugin
}
}
/**
* Enables or disables the fall in helper feature
*/

View File

@@ -29,7 +29,6 @@ import java.awt.Color;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Keybind;
import net.runelite.client.config.Stub;
@ConfigGroup("raids")
@@ -259,15 +258,29 @@ public interface RaidsConfig extends Config
@ConfigItem(
position = 17,
parent = "roomConfig",
keyName = "crabColor",
name = "Crab color",
keyName = "goodCrabColor",
name = "Good Crab color",
description = "The color of good crabs",
hidden = true,
unhide = "crabHandler"
)
default Color crabColor()
default Color goodCrabColor()
{
return Color.MAGENTA;
return new Color(255, 155, 245);
}
@ConfigItem(
position = 17,
parent = "roomConfig",
keyName = "rareCrabColor",
name = "Rare Crab color",
description = "The color of rare crabs",
hidden = true,
unhide = "crabHandler"
)
default Color rareCrabColor()
{
return new Color(255, 200, 0);
}
@ConfigItem(
@@ -457,15 +470,4 @@ public interface RaidsConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "hotkey",
name = "Toggle scout overlay",
description = "When pressed the scout overlay will be toggled. Must enable show scout overlay in raid",
position = 33
)
default Keybind hotkey()
{
return Keybind.NOT_SET;
}
}

View File

@@ -25,7 +25,6 @@
*/
package net.runelite.client.plugins.raids;
import com.google.common.collect.ImmutableList;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
@@ -35,8 +34,6 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import lombok.Getter;
import lombok.Setter;
@@ -71,42 +68,6 @@ public class RaidsOverlay extends Overlay
private static final int SMALL_ICON_SIZE = 21;
private static final int TITLE_COMPONENT_HEIGHT = 20;
private static final int LINE_COMPONENT_HEIGHT = 16;
private static final Pattern FIRST_HALF = Pattern.compile("Start, (.*), End,");
private static final Pattern SECOND_HALF = Pattern.compile(", Start, (.*), End");
private static final ImmutableList<String> goodCrabsFirst = ImmutableList.of(
"FSCCP.PCSCF - #WNWSWN#ESEENW",
"SCFCP.CSCFS - #ENEESW#ENWWSW",
"SCFPC.CSPCF - #WSWWNE#WSEENE",
"SCPFC.CCPSF - #NWWWSE#WNEESE",
"SCPFC.CSPCF - #NEEESW#WWNEEE",
"SCSPF.CCSPF - #ESWWNW#ESENES",
"SPCFC.CSPCF - #WWNEEE#WSWNWS",
"SCPFC.PCSCF - #WNEEES#NWSWNW", //rare crabs first bad crabs second
"SFCCPC.PCSCPF - #WSEENES#WWWNEEE", //good crabs first rare crabs second rare crabs third
"SCPFC.CCSSF - #NEESEN#WSWWNE" //good crabs
);
private static final ImmutableList<String> goodCrabsSecond = ImmutableList.of(
"FSCCP.PCSCF - #WNWSWN#ESEENW",
"FSCCS.PCPSF - #WSEEEN#WSWNWS",
"FSCPC.CSCPF - #WNWWSE#EENWWW",
"SCFCP.CCSPF - #ESEENW#ESWWNW",
"SCFCP.CSCFS - #ENEESW#ENWWSW",
"SCFPC.CSPCF - #WSWWNE#WSEENE",
"SCFPC.PCCSF - #WSEENE#WWWSEE",
"SCFPC.SCPCF - #NESENE#WSWWNE",
"SCPFC.CCPSF - #NWWWSE#WNEESE",
"SCPFC.CSPCF - #NEEESW#WWNEEE",
"SCPFC.CSPSF - #WWSEEE#NWSWWN",
"SCSPF.CCSPF - #ESWWNW#ESENES",
"SFCCP.CSCPF - #WNEESE#NWSWWN",
"SFCCS.PCPSF - #ENWWSW#ENESEN",
"SPCFC.CSPCF - #WWNEEE#WSWNWS",
"SPCFC.SCCPF - #ESENES#WWWNEE",
"SPSFP.CCCSF - #NWSWWN#ESEENW", //bad crabs first good crabs second
"SFCCPC.PCSCPF - #WSEENES#WWWNEEE", //good crabs first rare crabs second rare crabs third
"FSCCP.PCSCF - #ENWWWS#NEESEN", //bad crabs first good crabs second
"SCPFC.CCSSF - #NEESEN#WSWWNE" //good crabs
);
private final PanelComponent panelComponent = new PanelComponent();
private final ItemManager itemManager;
private final SpriteManager spriteManager;
@@ -116,17 +77,13 @@ public class RaidsOverlay extends Overlay
private RaidsConfig config;
@Setter
private boolean sharable = false;
@Getter
@Setter
private boolean scoutOverlayShown = false;
@Getter
private boolean scouterActive = false;
@Getter
private int width;
@Getter
private int height;
@@ -191,9 +148,6 @@ public class RaidsOverlay extends Overlay
{
color = Color.RED;
}
Matcher firstMatcher = FIRST_HALF.matcher(plugin.getRaid().getFullRotationString());
Matcher secondMatcher = SECOND_HALF.matcher(plugin.getRaid().getFullRotationString());
int combatCount = 0;
int roomCount = 0;
List<Integer> iceRooms = new ArrayList<>();
@@ -295,7 +249,7 @@ public class RaidsOverlay extends Overlay
.color(color)
.build());
if (recordRaid())
if (plugin.recordRaid() != null)
{
panelComponent.getChildren().add(TitleComponent.builder()
.text("Record Raid")
@@ -402,15 +356,20 @@ public class RaidsOverlay extends Overlay
}
if (config.crabHandler() && puzzleNameLC.equals("crabs"))
{
if (firstMatcher.find() && secondMatcher.find())
if (plugin.getGoodCrabs() == null)
{
if (crabHandler(firstMatcher.group(1), secondMatcher.group(1)))
color = Color.RED;
}
else
{
switch (plugin.getGoodCrabs())
{
color = config.crabColor();
}
else
{
color = Color.RED;
case "Good Crabs":
color = config.goodCrabColor();
break;
case "Rare Crabs":
color = config.rareCrabColor();
break;
}
}
}
@@ -508,26 +467,4 @@ public class RaidsOverlay extends Overlay
}
return ImageUtil.resizeCanvas(bim, SMALL_ICON_SIZE, SMALL_ICON_SIZE);
}
private boolean crabHandler(String firstHalf, String secondHalf)
{
return (firstHalf.contains("Crabs") && goodCrabsFirst.contains(plugin.getLayoutFullCode()))
|| (secondHalf.contains("Crabs") && goodCrabsSecond.contains(plugin.getLayoutFullCode()));
}
boolean recordRaid()
{
Matcher firstMatcher = FIRST_HALF.matcher(plugin.getRaid().getFullRotationString());
Matcher secondMatcher = SECOND_HALF.matcher(plugin.getRaid().getFullRotationString());
if (plugin.getRaid().getRotationString().toLowerCase().equals("vasa,tekton,vespula")
&& plugin.getRaid().getFullRotationString().toLowerCase().contains("crabs")
&& plugin.getRaid().getFullRotationString().toLowerCase().contains("tightrope"))
{
if (firstMatcher.find() && secondMatcher.find())
{
return (crabHandler(firstMatcher.group(1), secondMatcher.group(1)));
}
}
return false;
}
}

View File

@@ -25,6 +25,7 @@
*/
package net.runelite.client.plugins.raids;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.inject.Binder;
import com.google.inject.Provides;
@@ -38,7 +39,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
@@ -76,7 +76,6 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
@@ -84,7 +83,6 @@ import net.runelite.client.plugins.raids.solver.Layout;
import net.runelite.client.plugins.raids.solver.LayoutSolver;
import net.runelite.client.plugins.raids.solver.RotationSolver;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.OverlayMenuEntry;
@@ -92,15 +90,14 @@ import net.runelite.client.ui.overlay.WidgetOverlay;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.ui.overlay.tooltip.Tooltip;
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
import net.runelite.client.util.HotkeyListener;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text;
import org.apache.commons.lang3.StringUtils;
@PluginDescriptor(
name = "Chambers Of Xeric",
name = "CoX Scouter",
description = "Show helpful information for the Chambers of Xeric raid",
tags = {"combat", "raid", "overlay", "pve", "pvm", "bosses", "cox", "olm"},
tags = {"combat", "raid", "overlay", "pve", "pvm", "bosses", "cox", "olm", "scout"},
type = PluginType.PVM,
enabledByDefault = false
)
@@ -113,12 +110,40 @@ public class RaidsPlugin extends Plugin
private static final String RAID_START_MESSAGE = "The raid has begun!";
private static final String LEVEL_COMPLETE_MESSAGE = "level complete!";
private static final String RAID_COMPLETE_MESSAGE = "Congratulations - your raid is complete!";
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##");
private static final String SPLIT_REGEX = "\\s*,\\s*";
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##");
private static final Pattern ROTATION_REGEX = Pattern.compile("\\[(.*?)]");
private static final int LINE_COMPONENT_HEIGHT = 16;
private static final Pattern LEVEL_COMPLETE_REGEX = Pattern.compile("(.+) level complete! Duration: ([0-9:]+)");
private static final Pattern RAID_COMPLETE_REGEX = Pattern.compile("Congratulations - your raid is complete! Duration: ([0-9:]+)");
private static final ImmutableSet<String> GOOD_CRABS_FIRST = ImmutableSet.of(
"FSCCP.PCSCF - #WNWSWN#ESEENW", //both good crabs
"SCSPF.CCSPF - #ESWWNW#ESENES", //both good crabs
"SPCFC.CSPCF - #WWNEEE#WSWNWS", //both good crabs
"SCFCP.CSCFS - #ENEESW#ENWWSW", //good crabs
"SCPFC.CCSSF - #NEESEN#WSWWNE", //good crabs
"SCFPC.CSPCF - #WSWWNE#WSEENE" //good crabs first rare crabs second
);
private static final ImmutableSet<String> GOOD_CRABS_SECOND = ImmutableSet.of(
"SCFCP.CCSPF - #ESEENW#ESWWNW", //bad crabs first good crabs second
"SCPFC.CSPSF - #WWSEEE#NWSWWN", //bad crabs first good crabs second
"SFCCS.PCPSF - #ENWWSW#ENESEN", //bad crabs first good crabs second
"SPCFC.SCCPF - #ESENES#WWWNEE", //bad crabs first good crabs second
"SPSFP.CCCSF - #NWSWWN#ESEENW", //bad crabs first good crabs second
"FSCCP.PCSCF - #ENWWWS#NEESEN" //bad crabs first good crabs second
);
private static final ImmutableSet<String> RARE_CRABS_FIRST = ImmutableSet.of(
"SCPFC.CSPCF - #NEEESW#WWNEEE", //rare crabs first good crabs second
"SCPFC.PCSCF - #WNEEES#NWSWNW", //rare crabs first bad crabs second
"SCPFC.CCPSF - #NWWWSE#WNEESE" //both rare crabs
);
private static final ImmutableSet<String> RARE_CRABS_SECOND = ImmutableSet.of(
"FSCPC.CSCPF - #WNWWSE#EENWWW", //bad crabs first rare crabs second
"SCFPC.PCCSF - #WSEENE#WWWSEE", //bad crabs first rare crabs second
"SCFPC.SCPCF - #NESENE#WSWWNE", //bad crabs first rare crabs second
"SFCCP.CSCPF - #WNEESE#NWSWWN", //bad crabs first rare crabs second
"SCFPC.CSPCF - #WSWWNE#WSEENE" //good crabs first rare crabs second
);
private static final String TRIPLE_PUZZLE = "SFCCPC.PCSCPF - #WSEENES#WWWNEEE"; //good crabs first rare crabs second rare crabs third
private static final Pattern PUZZLES = Pattern.compile("Puzzle - (\\w+)");
@Getter
private final ArrayList<String> roomWhitelist = new ArrayList<>();
@Getter
@@ -129,7 +154,6 @@ public class RaidsPlugin extends Plugin
private final ArrayList<String> layoutWhitelist = new ArrayList<>();
@Getter
private final Map<String, List<Integer>> recommendedItemsList = new HashMap<>();
public boolean canShow;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
@@ -137,10 +161,6 @@ public class RaidsPlugin extends Plugin
@Inject
private Client client;
@Inject
private DrawManager drawManager;
@Inject
private ScheduledExecutorService executor;
@Inject
private RaidsConfig config;
@Inject
private OverlayManager overlayManager;
@@ -153,32 +173,21 @@ public class RaidsPlugin extends Plugin
@Inject
private LayoutSolver layoutSolver;
@Inject
private KeyManager keyManager;
@Inject
private SpriteManager spriteManager;
@Inject
private ClientThread clientThread;
@Inject
private TooltipManager tooltipManager;
@Inject
private ClientToolbar clientToolbar;
@Inject
private ItemManager itemManager;
@Getter
private Raid raid;
@Getter
private boolean inRaidChambers;
@Inject
private ClientToolbar clientToolbar;
private int upperTime = -1;
private int middleTime = -1;
private int lowerTime = -1;
private int raidTime = -1;
private WidgetOverlay widgetOverlay;
private String tooltip;
@Inject
private ItemManager itemManager;
private NavigationButton navButton;
private boolean raidStarted;
@Getter
private String layoutFullCode;
private RaidsTimer timer;
private String goodCrabs;
@Getter
private int startPlayerCount;
@Getter
@@ -187,6 +196,18 @@ public class RaidsPlugin extends Plugin
private List<String> startingPartyMembers = new ArrayList<>();
@Getter
private Set<String> missingPartyMembers = new HashSet<>();
@Getter
private String layoutFullCode;
@Getter
private boolean raidStarted;
private int upperTime = -1;
private int middleTime = -1;
private int lowerTime = -1;
private int raidTime = -1;
private WidgetOverlay widgetOverlay;
private String tooltip;
private NavigationButton navButton;
private RaidsTimer timer;
@Provides
RaidsConfig provideConfig(ConfigManager configManager)
@@ -209,7 +230,6 @@ public class RaidsPlugin extends Plugin
{
overlayManager.add(partyOverlay);
}
keyManager.registerKeyListener(hotkeyListener);
updateLists();
clientThread.invokeLater(() -> checkRaidPresence(true));
widgetOverlay = overlayManager.getWidgetOverlay(WidgetInfo.RAIDS_POINTS_INFOBOX);
@@ -236,13 +256,6 @@ public class RaidsPlugin extends Plugin
overlayManager.remove(partyOverlay);
}
infoBoxManager.removeInfoBox(timer);
keyManager.unregisterKeyListener(hotkeyListener);
inRaidChambers = false;
widgetOverlay = null;
raidStarted = false;
raid = null;
timer = null;
final Widget widget = client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX);
if (widget != null)
{
@@ -509,17 +522,18 @@ public class RaidsPlugin extends Plugin
}
partyMembers.clear();
for (int i = 0; i < widgets.length; i++)
for (Widget widget : widgets)
{
if (widgets[i] != null)
if (widget == null || widget.getText() == null)
{
// Party members names can be found as a color tagged string in every fourth(ish) of these children
String name = widgets[i].getName();
if (name.length() > 1)
{
// Clean away tag
partyMembers.add(name.substring(name.indexOf('>') + 1, name.indexOf('<', 1)));
}
continue;
}
String name = widget.getName();
if (name.length() > 1)
{
partyMembers.add(name.substring(name.indexOf('>') + 1, name.indexOf('<', 1)));
}
}
@@ -576,23 +590,43 @@ public class RaidsPlugin extends Plugin
return;
}
layoutFullCode = layout.getTest();
log.debug("Full Layout Code: " + layoutFullCode);
layoutFullCode = layout.getCode();
raid.updateLayout(layout);
RotationSolver.solve(raid.getCombatRooms());
overlay.setScoutOverlayShown(true);
setOverlayStatus(true);
sendRaidLayoutMessage();
Matcher puzzleMatch = PUZZLES.matcher(raid.getFullRotationString());
final List<String> puzzles = new ArrayList<>();
while (puzzleMatch.find())
{
puzzles.add(puzzleMatch.group());
}
if (raid.getFullRotationString().contains("Crabs"))
{
switch (puzzles.size())
{
case 1:
goodCrabs = handleCrabs(puzzles.get(0));
break;
case 2:
goodCrabs = handleCrabs(puzzles.get(0), puzzles.get(1));
break;
case 3:
goodCrabs = handleCrabs(puzzles.get(0), puzzles.get(1), puzzles.get(2));
break;
}
}
}
else if (!config.scoutOverlayAtBank())
{
overlay.setScoutOverlayShown(false);
setOverlayStatus(false);
}
}
// If we left party raid was started or we left raid
if (client.getVar(VarPlayer.IN_RAID_PARTY) == -1 && (!inRaidChambers || !config.scoutOverlayInRaid()))
{
overlay.setScoutOverlayShown(false);
setOverlayStatus(false);
raidStarted = false;
}
}
@@ -618,7 +652,7 @@ public class RaidsPlugin extends Plugin
.build())
.build());
if (overlay.recordRaid())
if (recordRaid() != null)
{
chatMessageManager.queue(QueuedMessage.builder()
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
@@ -983,6 +1017,10 @@ public class RaidsPlugin extends Plugin
lowerTime = -1;
raidTime = -1;
tooltip = null;
inRaidChambers = false;
widgetOverlay = null;
raidStarted = false;
timer = null;
}
private int timeToSeconds(String s)
@@ -1065,22 +1103,73 @@ public class RaidsPlugin extends Plugin
tooltip = builder.toString();
}
private final HotkeyListener hotkeyListener = new HotkeyListener(() -> config.hotkey())
private String handleCrabs(String firstGroup)
{
@Override
public void hotkeyPressed()
if (firstGroup.contains("Crabs") && GOOD_CRABS_FIRST.contains(layoutFullCode))
{
if (config.scoutOverlayInRaid() && raidStarted)
return "Good Crabs";
}
if (firstGroup.contains("Crabs") && RARE_CRABS_FIRST.contains(layoutFullCode))
{
return "Rare Crabs";
}
return null;
}
private String handleCrabs(String firstGroup, String secondGroup)
{
if (firstGroup.contains("Crabs") && GOOD_CRABS_FIRST.contains(layoutFullCode))
{
return "Good Crabs";
}
if (secondGroup.contains("Crabs") && GOOD_CRABS_SECOND.contains(layoutFullCode))
{
return "Good Crabs";
}
if (firstGroup.contains("Crabs") && RARE_CRABS_FIRST.contains(layoutFullCode))
{
return "Rare Crabs";
}
if (secondGroup.contains("Crabs") && RARE_CRABS_SECOND.contains(layoutFullCode))
{
return "Rare Crabs";
}
return null;
}
private String handleCrabs(String firstGroup, String secondGroup, String thirdGroup)
{
if (firstGroup.contains("Crabs"))
{
return "Good Crabs";
}
if (secondGroup.contains("Crabs"))
{
return "Rare Crabs";
}
if (thirdGroup.contains("Crabs"))
{
return "Rare Crabs";
}
return null;
}
String recordRaid()
{
if (raid.getRotationString().toLowerCase().equals("vasa,tekton,vespula")
&& raid.getFullRotationString().toLowerCase().contains("crabs")
&& raid.getFullRotationString().toLowerCase().contains("tightrope"))
{
if (goodCrabs != null)
{
if (overlay.isScoutOverlayShown())
{
overlay.setScoutOverlayShown(false);
}
else
{
overlay.setScoutOverlayShown(true);
}
return goodCrabs;
}
}
};
return null;
}
private void setOverlayStatus(boolean bool)
{
overlay.setScoutOverlayShown(bool);
}
}

View File

@@ -36,7 +36,7 @@ public class Layout
@Getter
@Setter
private String test;
private String code;
public void add(Room room)
{

View File

@@ -213,7 +213,7 @@ public class LayoutSolver
room.setPrevious(lastRoom);
lastRoom.setNext(room);
layout.add(room);
layout.setTest(code);
layout.setCode(code);
position += 8;
}

View File

@@ -98,9 +98,9 @@ class TargetWeaknessOverlay extends Overlay
final int healthScale = target.getHealth();
final int healthRatio = target.getHealthRatio();
final Integer maxHealth = npcManager.getHealth(target.getId());
final int maxHealth = npcManager.getHealth(target.getId());
if (healthRatio < 0 || healthScale <= 0 || maxHealth == null)
if (healthRatio < 0 || healthScale <= 0 || maxHealth == -1)
{
return -1;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* Copyright (c) 2019, Ganom <https://github.com/Ganom>
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,65 +25,125 @@
*/
package net.runelite.client.plugins.ticktimers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.awt.Color;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.runelite.api.Actor;
import net.runelite.api.AnimationID;
import net.runelite.api.NPC;
import net.runelite.api.NPCDefinition;
import net.runelite.api.NpcID;
import net.runelite.api.Prayer;
@Getter
class NPCContainer
{
@Getter
private NPC npc;
@Getter
private int npcIndex;
@Getter
private String npcName;
@Getter
private int npcSize;
private ImmutableSet<Integer> animations;
private int attackSpeed;
@Setter
@Getter
private int TicksUntilAttack;
private int ticksUntilAttack;
@Setter
@Getter
private int npcSpeed;
@Setter
@Getter
private Actor npcInteracting;
@Setter
@Getter
private Attackstyle attackStyle;
private AttackStyle attackStyle;
NPCContainer(NPC npc)
NPCContainer(NPC npc, int attackSpeed)
{
this.npc = npc;
this.npcName = npc.getName();
this.npcIndex = npc.getIndex();
this.npcInteracting = npc.getInteracting();
this.npcSpeed = 0;
this.attackStyle = Attackstyle.UNKNOWN;
this.TicksUntilAttack = 0;
this.attackStyle = AttackStyle.UNKNOWN;
this.attackSpeed = attackSpeed;
this.ticksUntilAttack = -1;
final NPCDefinition composition = npc.getTransformedDefinition();
BossMonsters monster = BossMonsters.of(npc.getId());
if (monster == null)
{
throw new IllegalStateException();
}
this.animations = monster.animations;
this.attackStyle = monster.attackStyle;
if (composition != null)
{
this.npcSize = composition.getSize();
}
}
@RequiredArgsConstructor
enum BossMonsters
{
SERGEANT_STRONGSTACK(NpcID.SERGEANT_STRONGSTACK, AttackStyle.MELEE, ImmutableSet.of(AnimationID.MINION_AUTO1, AnimationID.MINION_AUTO2, AnimationID.MINION_AUTO3)),
SERGEANT_STEELWILL(NpcID.SERGEANT_STEELWILL, AttackStyle.MAGE, ImmutableSet.of(AnimationID.MINION_AUTO1, AnimationID.MINION_AUTO2, AnimationID.MINION_AUTO3)),
SERGEANT_GRIMSPIKE(NpcID.SERGEANT_GRIMSPIKE, AttackStyle.RANGE, ImmutableSet.of(AnimationID.MINION_AUTO1, AnimationID.MINION_AUTO2, AnimationID.MINION_AUTO4)),
GENERAL_GRAARDOR(NpcID.GENERAL_GRAARDOR, AttackStyle.MELEE, ImmutableSet.of(AnimationID.GENERAL_AUTO1, AnimationID.GENERAL_AUTO2, AnimationID.GENERAL_AUTO3)),
TSTANON_KARLAK(NpcID.TSTANON_KARLAK, AttackStyle.MELEE, ImmutableSet.of(AnimationID.ZAMMY_GENERIC_AUTO)),
BALFRUG_KREEYATH(NpcID.BALFRUG_KREEYATH, AttackStyle.MAGE, ImmutableSet.of(AnimationID.ZAMMY_GENERIC_AUTO, AnimationID.BALFRUG_AUTO)),
ZAKLN_GRITCH(NpcID.ZAKLN_GRITCH, AttackStyle.RANGE, ImmutableSet.of(AnimationID.ZAMMY_GENERIC_AUTO, AnimationID.ZAKL_AUTO)),
KRIL_TSUTSAROTH(NpcID.KRIL_TSUTSAROTH, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.KRIL_SPEC, AnimationID.KRIL_AUTO)),
STARLIGHT(NpcID.STARLIGHT, AttackStyle.MELEE, ImmutableSet.of(AnimationID.STARLIGHT_AUTO)),
GROWLER(NpcID.GROWLER, AttackStyle.MAGE, ImmutableSet.of(AnimationID.GROWLER_AUTO)),
BREE(NpcID.BREE, AttackStyle.RANGE, ImmutableSet.of(AnimationID.BREE_AUTO)),
COMMANDER_ZILYANA(NpcID.COMMANDER_ZILYANA, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.ZILYANA_AUTO, AnimationID.ZILYANA_MELEE_AUTO, AnimationID.ZILYANA_SPEC)),
FLIGHT_KILISA(NpcID.FLIGHT_KILISA, AttackStyle.MELEE, ImmutableSet.of(AnimationID.KILISA_AUTO)),
FLOCKLEADER_GEERIN(NpcID.FLOCKLEADER_GEERIN, AttackStyle.MAGE, ImmutableSet.of(AnimationID.GEERIN_AUTO, AnimationID.GEERIN_FLINCH)),
WINGMAN_SKREE(NpcID.WINGMAN_SKREE, AttackStyle.RANGE, ImmutableSet.of(AnimationID.SKREE_AUTO)),
KREEARRA(NpcID.KREEARRA, AttackStyle.RANGE, ImmutableSet.of(AnimationID.KREE_RANGED)),
DAGANNOTH_REX(NpcID.DAGANNOTH_REX, AttackStyle.MAGE, ImmutableSet.of(AnimationID.DAG_REX)),
DAGANNOTH_SUPREME(NpcID.DAGANNOTH_SUPREME, AttackStyle.RANGE, ImmutableSet.of(AnimationID.DAG_SUPREME)),
DAGANNOTH_PRIME(NpcID.DAGANNOTH_PRIME, AttackStyle.MAGE, ImmutableSet.of(AnimationID.DAG_PRIME));
private static ImmutableMap<Integer, BossMonsters> idMap;
static
{
ImmutableMap.Builder<Integer, BossMonsters> builder = ImmutableMap.builder();
for (BossMonsters monster : values())
{
builder.put(monster.npcID, monster);
}
idMap = builder.build();
}
private final int npcID;
private final AttackStyle attackStyle;
private final ImmutableSet<Integer> animations;
static BossMonsters of(int npcID)
{
return idMap.get(npcID);
}
}
@AllArgsConstructor
@Getter
public enum Attackstyle
public enum AttackStyle
{
MAGE("Mage", Color.CYAN),
RANGE("Range", Color.GREEN),
MELEE("Melee", Color.RED),
UNKNOWN("Unknown", Color.WHITE);
MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC),
RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES),
MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE),
UNKNOWN("Unknown", Color.WHITE, null);
private String name = "";
private String name;
private Color color;
private Prayer prayer;
}
}

View File

@@ -23,6 +23,9 @@
*/
package net.runelite.client.plugins.ticktimers;
import java.awt.Font;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@@ -34,6 +37,54 @@ public interface TickTimersConfig extends Config
{
@ConfigItem(
position = 0,
keyName = "mainConfig",
name = "Main Config",
description = ""
)
default Stub mainConfig()
{
return new Stub();
}
@ConfigItem(
position = 1,
keyName = "prayerWidgetHelper",
name = "Prayer Widget Helper",
description = "Shows you which prayer to click and the time until click.",
parent = "mainConfig"
)
default boolean showPrayerWidgetHelper()
{
return false;
}
@ConfigItem(
position = 2,
keyName = "showHitSquares",
name = "Show Hit Squares",
description = "Shows you where the melee bosses can hit you from.",
parent = "mainConfig"
)
default boolean showHitSquares()
{
return false;
}
@ConfigItem(
position = 3,
keyName = "changeTickColor",
name = "Change Tick Color",
description = "If this is enabled, it will change the tick color to white" +
"<br> at 1 tick remaining, signaling you to swap.",
parent = "mainConfig"
)
default boolean changeTickColor()
{
return false;
}
@ConfigItem(
position = 4,
keyName = "bosses",
name = "Bosses",
description = ""
@@ -44,19 +95,31 @@ public interface TickTimersConfig extends Config
}
@ConfigItem(
position = 1,
keyName = "graardor",
name = "General Graardor",
description = "Show tick timers for General Graardor",
position = 5,
keyName = "gwd",
name = "God Wars Dungeon",
description = "Show tick timers for GWD Bosses. This must be enabled before you zone in.",
parent = "bosses"
)
default boolean graardor()
default boolean gwd()
{
return true;
}
@ConfigItem(
position = 22,
position = 6,
keyName = "dks",
name = "Dagannoth Kings",
description = "Show tick timers for Dagannoth Kings. This must be enabled before you zone in.",
parent = "bosses"
)
default boolean dks()
{
return true;
}
@ConfigItem(
position = 7,
keyName = "text",
name = "Text",
description = ""
@@ -67,7 +130,7 @@ public interface TickTimersConfig extends Config
}
@ConfigItem(
position = 23,
position = 8,
keyName = "fontStyle",
name = "Font Style",
description = "Plain | Bold | Italics",
@@ -75,7 +138,7 @@ public interface TickTimersConfig extends Config
)
default FontStyle fontStyle()
{
return FontStyle.PLAIN;
return FontStyle.BOLD;
}
@Range(
@@ -83,7 +146,7 @@ public interface TickTimersConfig extends Config
max = 40
)
@ConfigItem(
position = 24,
position = 9,
keyName = "textSize",
name = "Text Size",
description = "Text Size for Timers.",
@@ -95,7 +158,7 @@ public interface TickTimersConfig extends Config
}
@ConfigItem(
position = 25,
position = 10,
keyName = "shadows",
name = "Shadows",
description = "Adds Shadows to text.",
@@ -105,4 +168,22 @@ public interface TickTimersConfig extends Config
{
return false;
}
@Getter
@AllArgsConstructor
enum FontStyle
{
BOLD("Bold", Font.BOLD),
ITALIC("Italic", Font.ITALIC),
PLAIN("Plain", Font.PLAIN);
private String name;
private int font;
@Override
public String toString()
{
return getName();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* Copyright (c) 2019, Ganom <https://github.com/Ganom>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,13 +24,13 @@
package net.runelite.client.plugins.ticktimers;
import com.google.inject.Provides;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.AnimationID;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.NPC;
@@ -41,11 +41,11 @@ import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.NPCManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.overlay.OverlayManager;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor(
name = "Boss Tick Timers",
@@ -59,21 +59,24 @@ import org.apache.commons.lang3.ArrayUtils;
public class TickTimersPlugin extends Plugin
{
private static final int GENERAL_REGION = 11347;
private static final int ARMA_REGION = 11346;
private static final int SARA_REGION = 11601;
private static final int ZAMMY_REGION = 11603;
private static final int WATERBITH_REGION = 11589;
@Inject
private Client client;
@Inject
private OverlayManager overlayManager;
@Inject
private TimersOverlay timersOverlay;
@Inject
private TickTimersConfig config;
@Inject
private NPCManager npcManager;
@Getter(AccessLevel.PACKAGE)
private Map<NPC, NPCContainer> npcContainer = new HashMap<>();
private Set<NPCContainer> npcContainer = new HashSet<>();
private boolean validRegion;
@Provides
TickTimersConfig getConfig(ConfigManager configManager)
@@ -91,41 +94,71 @@ public class TickTimersPlugin extends Plugin
public void shutDown()
{
npcContainer.clear();
overlayManager.remove(timersOverlay);
validRegion = false;
}
@Subscribe
public void onGameStateChanged(GameStateChanged gameStateChanged)
{
if (gameStateChanged.getGameState() == GameState.LOGGED_IN)
{
if (isInGeneralRegion())
{
overlayManager.add(timersOverlay);
}
else
{
overlayManager.remove(timersOverlay);
}
}
if (gameStateChanged.getGameState() != GameState.LOGGED_IN)
{
return;
}
if (regionCheck())
{
validRegion = true;
overlayManager.add(timersOverlay);
}
else
{
validRegion = false;
overlayManager.remove(timersOverlay);
}
npcContainer.clear();
}
@Subscribe
public void onNpcSpawned(NpcSpawned event)
{
if (!validRegion)
{
return;
}
NPC npc = event.getNpc();
switch (npc.getId())
{
case NpcID.SERGEANT_STRONGSTACK:
case NpcID.SERGEANT_STEELWILL:
case NpcID.SERGEANT_GRIMSPIKE:
case NpcID.GENERAL_GRAARDOR:
case NpcID.GENERAL_GRAARDOR_6494:
npcContainer.put(npc, new NPCContainer(npc));
case NpcID.TSTANON_KARLAK:
case NpcID.BALFRUG_KREEYATH:
case NpcID.ZAKLN_GRITCH:
case NpcID.KRIL_TSUTSAROTH:
case NpcID.STARLIGHT:
case NpcID.BREE:
case NpcID.GROWLER:
case NpcID.COMMANDER_ZILYANA:
case NpcID.FLIGHT_KILISA:
case NpcID.FLOCKLEADER_GEERIN:
case NpcID.WINGMAN_SKREE:
case NpcID.KREEARRA:
if (config.gwd())
{
npcContainer.add(new NPCContainer(npc, npcManager.getAttackSpeed(npc.getId())));
}
break;
case NpcID.DAGANNOTH_REX:
case NpcID.DAGANNOTH_SUPREME:
case NpcID.DAGANNOTH_PRIME:
if (config.dks())
{
npcContainer.add(new NPCContainer(npc, npcManager.getAttackSpeed(npc.getId())));
}
break;
}
}
@@ -133,92 +166,76 @@ public class TickTimersPlugin extends Plugin
@Subscribe
public void onNpcDespawned(NpcDespawned event)
{
if (npcContainer.remove(event.getNpc()) != null && !npcContainer.isEmpty())
if (!validRegion)
{
npcContainer.remove(event.getNpc());
return;
}
NPC npc = event.getNpc();
switch (npc.getId())
{
case NpcID.SERGEANT_STRONGSTACK:
case NpcID.SERGEANT_STEELWILL:
case NpcID.SERGEANT_GRIMSPIKE:
case NpcID.GENERAL_GRAARDOR:
case NpcID.TSTANON_KARLAK:
case NpcID.BALFRUG_KREEYATH:
case NpcID.ZAKLN_GRITCH:
case NpcID.KRIL_TSUTSAROTH:
case NpcID.STARLIGHT:
case NpcID.BREE:
case NpcID.GROWLER:
case NpcID.COMMANDER_ZILYANA:
case NpcID.FLIGHT_KILISA:
case NpcID.FLOCKLEADER_GEERIN:
case NpcID.WINGMAN_SKREE:
case NpcID.KREEARRA:
case NpcID.DAGANNOTH_REX:
case NpcID.DAGANNOTH_SUPREME:
case NpcID.DAGANNOTH_PRIME:
npcContainer.removeIf(c -> c.getNpc() == npc);
break;
}
}
@Subscribe
public void onGameTick(GameTick Event)
{
if (config.graardor())
if (!validRegion)
{
graardorHandler();
return;
}
handleBosses();
}
private void graardorHandler()
private void handleBosses()
{
for (NPCContainer npcs : getNpcContainer().values())
for (NPCContainer npcs : getNpcContainer())
{
switch (npcs.getNpc().getId())
if (npcs.getTicksUntilAttack() >= 0)
{
case NpcID.SERGEANT_STRONGSTACK:
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
npcs.setAttackStyle(NPCContainer.Attackstyle.MELEE);
switch (npcs.getNpc().getAnimation())
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
}
for (int anims : npcs.getAnimations())
{
if (anims == npcs.getNpc().getAnimation())
{
if (npcs.getTicksUntilAttack() < 1)
{
case AnimationID.MINION_AUTO1:
case AnimationID.MINION_AUTO2:
if (npcs.getTicksUntilAttack() < 1)
{
npcs.setTicksUntilAttack(5);
}
break;
npcs.setTicksUntilAttack(npcs.getAttackSpeed());
}
break;
case NpcID.SERGEANT_STEELWILL:
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
npcs.setAttackStyle(NPCContainer.Attackstyle.MAGE);
switch (npcs.getNpc().getAnimation())
{
case AnimationID.MINION_AUTO1:
case AnimationID.MINION_AUTO2:
case AnimationID.MINION_AUTO3:
if (npcs.getTicksUntilAttack() < 1)
{
npcs.setTicksUntilAttack(5);
}
break;
}
case NpcID.SERGEANT_GRIMSPIKE:
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
npcs.setAttackStyle(NPCContainer.Attackstyle.RANGE);
switch (npcs.getNpc().getAnimation())
{
case AnimationID.MINION_AUTO1:
case AnimationID.MINION_AUTO2:
case AnimationID.MINION_AUTO4:
if (npcs.getTicksUntilAttack() < 1)
{
npcs.setTicksUntilAttack(5);
}
break;
}
break;
case NpcID.GENERAL_GRAARDOR:
case NpcID.GENERAL_GRAARDOR_6494:
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
npcs.setAttackStyle(NPCContainer.Attackstyle.MELEE);
switch (npcs.getNpc().getAnimation())
{
case AnimationID.GENERAL_AUTO1:
case AnimationID.GENERAL_AUTO2:
case AnimationID.GENERAL_AUTO3:
if (npcs.getTicksUntilAttack() < 1)
{
npcs.setTicksUntilAttack(6);
}
break;
}
break;
}
}
}
}
private boolean isInGeneralRegion()
private boolean regionCheck()
{
return ArrayUtils.contains(client.getMapRegions(), GENERAL_REGION);
return Arrays.stream(client.getMapRegions()).anyMatch(
x -> x == ARMA_REGION || x == GENERAL_REGION || x == ZAMMY_REGION || x == SARA_REGION || x == WATERBITH_REGION
);
}
}
}

View File

@@ -24,19 +24,17 @@
*/
package net.runelite.client.plugins.ticktimers;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.util.List;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.NPC;
import net.runelite.api.NPCDefinition;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldArea;
import net.runelite.api.coords.WorldPoint;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
@@ -63,67 +61,91 @@ public class TimersOverlay extends Overlay
@Override
public Dimension render(Graphics2D graphics)
{
Color tickcolor;
for (NPCContainer npcs : plugin.getNpcContainer().values())
for (NPCContainer npc : plugin.getNpcContainer())
{
renderNpcOverlay(graphics, npcs.getNpc(), npcs.getAttackStyle().getColor(), 100, 10);
final int ticksLeft = npcs.getTicksUntilAttack();
if (ticksLeft > 0)
if (npc.getNpc() == null)
{
if (ticksLeft == 1)
continue;
}
int ticksLeft = npc.getTicksUntilAttack();
final List<WorldPoint> hitSquares = getHitSquares(npc.getNpc().getWorldLocation(), npc.getNpcSize(), 1, false);
final NPCContainer.AttackStyle attackStyle = npc.getAttackStyle();
if (config.showHitSquares() && attackStyle.getName().equals("Melee"))
{
for (WorldPoint p : hitSquares)
{
tickcolor = npcs.getAttackStyle().getColor();
OverlayUtil.drawTile(graphics, client, p, client.getLocalPlayer().getWorldLocation(), attackStyle.getColor(), 0, 0, 50);
}
else
}
if (ticksLeft <= 0)
{
continue;
}
final String ticksLeftStr = String.valueOf(ticksLeft);
final int font = config.fontStyle().getFont();
final boolean shadows = config.shadows();
Color color = (ticksLeft <= 1 ? Color.WHITE : attackStyle.getColor());
if (!config.changeTickColor())
{
color = attackStyle.getColor();
}
final Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, Integer.toString(ticksLeft), 0);
OverlayUtil.renderTextLocation(graphics, ticksLeftStr, config.textSize(), font, color, canvasPoint, shadows, 0);
if (config.showPrayerWidgetHelper() && attackStyle.getPrayer() != null)
{
Rectangle bounds = OverlayUtil.renderPrayerOverlay(graphics, client, attackStyle.getPrayer(), color);
if (bounds != null)
{
tickcolor = Color.WHITE;
renderTextLocation(graphics, ticksLeftStr, 16, config.fontStyle().getFont(), color, centerPoint(bounds), shadows);
}
final String ticksLeftStr = String.valueOf(ticksLeft);
Point canvasPoint = npcs.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
renderTextLocation(graphics, ticksLeftStr, config.textSize(), config.fontStyle().getFont(), tickcolor, canvasPoint);
}
}
return null;
}
private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineAlpha, int fillAlpha)
{
int size = 1;
NPCDefinition composition = actor.getTransformedDefinition();
if (composition != null)
{
size = composition.getSize();
}
LocalPoint lp = actor.getLocalLocation();
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size);
if (tilePoly != null)
{
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
graphics.setStroke(new BasicStroke(2));
graphics.draw(tilePoly);
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
graphics.fill(tilePoly);
}
}
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint)
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows)
{
graphics.setFont(new Font("Arial", fontStyle, fontSize));
if (canvasPoint != null)
{
final Point canvasCenterPoint = new Point(
canvasPoint.getX(),
canvasPoint.getY());
canvasPoint.getX() - 3,
canvasPoint.getY() + 6);
final Point canvasCenterPoint_shadow = new Point(
canvasPoint.getX() + 1,
canvasPoint.getY() + 1);
if (config.shadows())
canvasPoint.getX() - 2,
canvasPoint.getY() + 7);
if (shadows)
{
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
}
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
}
}
private List<WorldPoint> getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder)
{
List<WorldPoint> little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList();
List<WorldPoint> big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList();
if (!includeUnder)
{
big.removeIf(little::contains);
}
return big;
}
private Point centerPoint(Rectangle rect)
{
int x = (int) (rect.getX() + rect.getWidth() / 2);
int y = (int) (rect.getY() + rect.getHeight() / 2);
return new Point(x, y);
}
}

View File

@@ -1,16 +1,20 @@
/*******************************************************************************
* Copyright (c) 2019. PKLite
* Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file.
* If there are any questions comments, or feedback about this software, please direct all inquiries directly to the following authors:
*
* PKLite discord: https://discord.gg/Dp3HuFM
* Written by PKLite(ST0NEWALL, others) <stonewall@stonewall@pklite.xyz>, 2019
*
******************************************************************************/
/*
* ******************************************************************************
* * Copyright (c) 2019 RuneLitePlus
* * Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file.
* * If there are any questions comments, or feedback about this software, please direct all inquiries directly to the file authors:
* * ST0NEWALL#9112
* * RuneLitePlus Discord: https://discord.gg/Q7wFtCe
* * RuneLitePlus website: https://runelitepl.us
* *****************************************************************************
*/
package net.runelite.client.plugins.whalewatchers;
import com.google.inject.Provides;
import java.util.EnumSet;
import java.util.Objects;
import javax.inject.Inject;
import lombok.Getter;
import net.runelite.api.Client;
@@ -21,9 +25,9 @@ import net.runelite.api.Skill;
import net.runelite.api.SkullIcon;
import net.runelite.api.VarPlayer;
import net.runelite.api.Varbits;
import static net.runelite.api.WorldType.HIGH_RISK;
import static net.runelite.api.WorldType.PVP;
import net.runelite.api.WorldType;
import static net.runelite.api.WorldType.isPvpWorld;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.HitsplatApplied;
import net.runelite.api.events.ItemContainerChanged;
@@ -50,7 +54,9 @@ import org.apache.commons.lang3.ObjectUtils;
public class WhaleWatchersPlugin extends Plugin
{
public boolean enableOverlay = false;
private static final String CONFIG_GROUP_NAME = "WhaleWatchers";
public boolean protectItemOverlay = false;
public int damageDone = 0;
public int damageTaken = 0;
public boolean inCombat = false;
@@ -83,11 +89,7 @@ public class WhaleWatchersPlugin extends Plugin
@Subscribe
public void onOverlayMenuClicked(OverlayMenuClicked event)
{
if (!event.getOverlay().equals(overlay))
{
return;
}
else
if (event.getOverlay().equals(overlay))
{
if (event.getEntry().getOption().equals("Reset"))
{
@@ -116,6 +118,28 @@ public class WhaleWatchersPlugin extends Plugin
resetDamageCounter();
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals(CONFIG_GROUP_NAME))
{
return;
}
if (!config.protectItemWarning())
{
protectItemOverlay = false;
}
if (!config.gloryWarning())
{
displayGloryOverlay = false;
}
if (!config.smiteableWarning())
{
displaySmiteOverlay = false;
}
}
@Subscribe
public void onHitsplatApplied(HitsplatApplied event)
@@ -186,28 +210,32 @@ public class WhaleWatchersPlugin extends Plugin
{
try
{
if (client.getLocalPlayer().getSkullIcon() == (SkullIcon.SKULL))
final SkullIcon skullIcon = Objects.requireNonNull(client.getLocalPlayer().getSkullIcon());
final EnumSet worldTypes = client.getWorldType();
if (WorldType.isHighRiskWorld(worldTypes))
{
if (client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 0 && client.getVar(Varbits.IN_WILDERNESS) == 1 ||
client.getWorldType().contains(PVP))
{
enableOverlay = true;
}
if (client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1 || client.getVar(Varbits.IN_WILDERNESS) == 0 ||
client.getWorldType().contains(HIGH_RISK) || client.getWorld() == 365)
{
enableOverlay = false;
}
protectItemOverlay = false;
return;
}
else
if (skullIcon.equals(SkullIcon.SKULL))
{
enableOverlay = false;
if (WorldType.isPvpWorld(worldTypes) || WorldType.isDeadmanWorld(worldTypes) ||
client.getVar(Varbits.IN_WILDERNESS) == 1)
{
protectItemOverlay = client.getRealSkillLevel(Skill.PRAYER) > 25 &&
client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 0;
}
else
{
protectItemOverlay = false;
}
}
}
catch (NullPointerException e)
{
// local player isn't skulled
}
}
}

View File

@@ -1,12 +1,14 @@
/*******************************************************************************
* Copyright (c) 2019. PKLite
* Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file.
* If there are any questions comments, or feedback about this software, please direct all inquiries directly to the following authors:
*
* PKLite discord: https://discord.gg/Dp3HuFM
* Written by PKLite(ST0NEWALL, others) <stonewall@stonewall@pklite.xyz>, 2019
*
******************************************************************************/
/*
* ******************************************************************************
* * Copyright (c) 2019 RuneLitePlus
* * Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file.
* * If there are any questions comments, or feedback about this software, please direct all inquiries directly to the file authors:
* * ST0NEWALL#9112
* * RuneLitePlus Discord: https://discord.gg/Q7wFtCe
* * RuneLitePlus website: https://runelitepl.us
* *****************************************************************************
*/
package net.runelite.client.plugins.whalewatchers;
@@ -49,7 +51,7 @@ public class WhaleWatchersProtOverlay extends Overlay
@Override
public Dimension render(Graphics2D graphics)
{
if (plugin.enableOverlay && config.protectItemWarning())
if (plugin.protectItemOverlay && config.protectItemWarning())
{
Rectangle rectangle = new Rectangle();
rectangle.setBounds(client.getCanvas().getBounds());

View File

@@ -278,6 +278,12 @@ public class XpGlobesOverlay extends Overlay
String xpHrString = decimalFormat.format(xpHr);
tableComponent.addRow(ColorUtil.prependColorTag("XP per hour:", Color.ORANGE), xpHrString);
}
if (config.enableTimeToLevel())
{
String timeLeft = xpTrackerService.getTimeTillGoal(mouseOverSkill.getSkill());
tableComponent.addRow(ColorUtil.prependColorTag("TimeLeft:", Color.ORANGE), timeLeft);
}
}
xpTooltip.getChildren().add(tableComponent);

View File

@@ -126,9 +126,9 @@ class XpState
* @param npc currently interacted NPC
* @param npcHealth health of currently interacted NPC
*/
void updateNpcExperience(Skill skill, NPC npc, Integer npcHealth)
void updateNpcExperience(Skill skill, NPC npc, int npcHealth)
{
if (npc == null || npc.getCombatLevel() <= 0 || npcHealth == null)
if (npc == null || npc.getCombatLevel() <= 0 || npcHealth == -1)
{
return;
}
@@ -170,11 +170,11 @@ class XpState
* @param npcHealth max health of npc that just died
* @return UPDATED in case new kill was successfully added
*/
XpUpdateResult updateNpcKills(Skill skill, NPC npc, Integer npcHealth)
XpUpdateResult updateNpcKills(Skill skill, NPC npc, int npcHealth)
{
XpStateSingle state = getSkill(skill);
if (state.getXpGained() <= 0 || npcHealth == null || npc != interactedNPC)
if (state.getXpGained() <= 0 || npcHealth == -1 || npc != interactedNPC)
{
return XpUpdateResult.NO_CHANGE;
}

View File

@@ -28,8 +28,10 @@ import com.google.common.base.Strings;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.Area;
@@ -38,8 +40,11 @@ import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.Prayer;
import net.runelite.api.TileObject;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.widgets.Widget;
/**
@@ -259,8 +264,7 @@ public class OverlayUtil
return result;
}
public static void renderActorTextAndImage(Graphics2D graphics, Actor actor, String text, Color color,
BufferedImage image, int yOffset, int xOffset)
public static void renderActorTextAndImage(Graphics2D graphics, Actor actor, String text, Color color, BufferedImage image, int yOffset, int xOffset)
{
Point textLocation = new Point(actor.getConvexHull().getBounds().x + xOffset,
actor.getConvexHull().getBounds().y + yOffset);
@@ -271,4 +275,69 @@ public class OverlayUtil
textLocation = new Point(textLocation.getX() + xOffset, textLocation.getY() + image.getHeight() - yOffset);
renderTextLocation(graphics, textLocation, text, color);
}
public static void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows, int yOffset)
{
graphics.setFont(new Font("Arial", fontStyle, fontSize));
if (canvasPoint != null)
{
final Point canvasCenterPoint = new Point(
canvasPoint.getX(),
canvasPoint.getY() + yOffset);
final Point canvasCenterPoint_shadow = new Point(
canvasPoint.getX() + 1,
canvasPoint.getY() + 1);
if (shadows)
{
renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
}
renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
}
}
public static void drawTile(Graphics2D graphics, Client client, WorldPoint point, WorldPoint playerPoint, Color color, int strokeWidth, int outlineAlpha, int fillAlpha)
{
if (point.distanceTo(playerPoint) >= 32)
{
return;
}
LocalPoint lp = LocalPoint.fromWorld(client, point);
if (lp == null)
{
return;
}
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
if (poly == null)
{
return;
}
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
graphics.setStroke(new BasicStroke(strokeWidth));
graphics.draw(poly);
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
graphics.fill(poly);
}
public static Rectangle renderPrayerOverlay(Graphics2D graphics, Client client, Prayer prayer, Color color)
{
Widget widget = client.getWidget(prayer.getWidgetInfo());
if (widget == null || widget.isHidden())
{
return null;
}
Rectangle bounds = widget.getBounds();
renderPolygon(graphics, rectangleToPolygon(bounds), color);
return bounds;
}
private static Polygon rectangleToPolygon(Rectangle rect)
{
int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x};
int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height};
return new Polygon(xpoints, ypoints, 4);
}
}