loot tracker: add view for grouping loot by npc/event
This commit is contained in:
@@ -29,6 +29,10 @@ import com.google.common.base.Strings;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.GridLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
@@ -39,14 +43,26 @@ import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
|
||||
@Getter
|
||||
class LootTrackerBox extends JPanel
|
||||
{
|
||||
private static final int ITEMS_PER_ROW = 5;
|
||||
private final long totalPrice;
|
||||
private final JPanel itemContainer = new JPanel();
|
||||
private final JLabel priceLabel = new JLabel();
|
||||
private final JLabel subTitleLabel = new JLabel();
|
||||
private final ItemManager itemManager;
|
||||
private final String id;
|
||||
|
||||
LootTrackerBox(final ItemManager itemManager, final String title, final String subTitle, final LootTrackerItemEntry[] items)
|
||||
@Getter
|
||||
private final List<LootTrackerRecord> records = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private long totalPrice;
|
||||
|
||||
LootTrackerBox(final ItemManager itemManager, final String id, @Nullable final String subtitle)
|
||||
{
|
||||
this.id = id;
|
||||
this.itemManager = itemManager;
|
||||
|
||||
setLayout(new BorderLayout(0, 1));
|
||||
setBorder(new EmptyBorder(5, 0, 0, 0));
|
||||
|
||||
@@ -54,43 +70,140 @@ class LootTrackerBox extends JPanel
|
||||
logTitle.setBorder(new EmptyBorder(7, 7, 7, 7));
|
||||
logTitle.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker());
|
||||
|
||||
final JLabel titleLabel = new JLabel(title);
|
||||
final JLabel titleLabel = new JLabel(id);
|
||||
titleLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
titleLabel.setForeground(Color.WHITE);
|
||||
|
||||
logTitle.add(titleLabel, BorderLayout.WEST);
|
||||
|
||||
// If we have subtitle, add it
|
||||
if (!Strings.isNullOrEmpty(subTitle))
|
||||
if (!Strings.isNullOrEmpty(subtitle))
|
||||
{
|
||||
final JLabel subTitleLabel = new JLabel(subTitle);
|
||||
subTitleLabel.setText(subtitle);
|
||||
subTitleLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
subTitleLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
logTitle.add(subTitleLabel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
totalPrice = calculatePrice(items);
|
||||
priceLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
priceLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
logTitle.add(priceLabel, BorderLayout.EAST);
|
||||
|
||||
if (totalPrice > 0)
|
||||
add(logTitle, BorderLayout.NORTH);
|
||||
add(itemContainer, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
int getTotalKills()
|
||||
{
|
||||
return records.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this box matches specified record
|
||||
* @param record loot record
|
||||
* @return true if match is made
|
||||
*/
|
||||
boolean matches(final LootTrackerRecord record)
|
||||
{
|
||||
return record.getTitle().equals(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this box matches specified id
|
||||
* @param id other record id
|
||||
* @return true if match is made
|
||||
*/
|
||||
boolean matches(final String id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
final JLabel priceLabel = new JLabel(StackFormatter.quantityToStackSize(totalPrice) + " gp");
|
||||
priceLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
priceLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
logTitle.add(priceLabel, BorderLayout.EAST);
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.id.equals(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an record's data into a loot box.
|
||||
* This will add new items to the list, re-calculating price and kill count.
|
||||
*/
|
||||
void combine(final LootTrackerRecord record)
|
||||
{
|
||||
if (!matches(record))
|
||||
{
|
||||
throw new IllegalArgumentException(record.toString());
|
||||
}
|
||||
|
||||
records.add(record);
|
||||
buildItems();
|
||||
|
||||
priceLabel.setText(StackFormatter.quantityToStackSize(totalPrice) + " gp");
|
||||
if (records.size() > 1)
|
||||
{
|
||||
subTitleLabel.setText("x " + records.size());
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates stacked items from the item list, calculates total price and then
|
||||
* displays all the items in the UI.
|
||||
*/
|
||||
private void buildItems()
|
||||
{
|
||||
final List<LootTrackerItem> allItems = new ArrayList<>();
|
||||
final List<LootTrackerItem> items = new ArrayList<>();
|
||||
totalPrice = 0;
|
||||
|
||||
for (LootTrackerRecord records : records)
|
||||
{
|
||||
allItems.addAll(Arrays.asList(records.getItems()));
|
||||
}
|
||||
|
||||
for (final LootTrackerItem entry : allItems)
|
||||
{
|
||||
totalPrice += entry.getPrice();
|
||||
|
||||
int quantity = 0;
|
||||
for (final LootTrackerItem i : items)
|
||||
{
|
||||
if (i.getId() == entry.getId())
|
||||
{
|
||||
quantity = i.getQuantity();
|
||||
items.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (quantity > 0)
|
||||
{
|
||||
int newQuantity = entry.getQuantity() + quantity;
|
||||
long pricePerItem = entry.getPrice() == 0 ? 0 : (entry.getPrice() / entry.getQuantity());
|
||||
|
||||
items.add(new LootTrackerItem(entry.getId(), entry.getName(), newQuantity, pricePerItem * newQuantity));
|
||||
}
|
||||
else
|
||||
{
|
||||
items.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
items.sort((i1, i2) -> Long.compare(i2.getPrice(), i1.getPrice()));
|
||||
|
||||
// Calculates how many rows need to be display to fit all items
|
||||
final int rowSize = ((items.length % ITEMS_PER_ROW == 0) ? 0 : 1) + items.length / ITEMS_PER_ROW;
|
||||
final JPanel itemContainer = new JPanel(new GridLayout(rowSize, ITEMS_PER_ROW, 1, 1));
|
||||
final int rowSize = ((items.size() % ITEMS_PER_ROW == 0) ? 0 : 1) + items.size() / ITEMS_PER_ROW;
|
||||
|
||||
itemContainer.removeAll();
|
||||
itemContainer.setLayout(new GridLayout(rowSize, ITEMS_PER_ROW, 1, 1));
|
||||
|
||||
for (int i = 0; i < rowSize * ITEMS_PER_ROW; i++)
|
||||
{
|
||||
final JPanel slotContainer = new JPanel();
|
||||
slotContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
if (i < items.length)
|
||||
if (i < items.size())
|
||||
{
|
||||
final LootTrackerItemEntry item = items[i];
|
||||
final LootTrackerItem item = items.get(i);
|
||||
final JLabel imageLabel = new JLabel();
|
||||
imageLabel.setToolTipText(buildToolTip(item));
|
||||
imageLabel.setVerticalAlignment(SwingConstants.CENTER);
|
||||
@@ -102,26 +215,14 @@ class LootTrackerBox extends JPanel
|
||||
itemContainer.add(slotContainer);
|
||||
}
|
||||
|
||||
add(logTitle, BorderLayout.NORTH);
|
||||
add(itemContainer, BorderLayout.CENTER);
|
||||
itemContainer.repaint();
|
||||
}
|
||||
|
||||
private String buildToolTip(LootTrackerItemEntry item)
|
||||
private static String buildToolTip(LootTrackerItem item)
|
||||
{
|
||||
final String name = item.getName();
|
||||
final int quantity = item.getQuantity();
|
||||
final long price = item.getPrice();
|
||||
|
||||
return name + " x " + quantity + " (" + StackFormatter.quantityToStackSize(price) + ")";
|
||||
}
|
||||
|
||||
private static long calculatePrice(final LootTrackerItemEntry[] itemStacks)
|
||||
{
|
||||
long total = 0;
|
||||
for (LootTrackerItemEntry itemStack : itemStacks)
|
||||
{
|
||||
total += itemStack.getPrice();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ package net.runelite.client.plugins.loottracker;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
class LootTrackerItemEntry
|
||||
class LootTrackerItem
|
||||
{
|
||||
private final int id;
|
||||
private final String name;
|
||||
@@ -26,8 +26,15 @@
|
||||
package net.runelite.client.plugins.loottracker;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
@@ -41,17 +48,27 @@ import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.components.PluginErrorPanel;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
|
||||
class LootTrackerPanel extends PluginPanel
|
||||
{
|
||||
private static final ImageIcon SINGLE_LOOT_VIEW;
|
||||
private static final ImageIcon SINGLE_LOOT_VIEW_FADED;
|
||||
private static final ImageIcon SINGLE_LOOT_VIEW_HOVER;
|
||||
private static final ImageIcon GROUPED_LOOT_VIEW;
|
||||
private static final ImageIcon GROUPED_LOOT_VIEW_FADED;
|
||||
private static final ImageIcon GROUPED_LOOT_VIEW_HOVER;
|
||||
private static final ImageIcon BACK_ARROW_ICON;
|
||||
private static final ImageIcon BACK_ARROW_ICON_HOVER;
|
||||
|
||||
private static final String HTML_LABEL_TEMPLATE =
|
||||
"<html><body style='color:%s'>%s<span style='color:white'>%s</span></body></html>";
|
||||
|
||||
// When there is no loot, display this
|
||||
private final PluginErrorPanel errorPanel = new PluginErrorPanel();
|
||||
|
||||
// Handle loot logs
|
||||
// Handle loot boxes
|
||||
private final JPanel logsContainer = new JPanel();
|
||||
|
||||
// Handle overall session data
|
||||
@@ -59,9 +76,39 @@ class LootTrackerPanel extends PluginPanel
|
||||
private final JLabel overallKillsLabel = new JLabel();
|
||||
private final JLabel overallGpLabel = new JLabel();
|
||||
private final JLabel overallIcon = new JLabel();
|
||||
|
||||
// Details and navigation
|
||||
private final JPanel actionsContainer = new JPanel();
|
||||
private final JLabel detailsTitle = new JLabel();
|
||||
private final JLabel backBtn = new JLabel();
|
||||
private final JLabel singleLootBtn = new JLabel();
|
||||
private final JLabel groupedLootBtn = new JLabel();
|
||||
|
||||
// Log collection
|
||||
private final List<LootTrackerRecord> records = new ArrayList<>();
|
||||
private final List<LootTrackerBox> boxes = new ArrayList<>();
|
||||
|
||||
private final ItemManager itemManager;
|
||||
private int overallKills;
|
||||
private int overallGp;
|
||||
private boolean groupLoot;
|
||||
private String currentView;
|
||||
|
||||
static
|
||||
{
|
||||
final BufferedImage singleLootImg = ImageUtil.getResourceStreamFromClass(LootTrackerPlugin.class, "single_loot_icon.png");
|
||||
final BufferedImage groupedLootImg = ImageUtil.getResourceStreamFromClass(LootTrackerPlugin.class, "grouped_loot_icon.png");
|
||||
final BufferedImage backArrowImg = ImageUtil.getResourceStreamFromClass(LootTrackerPlugin.class, "back_icon.png");
|
||||
|
||||
SINGLE_LOOT_VIEW = new ImageIcon(singleLootImg);
|
||||
SINGLE_LOOT_VIEW_FADED = new ImageIcon(ImageUtil.alphaOffset(singleLootImg, -180));
|
||||
SINGLE_LOOT_VIEW_HOVER = new ImageIcon(ImageUtil.alphaOffset(singleLootImg, -220));
|
||||
|
||||
GROUPED_LOOT_VIEW = new ImageIcon(groupedLootImg);
|
||||
GROUPED_LOOT_VIEW_FADED = new ImageIcon(ImageUtil.alphaOffset(groupedLootImg, -180));
|
||||
GROUPED_LOOT_VIEW_HOVER = new ImageIcon(ImageUtil.alphaOffset(groupedLootImg, -220));
|
||||
|
||||
BACK_ARROW_ICON = new ImageIcon(backArrowImg);
|
||||
BACK_ARROW_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(backArrowImg, -180));
|
||||
}
|
||||
|
||||
LootTrackerPanel(final ItemManager itemManager)
|
||||
{
|
||||
@@ -75,8 +122,104 @@ class LootTrackerPanel extends PluginPanel
|
||||
layoutPanel.setLayout(new BoxLayout(layoutPanel, BoxLayout.Y_AXIS));
|
||||
add(layoutPanel, BorderLayout.NORTH);
|
||||
|
||||
actionsContainer.setLayout(new BorderLayout());
|
||||
actionsContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
actionsContainer.setPreferredSize(new Dimension(0, 30));
|
||||
actionsContainer.setBorder(new EmptyBorder(5, 5, 5, 10));
|
||||
actionsContainer.setVisible(false);
|
||||
|
||||
final JPanel viewControls = new JPanel(new GridLayout(1, 2, 10, 0));
|
||||
viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
singleLootBtn.setIcon(SINGLE_LOOT_VIEW);
|
||||
singleLootBtn.setToolTipText("Show each kill separately");
|
||||
singleLootBtn.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
changeGrouping(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
singleLootBtn.setIcon(groupLoot ? SINGLE_LOOT_VIEW_FADED : SINGLE_LOOT_VIEW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
singleLootBtn.setIcon(groupLoot ? SINGLE_LOOT_VIEW_HOVER : SINGLE_LOOT_VIEW);
|
||||
}
|
||||
});
|
||||
|
||||
groupedLootBtn.setIcon(GROUPED_LOOT_VIEW);
|
||||
groupedLootBtn.setToolTipText("Group loot by source");
|
||||
groupedLootBtn.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
changeGrouping(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
groupedLootBtn.setIcon(groupLoot ? GROUPED_LOOT_VIEW : GROUPED_LOOT_VIEW_FADED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
groupedLootBtn.setIcon(groupLoot ? GROUPED_LOOT_VIEW : GROUPED_LOOT_VIEW_HOVER);
|
||||
}
|
||||
});
|
||||
|
||||
viewControls.add(groupedLootBtn);
|
||||
viewControls.add(singleLootBtn);
|
||||
changeGrouping(true);
|
||||
|
||||
final JPanel leftTitleContainer = new JPanel(new BorderLayout(5, 0));
|
||||
leftTitleContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
detailsTitle.setForeground(Color.WHITE);
|
||||
|
||||
backBtn.setIcon(BACK_ARROW_ICON);
|
||||
backBtn.setVisible(false);
|
||||
backBtn.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
currentView = null;
|
||||
backBtn.setVisible(false);
|
||||
detailsTitle.setText("");
|
||||
rebuild();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
backBtn.setIcon(BACK_ARROW_ICON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
backBtn.setIcon(BACK_ARROW_ICON_HOVER);
|
||||
}
|
||||
});
|
||||
|
||||
leftTitleContainer.add(backBtn, BorderLayout.WEST);
|
||||
leftTitleContainer.add(detailsTitle, BorderLayout.CENTER);
|
||||
|
||||
actionsContainer.add(leftTitleContainer, BorderLayout.WEST);
|
||||
actionsContainer.add(viewControls, BorderLayout.EAST);
|
||||
|
||||
// Create panel that will contain overall data
|
||||
overallPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
overallPanel.setBorder(new EmptyBorder(8, 10, 8, 10));
|
||||
overallPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
overallPanel.setLayout(new BorderLayout());
|
||||
overallPanel.setVisible(false);
|
||||
@@ -85,7 +228,7 @@ class LootTrackerPanel extends PluginPanel
|
||||
final JPanel overallInfo = new JPanel();
|
||||
overallInfo.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
overallInfo.setLayout(new GridLayout(2, 1));
|
||||
overallInfo.setBorder(new EmptyBorder(0, 10, 0, 0));
|
||||
overallInfo.setBorder(new EmptyBorder(2, 10, 2, 0));
|
||||
overallKillsLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
overallGpLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
overallInfo.add(overallKillsLabel);
|
||||
@@ -97,8 +240,9 @@ class LootTrackerPanel extends PluginPanel
|
||||
final JMenuItem reset = new JMenuItem("Reset All");
|
||||
reset.addActionListener(e ->
|
||||
{
|
||||
overallKills = 0;
|
||||
overallGp = 0;
|
||||
// If not in detailed view, remove all, otherwise only remove for the currently detailed title
|
||||
records.removeIf(r -> r.matches(currentView));
|
||||
boxes.removeIf(b -> b.matches(currentView));
|
||||
updateOverall();
|
||||
logsContainer.removeAll();
|
||||
logsContainer.repaint();
|
||||
@@ -110,8 +254,10 @@ class LootTrackerPanel extends PluginPanel
|
||||
popupMenu.add(reset);
|
||||
overallPanel.setComponentPopupMenu(popupMenu);
|
||||
|
||||
// Create loot logs wrapper
|
||||
// Create loot boxes wrapper
|
||||
logsContainer.setLayout(new BoxLayout(logsContainer, BoxLayout.Y_AXIS));
|
||||
layoutPanel.add(actionsContainer);
|
||||
layoutPanel.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||
layoutPanel.add(overallPanel);
|
||||
layoutPanel.add(logsContainer);
|
||||
|
||||
@@ -125,50 +271,129 @@ class LootTrackerPanel extends PluginPanel
|
||||
overallIcon.setIcon(new ImageIcon(img));
|
||||
}
|
||||
|
||||
private static String htmlLabel(String key, long value)
|
||||
/**
|
||||
* Adds a new entry to the plugin.
|
||||
* Creates a subtitle, adds a new entry and then passes off to the render methods, that will decide
|
||||
* how to display this new data.
|
||||
*/
|
||||
void add(final String eventName, final int actorLevel, LootTrackerItem[] items)
|
||||
{
|
||||
final String valueStr = StackFormatter.quantityToStackSize(value);
|
||||
return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), key, valueStr);
|
||||
final String subTitle = actorLevel > -1 ? "(lvl-" + actorLevel + ")" : "";
|
||||
final LootTrackerRecord record = new LootTrackerRecord(eventName, subTitle, items, System.currentTimeMillis());
|
||||
records.add(record);
|
||||
buildBox(record);
|
||||
}
|
||||
|
||||
void addLog(final String eventName, final int actorLevel, LootTrackerItemEntry[] items)
|
||||
/**
|
||||
* Changes grouping mode of panel
|
||||
* @param group if loot should be grouped or not
|
||||
*/
|
||||
private void changeGrouping(boolean group)
|
||||
{
|
||||
// Remove error and show overall
|
||||
groupLoot = group;
|
||||
rebuild();
|
||||
groupedLootBtn.setIcon(group ? GROUPED_LOOT_VIEW : GROUPED_LOOT_VIEW_FADED);
|
||||
singleLootBtn.setIcon(group ? SINGLE_LOOT_VIEW_FADED : SINGLE_LOOT_VIEW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds all the boxes from scratch using existing listed records, depending on the grouping mode.
|
||||
*/
|
||||
private void rebuild()
|
||||
{
|
||||
logsContainer.removeAll();
|
||||
boxes.clear();
|
||||
records.forEach(this::buildBox);
|
||||
updateOverall();
|
||||
logsContainer.revalidate();
|
||||
logsContainer.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method decides what to do with a new record, if a similar log exists, it will
|
||||
* add its items to it, updating the log's overall price and kills. If not, a new log will be created
|
||||
* to hold this entry's information.
|
||||
*/
|
||||
private void buildBox(LootTrackerRecord record)
|
||||
{
|
||||
// If this record is not part of current view, return
|
||||
if (!record.matches(currentView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Group all similar loot together
|
||||
if (groupLoot)
|
||||
{
|
||||
for (LootTrackerBox box : boxes)
|
||||
{
|
||||
if (box.matches(record))
|
||||
{
|
||||
box.combine(record);
|
||||
updateOverall();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show main view
|
||||
remove(errorPanel);
|
||||
actionsContainer.setVisible(true);
|
||||
overallPanel.setVisible(true);
|
||||
|
||||
// Create box
|
||||
final String subTitle = actorLevel > -1 ? "(lvl-" + actorLevel + ")" : "";
|
||||
final LootTrackerBox box = new LootTrackerBox(itemManager, eventName, subTitle, items);
|
||||
logsContainer.add(box, 0);
|
||||
logsContainer.repaint();
|
||||
final LootTrackerBox box = new LootTrackerBox(itemManager, record.getTitle(), record.getSubTitle());
|
||||
box.combine(record);
|
||||
|
||||
// Update overall
|
||||
overallGp += box.getTotalPrice();
|
||||
overallKills += 1;
|
||||
updateOverall();
|
||||
// Create popup menu
|
||||
final JPopupMenu popupMenu = new JPopupMenu();
|
||||
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
box.setComponentPopupMenu(popupMenu);
|
||||
|
||||
// Create reset menu
|
||||
final JMenuItem reset = new JMenuItem("Reset");
|
||||
reset.addActionListener(e ->
|
||||
{
|
||||
overallGp -= box.getTotalPrice();
|
||||
overallKills -= 1;
|
||||
records.removeAll(box.getRecords());
|
||||
boxes.remove(box);
|
||||
updateOverall();
|
||||
logsContainer.remove(box);
|
||||
logsContainer.repaint();
|
||||
});
|
||||
|
||||
// Create popup menu
|
||||
final JPopupMenu popupMenu = new JPopupMenu();
|
||||
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
popupMenu.add(reset);
|
||||
box.setComponentPopupMenu(popupMenu);
|
||||
|
||||
// Create details menu
|
||||
final JMenuItem details = new JMenuItem("View details");
|
||||
details.addActionListener(e ->
|
||||
{
|
||||
currentView = record.getTitle();
|
||||
detailsTitle.setText(currentView);
|
||||
backBtn.setVisible(true);
|
||||
rebuild();
|
||||
});
|
||||
|
||||
popupMenu.add(details);
|
||||
|
||||
// Add box to panel
|
||||
boxes.add(box);
|
||||
logsContainer.add(box, 0);
|
||||
|
||||
// Update overall
|
||||
updateOverall();
|
||||
}
|
||||
|
||||
private void updateOverall()
|
||||
{
|
||||
final long overallGp = boxes.stream().mapToLong(LootTrackerBox::getTotalPrice).sum();
|
||||
final int overallKills = boxes.stream().mapToInt(LootTrackerBox::getTotalKills).sum();
|
||||
overallKillsLabel.setText(htmlLabel("Total count: ", overallKills));
|
||||
overallGpLabel.setText(htmlLabel("Total value: ", overallGp));
|
||||
}
|
||||
|
||||
private static String htmlLabel(String key, long value)
|
||||
{
|
||||
final String valueStr = StackFormatter.quantityToStackSize(value);
|
||||
return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), key, valueStr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,8 +150,8 @@ public class LootTrackerPlugin extends Plugin
|
||||
final Collection<ItemStack> items = npcLootReceived.getItems();
|
||||
final String name = npc.getName();
|
||||
final int combat = npc.getCombatLevel();
|
||||
final LootTrackerItemEntry[] entries = buildEntries(stack(items));
|
||||
SwingUtilities.invokeLater(() -> panel.addLog(name, combat, entries));
|
||||
final LootTrackerItem[] entries = buildEntries(stack(items));
|
||||
SwingUtilities.invokeLater(() -> panel.add(name, combat, entries));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -161,8 +161,8 @@ public class LootTrackerPlugin extends Plugin
|
||||
final Collection<ItemStack> items = playerLootReceived.getItems();
|
||||
final String name = player.getName();
|
||||
final int combat = player.getCombatLevel();
|
||||
final LootTrackerItemEntry[] entries = buildEntries(stack(items));
|
||||
SwingUtilities.invokeLater(() -> panel.addLog(name, combat, entries));
|
||||
final LootTrackerItem[] entries = buildEntries(stack(items));
|
||||
SwingUtilities.invokeLater(() -> panel.add(name, combat, entries));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -209,8 +209,8 @@ public class LootTrackerPlugin extends Plugin
|
||||
|
||||
if (!items.isEmpty())
|
||||
{
|
||||
final LootTrackerItemEntry[] entries = buildEntries(stack(items));
|
||||
SwingUtilities.invokeLater(() -> panel.addLog(eventType, -1, entries));
|
||||
final LootTrackerItem[] entries = buildEntries(stack(items));
|
||||
SwingUtilities.invokeLater(() -> panel.add(eventType, -1, entries));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -252,19 +252,19 @@ public class LootTrackerPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private LootTrackerItemEntry[] buildEntries(final Collection<ItemStack> itemStacks)
|
||||
private LootTrackerItem[] buildEntries(final Collection<ItemStack> itemStacks)
|
||||
{
|
||||
return itemStacks.stream().map(itemStack ->
|
||||
{
|
||||
final ItemComposition itemComposition = itemManager.getItemComposition(itemStack.getId());
|
||||
final int realItemId = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemStack.getId();
|
||||
final long price = (long)itemManager.getItemPrice(realItemId) * (long)itemStack.getQuantity();
|
||||
final long price = (long) itemManager.getItemPrice(realItemId) * (long) itemStack.getQuantity();
|
||||
|
||||
return new LootTrackerItemEntry(
|
||||
return new LootTrackerItem(
|
||||
itemStack.getId(),
|
||||
itemComposition.getName(),
|
||||
itemStack.getQuantity(),
|
||||
price);
|
||||
}).toArray(LootTrackerItemEntry[]::new);
|
||||
}).toArray(LootTrackerItem[]::new);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||
* 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.loottracker;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
class LootTrackerRecord
|
||||
{
|
||||
private final String title;
|
||||
private final String subTitle;
|
||||
private final LootTrackerItem[] items;
|
||||
private final long timestamp;
|
||||
|
||||
/**
|
||||
* Checks if this record matches specified id
|
||||
* @param id other record id
|
||||
* @return true if match is made
|
||||
*/
|
||||
boolean matches(final String id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return title.equals(id);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Reference in New Issue
Block a user