Merge remote-tracking branch 'rl-upstream/master' into rl-upstream-160322

This commit is contained in:
JumpIfZero
2022-03-16 14:00:41 +02:00
12 changed files with 359 additions and 219 deletions

View File

@@ -164,9 +164,16 @@ public class ChatMessageManager
stringStack[size - 4] = ColorUtil.wrapWithColorTag(channel, channelColor);
}
String prefix = "";
if (chatMessageType == ChatMessageType.CLAN_GIM_CHAT || chatMessageType == ChatMessageType.CLAN_GIM_MESSAGE)
{
message = message.substring(1); // remove |
prefix = "|";
}
if (messageNode.getRuneLiteFormatMessage() != null)
{
stringStack[size - 2] = message = formatRuneLiteMessage(messageNode.getRuneLiteFormatMessage(),
message = formatRuneLiteMessage(messageNode.getRuneLiteFormatMessage(),
chatMessageType, splitpmbox);
}
@@ -178,20 +185,15 @@ public class ChatMessageManager
continue;
}
String prefix = "";
if (chatMessageType == ChatMessageType.CLAN_GIM_CHAT || chatMessageType == ChatMessageType.CLAN_GIM_MESSAGE)
{
message = message.substring(1); // remove |
prefix = "|";
}
// Replace </col> tags in the message with the new color so embedded </col> won't reset the color
final Color color = chatColor.getColor();
stringStack[size - 2] = prefix + ColorUtil.wrapWithColorTag(
message = ColorUtil.wrapWithColorTag(
message.replace(ColorUtil.CLOSING_COLOR_TAG, ColorUtil.colorTag(color)),
color);
break;
}
stringStack[size - 2] = prefix + message;
}
@Subscribe

View File

@@ -353,8 +353,6 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
System.setProperty("jogl.debug", "true");
}
System.setProperty("jogamp.gluegen.UseNativeExeFile", "true");
GLProfile.initSingleton();
invokeOnMainThread(() ->

View File

@@ -41,4 +41,5 @@ public class LootReceived
private int combatLevel;
private LootRecordType type;
private Collection<ItemStack> items;
private int amount;
}

View File

@@ -242,8 +242,7 @@ class LootTrackerBox extends JPanel
subTitleLabel.setToolTipText(QuantityFormatter.formatNumber(totalPrice / kills) + " gp (average)");
}
validate();
repaint();
revalidate();
}
void collapse()
@@ -368,7 +367,7 @@ class LootTrackerBox extends JPanel
itemContainer.add(slotContainer);
}
itemContainer.repaint();
itemContainer.revalidate();
}
private static String buildToolTip(LootTrackerItem item)

View File

