oops
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.dpscounter;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("dpscounter")
|
||||
public interface DpsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "showDamage",
|
||||
name = "Show damage",
|
||||
description = "Show total damage instead of DPS"
|
||||
)
|
||||
default boolean showDamage()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "autopause",
|
||||
name = "Auto pause",
|
||||
description = "Pause the DPS tracker when a boss dies"
|
||||
)
|
||||
default boolean autopause()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,293 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.dpscounter;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Hitsplat;
|
||||
import net.runelite.api.NPC;
|
||||
import static net.runelite.api.NpcID.*;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.HitsplatApplied;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.OverlayMenuClicked;
|
||||
import net.runelite.client.events.PartyChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ws.PartyMember;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import net.runelite.client.ws.WSClient;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "DPS Counter",
|
||||
description = "Counts damage (per second) by a party",
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Slf4j
|
||||
public class DpsCounterPlugin extends Plugin
|
||||
{
|
||||
private static final ImmutableSet<Integer> BOSSES = ImmutableSet.of(
|
||||
ABYSSAL_SIRE, ABYSSAL_SIRE_5887, ABYSSAL_SIRE_5888, ABYSSAL_SIRE_5889, ABYSSAL_SIRE_5890, ABYSSAL_SIRE_5891, ABYSSAL_SIRE_5908,
|
||||
CALLISTO, CALLISTO_6609,
|
||||
CERBERUS, CERBERUS_5863, CERBERUS_5866,
|
||||
CHAOS_ELEMENTAL, CHAOS_ELEMENTAL_6505,
|
||||
CORPOREAL_BEAST,
|
||||
GENERAL_GRAARDOR, GENERAL_GRAARDOR_6494,
|
||||
GIANT_MOLE, GIANT_MOLE_6499,
|
||||
KALPHITE_QUEEN, KALPHITE_QUEEN_963, KALPHITE_QUEEN_965, KALPHITE_QUEEN_4303, KALPHITE_QUEEN_4304, KALPHITE_QUEEN_6500, KALPHITE_QUEEN_6501,
|
||||
KING_BLACK_DRAGON, KING_BLACK_DRAGON_2642, KING_BLACK_DRAGON_6502,
|
||||
KRIL_TSUTSAROTH, KRIL_TSUTSAROTH_6495,
|
||||
SARACHNIS,
|
||||
VENENATIS, VENENATIS_6610,
|
||||
VETION, VETION_REBORN,
|
||||
|
||||
// ToB
|
||||
THE_MAIDEN_OF_SUGADINTI, THE_MAIDEN_OF_SUGADINTI_8361, THE_MAIDEN_OF_SUGADINTI_8362, THE_MAIDEN_OF_SUGADINTI_8363, THE_MAIDEN_OF_SUGADINTI_8364, THE_MAIDEN_OF_SUGADINTI_8365,
|
||||
PESTILENT_BLOAT,
|
||||
NYLOCAS_VASILIAS, NYLOCAS_VASILIAS_8355, NYLOCAS_VASILIAS_8356, NYLOCAS_VASILIAS_8357,
|
||||
SOTETSEG, SOTETSEG_8388,
|
||||
XARPUS_8340, XARPUS_8341,
|
||||
VERZIK_VITUR_8370,
|
||||
VERZIK_VITUR_8372,
|
||||
VERZIK_VITUR_8374,
|
||||
|
||||
// CoX
|
||||
TEKTON, TEKTON_7541, TEKTON_7542, TEKTON_ENRAGED, TEKTON_ENRAGED_7544, TEKTON_7545,
|
||||
VESPULA, VESPULA_7531, VESPULA_7532, ABYSSAL_PORTAL,
|
||||
VANGUARD, VANGUARD_7526, VANGUARD_7527, VANGUARD_7528, VANGUARD_7529,
|
||||
GREAT_OLM, GREAT_OLM_LEFT_CLAW, GREAT_OLM_RIGHT_CLAW_7553, GREAT_OLM_7554, GREAT_OLM_LEFT_CLAW_7555,
|
||||
DEATHLY_RANGER, DEATHLY_MAGE,
|
||||
MUTTADILE, MUTTADILE_7562, MUTTADILE_7563,
|
||||
VASA_NISTIRIO, VASA_NISTIRIO_7567,
|
||||
GUARDIAN, GUARDIAN_7570, GUARDIAN_7571, GUARDIAN_7572,
|
||||
LIZARDMAN_SHAMAN_7573, LIZARDMAN_SHAMAN_7574,
|
||||
ICE_DEMON, ICE_DEMON_7585,
|
||||
SKELETAL_MYSTIC, SKELETAL_MYSTIC_7605, SKELETAL_MYSTIC_7606,
|
||||
|
||||
THE_NIGHTMARE, THE_NIGHTMARE_9426, THE_NIGHTMARE_9427, THE_NIGHTMARE_9428, THE_NIGHTMARE_9429, THE_NIGHTMARE_9430, THE_NIGHTMARE_9431, THE_NIGHTMARE_9432, THE_NIGHTMARE_9433
|
||||
);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private PartyService partyService;
|
||||
|
||||
@Inject
|
||||
private WSClient wsClient;
|
||||
|
||||
@Inject
|
||||
private DpsOverlay dpsOverlay;
|
||||
|
||||
@Inject
|
||||
private DpsConfig dpsConfig;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Map<String, DpsMember> members = new ConcurrentHashMap<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final DpsMember total = new DpsMember("Total");
|
||||
|
||||
@Provides
|
||||
DpsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(DpsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
total.reset();
|
||||
overlayManager.add(dpsOverlay);
|
||||
wsClient.registerMessage(DpsUpdate.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
wsClient.unregisterMessage(DpsUpdate.class);
|
||||
overlayManager.remove(dpsOverlay);
|
||||
members.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPartyChanged(PartyChanged partyChanged)
|
||||
{
|
||||
members.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onHitsplatApplied(HitsplatApplied hitsplatApplied)
|
||||
{
|
||||
Player player = client.getLocalPlayer();
|
||||
Actor actor = hitsplatApplied.getActor();
|
||||
if (!(actor instanceof NPC))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Hitsplat hitsplat = hitsplatApplied.getHitsplat();
|
||||
|
||||
switch (hitsplat.getHitsplatType())
|
||||
{
|
||||
case DAMAGE_ME:
|
||||
int hit = hitsplat.getAmount();
|
||||
// Update local member
|
||||
PartyMember localMember = partyService.getLocalMember();
|
||||
// If not in a party, user local player name
|
||||
final String name = localMember == null ? player.getName() : localMember.getName();
|
||||
DpsMember dpsMember = members.computeIfAbsent(name, DpsMember::new);
|
||||
dpsMember.addDamage(hit);
|
||||
|
||||
// broadcast damage
|
||||
if (localMember != null)
|
||||
{
|
||||
final DpsUpdate specialCounterUpdate = new DpsUpdate(hit);
|
||||
specialCounterUpdate.setMemberId(localMember.getMemberId());
|
||||
wsClient.send(specialCounterUpdate);
|
||||
}
|
||||
// apply to total
|
||||
break;
|
||||
case DAMAGE_OTHER:
|
||||
final int npcId = ((NPC) actor).getId();
|
||||
boolean isBoss = BOSSES.contains(npcId);
|
||||
if (actor != player.getInteracting() && !isBoss)
|
||||
{
|
||||
// only track damage to npcs we are attacking, or is a nearby common boss
|
||||
return;
|
||||
}
|
||||
// apply to total
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
unpause();
|
||||
total.addDamage(hitsplat.getAmount());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDpsUpdate(DpsUpdate dpsUpdate)
|
||||
{
|
||||
if (partyService.getLocalMember().getMemberId().equals(dpsUpdate.getMemberId()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String name = partyService.getMemberById(dpsUpdate.getMemberId()).getName();
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unpause();
|
||||
|
||||
DpsMember dpsMember = members.computeIfAbsent(name, DpsMember::new);
|
||||
dpsMember.addDamage(dpsUpdate.getHit());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onOverlayMenuClicked(OverlayMenuClicked event)
|
||||
{
|
||||
if (event.getEntry() == DpsOverlay.RESET_ENTRY)
|
||||
{
|
||||
members.clear();
|
||||
total.reset();
|
||||
}
|
||||
else if (event.getEntry() == DpsOverlay.UNPAUSE_ENTRY)
|
||||
{
|
||||
unpause();
|
||||
}
|
||||
else if (event.getEntry() == DpsOverlay.PAUSE_ENTRY)
|
||||
{
|
||||
pause();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned npcDespawned)
|
||||
{
|
||||
NPC npc = npcDespawned.getNpc();
|
||||
|
||||
if (npc.isDead() && BOSSES.contains(npc.getId()))
|
||||
{
|
||||
log.debug("Boss has died!");
|
||||
|
||||
if (dpsConfig.autopause())
|
||||
{
|
||||
pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void pause()
|
||||
{
|
||||
if (total.isPaused())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Pausing");
|
||||
|
||||
for (DpsMember dpsMember : members.values())
|
||||
{
|
||||
dpsMember.pause();
|
||||
}
|
||||
total.pause();
|
||||
|
||||
dpsOverlay.setPaused(true);
|
||||
}
|
||||
|
||||
private void unpause()
|
||||
{
|
||||
if (!total.isPaused())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Unpausing");
|
||||
|
||||
for (DpsMember dpsMember : members.values())
|
||||
{
|
||||
dpsMember.unpause();
|
||||
}
|
||||
total.unpause();
|
||||
|
||||
dpsOverlay.setPaused(false);
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.dpscounter;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
class DpsMember
|
||||
{
|
||||
private final String name;
|
||||
private Instant start;
|
||||
private Instant end;
|
||||
private int damage;
|
||||
|
||||
void addDamage(int amount)
|
||||
{
|
||||
if (start == null)
|
||||
{
|
||||
start = Instant.now();
|
||||
}
|
||||
|
||||
damage += amount;
|
||||
}
|
||||
|
||||
float getDps()
|
||||
{
|
||||
if (start == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Instant now = end == null ? Instant.now() : end;
|
||||
int diff = (int) (now.toEpochMilli() - start.toEpochMilli()) / 1000;
|
||||
if (diff == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (float) damage / (float) diff;
|
||||
}
|
||||
|
||||
void pause()
|
||||
{
|
||||
end = Instant.now();
|
||||
}
|
||||
|
||||
boolean isPaused()
|
||||
{
|
||||
return start == null || end != null;
|
||||
}
|
||||
|
||||
void unpause()
|
||||
{
|
||||
if (end == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
start = start.plus(Duration.between(end, Instant.now()));
|
||||
end = null;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
damage = 0;
|
||||
start = end = Instant.now();
|
||||
}
|
||||
|
||||
Duration elapsed()
|
||||
{
|
||||
return Duration.between(start, end == null ? Instant.now() : end);
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.dpscounter;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
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.TitleComponent;
|
||||
import net.runelite.client.ui.overlay.tooltip.Tooltip;
|
||||
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
|
||||
class DpsOverlay extends Overlay
|
||||
{
|
||||
private static final DecimalFormat DPS_FORMAT = new DecimalFormat("#0.0");
|
||||
private static final int PANEL_WIDTH_OFFSET = 10; // assumes 8 for panel component border + 2px between left and right
|
||||
|
||||
static final OverlayMenuEntry RESET_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Reset", "DPS counter");
|
||||
static final OverlayMenuEntry PAUSE_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Pause", "DPS counter");
|
||||
static final OverlayMenuEntry UNPAUSE_ENTRY = new OverlayMenuEntry(RUNELITE_OVERLAY, "Unpause", "DPS counter");
|
||||
|
||||
private final DpsCounterPlugin dpsCounterPlugin;
|
||||
private final DpsConfig dpsConfig;
|
||||
private final PartyService partyService;
|
||||
private final Client client;
|
||||
private final TooltipManager tooltipManager;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
DpsOverlay(DpsCounterPlugin dpsCounterPlugin, DpsConfig dpsConfig, PartyService partyService, Client client,
|
||||
TooltipManager tooltipManager)
|
||||
{
|
||||
super(dpsCounterPlugin);
|
||||
this.dpsCounterPlugin = dpsCounterPlugin;
|
||||
this.dpsConfig = dpsConfig;
|
||||
this.partyService = partyService;
|
||||
this.client = client;
|
||||
this.tooltipManager = tooltipManager;
|
||||
getMenuEntries().add(RESET_ENTRY);
|
||||
setPaused(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseOver()
|
||||
{
|
||||
DpsMember total = dpsCounterPlugin.getTotal();
|
||||
Duration elapsed = total.elapsed();
|
||||
long s = elapsed.getSeconds();
|
||||
String format;
|
||||
if (s >= 3600)
|
||||
{
|
||||
format = String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60));
|
||||
}
|
||||
else
|
||||
{
|
||||
format = String.format("%d:%02d", s / 60, (s % 60));
|
||||
}
|
||||
tooltipManager.add(new Tooltip("Elapsed time: " + format));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Map<String, DpsMember> dpsMembers = dpsCounterPlugin.getMembers();
|
||||
if (dpsMembers.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean inParty = !partyService.getMembers().isEmpty();
|
||||
boolean showDamage = dpsConfig.showDamage();
|
||||
DpsMember total = dpsCounterPlugin.getTotal();
|
||||
boolean paused = total.isPaused();
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
final String title = (inParty ? "Party " : "") + (showDamage ? "Damage" : "DPS") + (paused ? " (paused)" : "");
|
||||
panelComponent.getChildren().add(
|
||||
TitleComponent.builder()
|
||||
.text(title)
|
||||
.build());
|
||||
|
||||
int maxWidth = ComponentConstants.STANDARD_WIDTH;
|
||||
FontMetrics fontMetrics = graphics.getFontMetrics();
|
||||
|
||||
for (DpsMember dpsMember : dpsMembers.values())
|
||||
{
|
||||
String left = dpsMember.getName();
|
||||
String right = showDamage ? QuantityFormatter.formatNumber(dpsMember.getDamage()) : DPS_FORMAT.format(dpsMember.getDps());
|
||||
maxWidth = Math.max(maxWidth, fontMetrics.stringWidth(left) + fontMetrics.stringWidth(right));
|
||||
panelComponent.getChildren().add(
|
||||
LineComponent.builder()
|
||||
.left(left)
|
||||
.right(right)
|
||||
.build());
|
||||
}
|
||||
|
||||
panelComponent.setPreferredSize(new Dimension(maxWidth + PANEL_WIDTH_OFFSET, 0));
|
||||
|
||||
if (!inParty)
|
||||
{
|
||||
Player player = client.getLocalPlayer();
|
||||
if (player.getName() != null)
|
||||
{
|
||||
DpsMember self = dpsMembers.get(player.getName());
|
||||
|
||||
if (self != null && total.getDamage() > self.getDamage())
|
||||
{
|
||||
panelComponent.getChildren().add(
|
||||
LineComponent.builder()
|
||||
.left(total.getName())
|
||||
.right(showDamage ? Integer.toString(total.getDamage()) : DPS_FORMAT.format(total.getDps()))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
void setPaused(boolean paused)
|
||||
{
|
||||
OverlayMenuEntry remove = paused ? PAUSE_ENTRY : UNPAUSE_ENTRY;
|
||||
OverlayMenuEntry add = paused ? UNPAUSE_ENTRY : PAUSE_ENTRY;
|
||||
getMenuEntries().remove(remove);
|
||||
if (!getMenuEntries().contains(add))
|
||||
{
|
||||
getMenuEntries().add(add);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.dpscounter;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import net.runelite.http.api.ws.messages.party.PartyMemberMessage;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DpsUpdate extends PartyMemberMessage
|
||||
{
|
||||
private int hit;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Jake Wilson <https://github.com/jakewilson>
|
||||
* 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.timetracking;
|
||||
|
||||
public enum SortOrder
|
||||
{
|
||||
NONE,
|
||||
ASC,
|
||||
DESC
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.keyremapping;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.awt.event.KeyEvent;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.client.config.ModifierlessKeybind;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class KeyRemappingListenerTest
|
||||
{
|
||||
@Inject
|
||||
private KeyRemappingListener keyRemappingListener;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private KeyRemappingPlugin keyRemappingPlugin;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private KeyRemappingConfig keyRemappingConfig;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypingStateChange()
|
||||
{
|
||||
when(keyRemappingConfig.cameraRemap()).thenReturn(true);
|
||||
when(keyRemappingConfig.up()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_W, 0));
|
||||
when(keyRemappingConfig.down()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_S, 0));
|
||||
when(keyRemappingConfig.left()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_A, 0));
|
||||
when(keyRemappingConfig.right()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_D, 0));
|
||||
|
||||
when(keyRemappingPlugin.chatboxFocused()).thenReturn(true);
|
||||
KeyEvent event = mock(KeyEvent.class);
|
||||
when(event.getKeyCode()).thenReturn(KeyEvent.VK_D);
|
||||
when(event.getExtendedKeyCode()).thenReturn(KeyEvent.VK_D); // for keybind matches()
|
||||
keyRemappingListener.keyPressed(event);
|
||||
verify(event).setKeyCode(KeyEvent.VK_RIGHT);
|
||||
|
||||
// with the plugin now in typing mode, previously pressed and remapped keys should still be mapped
|
||||
// on key release regardless
|
||||
when(keyRemappingPlugin.isTyping()).thenReturn(true);
|
||||
event = mock(KeyEvent.class);
|
||||
when(event.getKeyCode()).thenReturn(KeyEvent.VK_D);
|
||||
keyRemappingListener.keyReleased(event);
|
||||
verify(event).setKeyCode(KeyEvent.VK_RIGHT);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user