@@ -81,6 +81,16 @@ public interface LootTrackerConfig extends Config
return false;
}
@ConfigItem(
keyName = "syncPanel",
name = "Remember loot",
description = "Saves loot between client sessions"
)
default boolean syncPanel()
{
return true;
}
@ConfigItem(
keyName = "ignoredEvents",
name = "Ignored Loot Sources",

View File

@@ -323,7 +323,7 @@ class LootTrackerPanel extends PluginPanel
boxes.removeIf(b -> b.matches(currentView, currentType));
updateOverall();
logsContainer.removeAll();
logsContainer.repaint();
logsContainer.revalidate();
// Delete all loot, or loot matching the current view
if (currentView != null)
@@ -368,7 +368,7 @@ class LootTrackerPanel extends PluginPanel
* 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 LootRecordType type, final int actorLevel, LootTrackerItem[] items)
void add(final String eventName, final LootRecordType type, final int actorLevel, LootTrackerItem[] items, int kills)
{
final String subTitle;
if (type == LootRecordType.PICKPOCKET)
@@ -379,7 +379,7 @@ class LootTrackerPanel extends PluginPanel
{
subTitle = actorLevel > -1 ? "(lvl-" + actorLevel + ")" : "";
}
final LootTrackerRecord record = new LootTrackerRecord(eventName, subTitle, type, items, 1);
final LootTrackerRecord record = new LootTrackerRecord(eventName, subTitle, type, items, kills);
sessionRecords.add(record);
if (hideIgnoredItems && plugin.isEventIgnored(eventName))
@@ -505,7 +505,6 @@ class LootTrackerPanel extends PluginPanel
boxes.forEach(LootTrackerBox::rebuild);
updateOverall();
logsContainer.revalidate();
logsContainer.repaint();
}
/**
@@ -606,7 +605,7 @@ class LootTrackerPanel extends PluginPanel
boxes.remove(box);
updateOverall();
logsContainer.remove(box);
logsContainer.repaint();
logsContainer.revalidate();
// Without loot being grouped we have no way to identify single kills to be deleted
if (groupLoot)

View File

@@ -263,6 +263,23 @@ public class LootTrackerPlugin extends Plugin
// Mahogany Homes
private static final String MAHOGANY_CRATE_EVENT = "Supply crate (Mahogany Homes)";
// Implings
private static final Set<Integer> IMPLING_JARS = ImmutableSet.of(
ItemID.BABY_IMPLING_JAR,
ItemID.YOUNG_IMPLING_JAR,
ItemID.GOURMET_IMPLING_JAR,
ItemID.EARTH_IMPLING_JAR,
ItemID.ESSENCE_IMPLING_JAR,
ItemID.ECLECTIC_IMPLING_JAR,
ItemID.NATURE_IMPLING_JAR,
ItemID.MAGPIE_IMPLING_JAR,
ItemID.NINJA_IMPLING_JAR,
ItemID.CRYSTAL_IMPLING_JAR,
ItemID.DRAGON_IMPLING_JAR,
ItemID.LUCKY_IMPLING_JAR
);
private static final String IMPLING_CATCH_MESSAGE = "You manage to catch the impling and acquire some loot.";
private static final Set<Character> VOWELS = ImmutableSet.of('a', 'e', 'i', 'o', 'u');
@Inject
@@ -304,24 +321,23 @@ public class LootTrackerPlugin extends Plugin
@Inject
private Gson gson;
@Getter(AccessLevel.PACKAGE)
@Inject
private LootTrackerClient lootTrackerClient;
private LootTrackerPanel panel;
private NavigationButton navButton;
@VisibleForTesting
String eventType;
@VisibleForTesting
LootRecordType lootRecordType;
private Object metadata;
private boolean chestLooted;
private String lastPickpocketTarget;
private List<String> ignoredItems = new ArrayList<>();
private List<String> ignoredEvents = new ArrayList<>();
private InventoryID inventoryId;
private Multiset<Integer> inventorySnapshot;
private InvChangeCallback inventorySnapshotCb;
@Getter(AccessLevel.PACKAGE)
@Inject
private LootTrackerClient lootTrackerClient;
private final List<LootRecord> queuedLoots = new ArrayList<>();
private String profileKey;
private Instant lastLootImport = Instant.now().minus(1, ChronoUnit.MINUTES);
@@ -396,7 +412,6 @@ public class LootTrackerPlugin extends Plugin
return;
}
log.debug("Profile changed to {}", profileKey);
switchProfile(profileKey);
}
@@ -411,6 +426,11 @@ public class LootTrackerPlugin extends Plugin
log.debug("Switched to profile {}", profileKey);
if (!config.syncPanel())
{
return;
}
int drops = 0;
List<ConfigLoot> loots = new ArrayList<>();
Instant old = Instant.now().minus(MAX_AGE);
@@ -552,9 +572,14 @@ public class LootTrackerPlugin extends Plugin
}
void addLoot(@NonNull String name, int combatLevel, LootRecordType type, Object metadata, Collection<ItemStack> items)
{
addLoot(name, combatLevel, type, metadata, items, 1);
}
void addLoot(@NonNull String name, int combatLevel, LootRecordType type, Object metadata, Collection<ItemStack> items, int amount)
{
final LootTrackerItem[] entries = buildEntries(stack(items));
SwingUtilities.invokeLater(() -> panel.add(name, type, combatLevel, entries));
SwingUtilities.invokeLater(() -> panel.add(name, type, combatLevel, entries, amount));
LootRecord lootRecord = new LootRecord(name, type, metadata, toGameItems(items), Instant.now(), getLootWorldId());
synchronized (queuedLoots)
@@ -562,7 +587,7 @@ public class LootTrackerPlugin extends Plugin
queuedLoots.add(lootRecord);
}
eventBus.post(new LootReceived(name, combatLevel, type, items));
eventBus.post(new LootReceived(name, combatLevel, type, items, amount));
}
private Integer getLootWorldId()
@@ -616,12 +641,14 @@ public class LootTrackerPlugin extends Plugin
@Subscribe
public void onWidgetLoaded(WidgetLoaded widgetLoaded)
{
String event;
Object metadata = null;
final ItemContainer container;
switch (widgetLoaded.getGroupId())
{
case (WidgetID.BARROWS_REWARD_GROUP_ID):
setEvent(LootRecordType.EVENT, "Barrows");
event = "Barrows";
container = client.getItemContainer(InventoryID.BARROWS_REWARD);
break;
case (WidgetID.CHAMBERS_OF_XERIC_REWARD_GROUP_ID):
@@ -629,7 +656,7 @@ public class LootTrackerPlugin extends Plugin
{
return;
}
setEvent(LootRecordType.EVENT, "Chambers of Xeric");
event = "Chambers of Xeric";
container = client.getItemContainer(InventoryID.CHAMBERS_OF_XERIC_CHEST);
chestLooted = true;
break;
@@ -643,33 +670,33 @@ public class LootTrackerPlugin extends Plugin
{
return;
}
setEvent(LootRecordType.EVENT, "Theatre of Blood");
event = "Theatre of Blood";
container = client.getItemContainer(InventoryID.THEATRE_OF_BLOOD_CHEST);
chestLooted = true;
break;
case (WidgetID.CLUE_SCROLL_REWARD_GROUP_ID):
// event type should be set via ChatMessage for clue scrolls.
// Clue Scrolls use same InventoryID as Barrows
container = client.getItemContainer(InventoryID.BARROWS_REWARD);
if (eventType == null)
{
log.debug("Clue scroll reward interface with no event!");
return;
}
break;
case (WidgetID.KINGDOM_GROUP_ID):
setEvent(LootRecordType.EVENT, "Kingdom of Miscellania");
event = "Kingdom of Miscellania";
container = client.getItemContainer(InventoryID.KINGDOM_OF_MISCELLANIA);
break;
case (WidgetID.FISHING_TRAWLER_REWARD_GROUP_ID):
setEvent(LootRecordType.EVENT, "Fishing Trawler", client.getBoostedSkillLevel(Skill.FISHING));
event = "Fishing Trawler";
metadata = client.getBoostedSkillLevel(Skill.FISHING);
container = client.getItemContainer(InventoryID.FISHING_TRAWLER_REWARD);
break;
case (WidgetID.DRIFT_NET_FISHING_REWARD_GROUP_ID):
setEvent(LootRecordType.EVENT, "Drift Net", client.getBoostedSkillLevel(Skill.FISHING));
event = "Drift Net";
metadata = client.getBoostedSkillLevel(Skill.FISHING);
container = client.getItemContainer(InventoryID.DRIFT_NET_FISHING_REWARD);
break;
case WidgetID.WILDERNESS_LOOT_CHEST:
if (chestLooted)
{
return;
}
event = "Loot Chest";
container = client.getItemContainer(InventoryID.WILDERNESS_LOOT_CHEST);
chestLooted = true;
break;
default:
return;
}
@@ -685,13 +712,13 @@ public class LootTrackerPlugin extends Plugin
.map(item -> new ItemStack(item.getId(), item.getQuantity(), client.getLocalPlayer().getLocalLocation()))
.collect(Collectors.toList());
if (config.showRaidsLootValue() && (eventType.equals("Theatre of Blood") || eventType.equals("Chambers of Xeric")))
if (config.showRaidsLootValue() && (event.equals("Theatre of Blood") || event.equals("Chambers of Xeric")))
{
long totalValue = items.stream()
.filter(item -> item.getId() > -1)
.mapToLong(item -> (long) (config.priceType() == LootTrackerPriceType.GRAND_EXCHANGE ?
itemManager.getItemPrice(item.getId()) * item.getQuantity() :
itemManager.getItemComposition(item.getId()).getHaPrice() * item.getQuantity()))
.mapToLong(item -> config.priceType() == LootTrackerPriceType.GRAND_EXCHANGE ?
(long) itemManager.getItemPrice(item.getId()) * item.getQuantity() :
(long) itemManager.getItemComposition(item.getId()).getHaPrice() * item.getQuantity())
.sum();
String chatMessage = new ChatMessageBuilder()
@@ -711,11 +738,11 @@ public class LootTrackerPlugin extends Plugin
if (items.isEmpty())
{
log.debug("No items to find for Event: {} | Container: {}", eventType, container);
log.debug("No items to find for Event: {} | Container: {}", event, container);
return;
}
addLoot(eventType, -1, lootRecordType, metadata, items);
addLoot(event, -1, LootRecordType.EVENT, metadata, items);
}
@Subscribe
@@ -738,17 +765,14 @@ public class LootTrackerPlugin extends Plugin
return;
}
setEvent(LootRecordType.EVENT, CHEST_EVENT_TYPES.get(regionID));
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, CHEST_EVENT_TYPES.get(regionID)));
return;
}
if (message.equals(COFFIN_LOOTED_MESSAGE) &&
isPlayerWithinMapRegion(HALLOWED_SEPULCHRE_MAP_REGIONS))
{
setEvent(LootRecordType.EVENT, HALLOWED_SEPULCHRE_COFFIN_EVENT);
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, HALLOWED_SEPULCHRE_COFFIN_EVENT));
return;
}
@@ -759,16 +783,14 @@ public class LootTrackerPlugin extends Plugin
return;
}
setEvent(LootRecordType.EVENT, HERBIBOAR_EVENT, client.getBoostedSkillLevel(Skill.HERBLORE));
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, HERBIBOAR_EVENT, client.getBoostedSkillLevel(Skill.HERBLORE)));
return;
}
final int regionID = client.getLocalPlayer().getWorldLocation().getRegionID();
if (HESPORI_REGION == regionID && message.equals(HESPORI_LOOTED_MESSAGE))
{
setEvent(LootRecordType.EVENT, HESPORI_EVENT);
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, HESPORI_EVENT));
return;
}
@@ -776,8 +798,7 @@ public class LootTrackerPlugin extends Plugin
if (hamStoreroomMatcher.matches() && regionID == HAM_STOREROOM_REGION)
{
String keyType = hamStoreroomMatcher.group("key");
setEvent(LootRecordType.EVENT, String.format("H.A.M. chest (%s)", keyType));
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, String.format("H.A.M. chest (%s)", keyType)));
return;
}
@@ -790,14 +811,10 @@ public class LootTrackerPlugin extends Plugin
// Occasional edge case where the pickpocket message doesn't list the correct name of the NPC (e.g. H.A.M. Members)
if (PICKPOCKET_DISAMBIGUATION_MAP.get(lastPickpocketTarget).contains(pickpocketTarget))
{
setEvent(LootRecordType.PICKPOCKET, lastPickpocketTarget);
}
else
{
setEvent(LootRecordType.PICKPOCKET, pickpocketTarget);
pickpocketTarget = lastPickpocketTarget;
}
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.PICKPOCKET, pickpocketTarget));
return;
}
@@ -806,27 +823,36 @@ public class LootTrackerPlugin extends Plugin
if (m.find())
{
final String type = m.group(1).toLowerCase();
String eventType;
switch (type)
{
case "beginner":
setEvent(LootRecordType.EVENT, "Clue Scroll (Beginner)");
return;
eventType = "Clue Scroll (Beginner)";
break;
case "easy":
setEvent(LootRecordType.EVENT, "Clue Scroll (Easy)");
return;
eventType = "Clue Scroll (Easy)";
break;
case "medium":
setEvent(LootRecordType.EVENT, "Clue Scroll (Medium)");
return;
eventType = "Clue Scroll (Medium)";
break;
case "hard":
setEvent(LootRecordType.EVENT, "Clue Scroll (Hard)");
return;
eventType = "Clue Scroll (Hard)";
break;
case "elite":
setEvent(LootRecordType.EVENT, "Clue Scroll (Elite)");
return;
eventType = "Clue Scroll (Elite)";
break;
case "master":
setEvent(LootRecordType.EVENT, "Clue Scroll (Master)");
eventType = "Clue Scroll (Master)";
break;
default:
log.debug("Unrecognized clue type: {}", type);
return;
}
// Clue Scrolls use same InventoryID as Barrows
onInvChange(InventoryID.BARROWS_REWARD, collectInvItems(LootRecordType.EVENT, eventType));
return;
}
if (SHADE_CHEST_NO_KEY_PATTERN.matcher(message).matches())
@@ -848,56 +874,64 @@ public class LootTrackerPlugin extends Plugin
return;
}
setEvent(LootRecordType.EVENT, type, client.getBoostedSkillLevel(Skill.HUNTER));
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, type, client.getBoostedSkillLevel(Skill.HUNTER)));
return;
}
if (regionID == TEMPOROSS_REGION && message.startsWith(TEMPOROSS_LOOT_STRING))
{
setEvent(LootRecordType.EVENT, TEMPOROSS_EVENT, client.getBoostedSkillLevel(Skill.FISHING));
takeInventorySnapshot();
onInvChange(collectInvItems(LootRecordType.EVENT, TEMPOROSS_EVENT, client.getBoostedSkillLevel(Skill.FISHING)));
return;
}
if (message.equals(IMPLING_CATCH_MESSAGE))
{
onInvChange(collectInvItems(LootRecordType.EVENT, client.getLocalPlayer().getInteracting().getName()));
return;
}
}
@Subscribe
public void onItemContainerChanged(ItemContainerChanged event)
{
if (event.getContainerId() != InventoryID.INVENTORY.getId()
|| eventType == null)
// when the wilderness chest empties, clear chest loot flag for the next key
if (event.getContainerId() == InventoryID.WILDERNESS_LOOT_CHEST.getId()
&& Arrays.stream(event.getItemContainer().getItems()).noneMatch(i -> i.getId() > -1))
{
log.debug("Resetting chest loot flag");
chestLooted = false;
}
if (inventoryId == null || event.getContainerId() != inventoryId.getId())
{
return;
}
if (CHEST_EVENT_TYPES.containsValue(eventType)
|| SHADE_CHEST_OBJECTS.containsValue(eventType)
|| HALLOWED_SEPULCHRE_COFFIN_EVENT.equals(eventType)
|| HALLOWED_SACK_EVENT.equals(eventType)
|| HERBIBOAR_EVENT.equals(eventType)
|| HESPORI_EVENT.equals(eventType)
|| WINTERTODT_SUPPLY_CRATE_EVENT.equals(eventType)
|| eventType.endsWith("Bird House")
|| eventType.startsWith("H.A.M. chest")
|| lootRecordType == LootRecordType.PICKPOCKET
|| eventType.endsWith("lockbox"))
{
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
Collection<ItemStack> groundItems = lootManager.getItemSpawns(playerLocation);
final ItemContainer inventoryContainer = event.getItemContainer();
Multiset<Integer> currentInventory = HashMultiset.create();
Arrays.stream(inventoryContainer.getItems())
.forEach(item -> currentInventory.add(item.getId(), item.getQuantity()));
processInventoryLoot(eventType, lootRecordType, metadata, event.getItemContainer(), groundItems);
resetEvent();
}
// Events that do not produce ground items
else if (SEEDPACK_EVENT.equals(eventType)
|| CASKET_EVENT.equals(eventType)
|| BIRDNEST_EVENT.equals(eventType)
|| SPOILS_OF_WAR_EVENT.equals(eventType)
|| TEMPOROSS_EVENT.equals(eventType)
|| TEMPOROSS_CASKET_EVENT.equals(eventType)
|| MAHOGANY_CRATE_EVENT.equals(eventType))
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
final Collection<ItemStack> groundItems = lootManager.getItemSpawns(playerLocation);
final Multiset<Integer> diff = Multisets.difference(currentInventory, inventorySnapshot);
final Multiset<Integer> diffr = Multisets.difference(inventorySnapshot, currentInventory);
final List<ItemStack> items = diff.entrySet().stream()
.map(e -> new ItemStack(e.getElement(), e.getCount(), client.getLocalPlayer().getLocalLocation()))
.collect(Collectors.toList());
log.debug("Inv change: {} Ground items: {}", items, groundItems);
if (inventorySnapshotCb != null)
{
processInventoryLoot(eventType, lootRecordType, metadata, event.getItemContainer(), Collections.emptyList());
resetEvent();
inventorySnapshotCb.accept(items, groundItems, diffr);
}
inventoryId = null;
inventorySnapshot = null;
inventorySnapshotCb = null;
}
@Subscribe
@@ -911,58 +945,60 @@ public class LootTrackerPlugin extends Plugin
}
else if (isObjectOp(event.getMenuAction()) && event.getMenuOption().equals("Open") && SHADE_CHEST_OBJECTS.containsKey(event.getId()))
{
setEvent(LootRecordType.EVENT, SHADE_CHEST_OBJECTS.get(event.getId()));
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, SHADE_CHEST_OBJECTS.get(event.getId())));
}
else if (isItemOp(event.getMenuAction()))
{
if (event.getMenuOption().equals("Take") && event.getId() == ItemID.SEED_PACK)
{
setEvent(LootRecordType.EVENT, SEEDPACK_EVENT);
takeInventorySnapshot();
onInvChange(collectInvItems(LootRecordType.EVENT, SEEDPACK_EVENT));
}
else if (event.getMenuOption().equals("Search") && BIRDNEST_IDS.contains(event.getId()))
{
setEvent(LootRecordType.EVENT, BIRDNEST_EVENT, event.getId());
takeInventorySnapshot();
onInvChange(collectInvItems(LootRecordType.EVENT, BIRDNEST_EVENT));
}
else if (event.getMenuOption().equals("Open"))
{
switch (event.getId())
{
case ItemID.CASKET:
setEvent(LootRecordType.EVENT, CASKET_EVENT);
takeInventorySnapshot();
onInvChange(collectInvItems(LootRecordType.EVENT, CASKET_EVENT));
break;
case ItemID.SUPPLY_CRATE:
case ItemID.EXTRA_SUPPLY_CRATE:
setEvent(LootRecordType.EVENT, WINTERTODT_SUPPLY_CRATE_EVENT);
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, WINTERTODT_SUPPLY_CRATE_EVENT));
break;
case ItemID.SPOILS_OF_WAR:
setEvent(LootRecordType.EVENT, SPOILS_OF_WAR_EVENT);
takeInventorySnapshot();
onInvChange(collectInvItems(LootRecordType.EVENT, SPOILS_OF_WAR_EVENT));
break;
case ItemID.CASKET_25590:
setEvent(LootRecordType.EVENT, TEMPOROSS_CASKET_EVENT);
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, TEMPOROSS_CASKET_EVENT));
break;
case ItemID.SIMPLE_LOCKBOX_25647:
case ItemID.ELABORATE_LOCKBOX_25649:
case ItemID.ORNATE_LOCKBOX_25651:
setEvent(LootRecordType.EVENT, itemManager.getItemComposition(event.getId()).getName());
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, itemManager.getItemComposition(event.getId()).getName()));
break;
case ItemID.SUPPLY_CRATE_24884:
setEvent(LootRecordType.EVENT, MAHOGANY_CRATE_EVENT, client.getBoostedSkillLevel(Skill.CONSTRUCTION));
takeInventorySnapshot();
onInvChange(collectInvItems(LootRecordType.EVENT, MAHOGANY_CRATE_EVENT, client.getBoostedSkillLevel(Skill.CONSTRUCTION)));
break;
case ItemID.HALLOWED_SACK:
setEvent(LootRecordType.EVENT, HALLOWED_SACK_EVENT);
takeInventorySnapshot();
onInvChange(collectInvAndGroundItems(LootRecordType.EVENT, HALLOWED_SACK_EVENT));
break;
}
}
else if (event.getMenuOption().equals("Loot") && IMPLING_JARS.contains(event.getId()))
{
onInvChange(((invItems, groundItems, removedItems) ->
{
int cnt = removedItems.count(event.getId());
if (cnt > 0)
{
String name = itemManager.getItemComposition(event.getId()).getName();
addLoot(name, -1, LootRecordType.EVENT, null, invItems, cnt);
}
}));
}
}
}
@@ -1057,59 +1093,65 @@ public class LootTrackerPlugin extends Plugin
}
}
private void setEvent(LootRecordType lootRecordType, String eventType, Object metadata)
{
this.lootRecordType = lootRecordType;
this.eventType = eventType;
this.metadata = metadata;
}
private void setEvent(LootRecordType lootRecordType, String eventType)
{
setEvent(lootRecordType, eventType, null);
}
private void resetEvent()
{
lootRecordType = null;
eventType = null;
metadata = null;
inventoryId = null;
inventorySnapshot = null;
inventorySnapshotCb = null;
}
private void takeInventorySnapshot()
@FunctionalInterface
interface InvChangeCallback
{
final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY);
void accept(Collection<ItemStack> invItems, Collection<ItemStack> groundItems, Multiset<Integer> removedItems);
}
private InvChangeCallback collectInvItems(LootRecordType type, String event)
{
return collectInvItems(type, event, null);
}
private InvChangeCallback collectInvItems(LootRecordType type, String event, Object metadata)
{
return (invItems, groundItems, removedItems) ->
addLoot(event, -1, type, metadata, invItems);
}
private InvChangeCallback collectInvAndGroundItems(LootRecordType type, String event)
{
return collectInvAndGroundItems(type, event, null);
}
private InvChangeCallback collectInvAndGroundItems(LootRecordType type, String event, Object metadata)
{
return (invItems, groundItems, removedItems) ->
{
List<ItemStack> combined = new ArrayList<>();
combined.addAll(invItems);
combined.addAll(groundItems);
addLoot(event, -1, type, metadata, combined);
};
}
private void onInvChange(InvChangeCallback cb)
{
onInvChange(InventoryID.INVENTORY, cb);
}
private void onInvChange(InventoryID inv, InvChangeCallback cb)
{
inventoryId = inv;
inventorySnapshot = HashMultiset.create();
inventorySnapshotCb = cb;
final ItemContainer itemContainer = client.getItemContainer(inv);
if (itemContainer != null)
{
inventorySnapshot = HashMultiset.create();
Arrays.stream(itemContainer.getItems())
.forEach(item -> inventorySnapshot.add(item.getId(), item.getQuantity()));
}
}
private void processInventoryLoot(String event, LootRecordType lootRecordType, Object metadata, ItemContainer inventoryContainer, Collection<ItemStack> groundItems)
{
if (inventorySnapshot != null)
{
Multiset<Integer> currentInventory = HashMultiset.create();
Arrays.stream(inventoryContainer.getItems())
.forEach(item -> currentInventory.add(item.getId(), item.getQuantity()));
groundItems.stream()
.forEach(item -> currentInventory.add(item.getId(), item.getQuantity()));
final Multiset<Integer> diff = Multisets.difference(currentInventory, inventorySnapshot);
List<ItemStack> items = diff.entrySet().stream()
.map(e -> new ItemStack(e.getElement(), e.getCount(), client.getLocalPlayer().getLocalLocation()))
.collect(Collectors.toList());
addLoot(event, -1, lootRecordType, metadata, items);
inventorySnapshot = null;
}
}
private boolean processHerbiboarHerbSackLoot(int timestamp)
{
List<ItemStack> herbs = new ArrayList<>();

View File

@@ -3358,5 +3358,57 @@
"z1": 0,
"z2": 3
}
],
"7243": [ // Cabin Fever ships
{
"rx1": 21,
"ry1": 23,
"rx2": 25,
"ry2": 46,
"z1": 0,
"z2": 0
},
{
"rx1": 30,
"ry1": 19,
"rx2": 34,
"ry2": 42,
"z1": 0,
"z2": 0
}
],
"12336": [ // Tutorial Island
{ // bank front
"rx1": 46,
"ry1": 46,
"rx2": 53,
"ry2": 46,
"z1": 0,
"z2": 0
},
{ // bank back
"rx1": 47,
"ry1": 54,
"rx2": 48,
"ry2": 54,
"z1": 0,
"z2": 0
},
{ // monastery
"rx1": 57,
"ry1": 34,
"rx2": 57,
"ry2": 35,
"z1": 0,
"z2": 0
},
{ // monastery z1
"rx1": 43,
"ry1": 33,
"rx2": 52,
"ry2": 36,
"z1": 1,
"z2": 1
}
]
}