diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java index a0d30e8be9..a88552e37e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.cannon; +import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; import java.awt.Color; import java.time.temporal.ChronoUnit; @@ -38,7 +39,6 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameObject; import net.runelite.api.InventoryID; -import net.runelite.api.Item; import net.runelite.api.ItemID; import static net.runelite.api.ObjectID.CANNON_BASE; import net.runelite.api.Player; @@ -62,6 +62,7 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.task.Schedule; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.ItemUtil; @PluginDescriptor( name = "Cannon", @@ -72,6 +73,9 @@ public class CannonPlugin extends Plugin { private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)"); private static final int MAX_CBALLS = 30; + private static final ImmutableSet CANNON_PARTS = ImmutableSet.of( + ItemID.CANNON_BASE, ItemID.CANNON_STAND, ItemID.CANNON_BARRELS, ItemID.CANNON_FURNACE + ); private CannonCounter counter; private boolean skipProjectileCheckThisTick; @@ -157,46 +161,7 @@ public class CannonPlugin extends Plugin return; } - boolean hasBase = false; - boolean hasStand = false; - boolean hasBarrels = false; - boolean hasFurnace = false; - boolean hasAll = false; - - if (!cannonPlaced) - { - for (Item item : event.getItemContainer().getItems()) - { - if (item == null) - { - continue; - } - - switch (item.getId()) - { - case ItemID.CANNON_BASE: - hasBase = true; - break; - case ItemID.CANNON_STAND: - hasStand = true; - break; - case ItemID.CANNON_BARRELS: - hasBarrels = true; - break; - case ItemID.CANNON_FURNACE: - hasFurnace = true; - break; - } - - if (hasBase && hasStand && hasBarrels && hasFurnace) - { - hasAll = true; - break; - } - } - } - - cannonSpotOverlay.setHidden(!hasAll); + cannonSpotOverlay.setHidden(!ItemUtil.containsAllItemIds(event.getItemContainer().getItems(), CANNON_PARTS)); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java index 6dc32fde32..8ca2ed8a31 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java @@ -36,10 +36,8 @@ import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.image.BufferedImage; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.stream.Stream; import javax.inject.Inject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -97,6 +95,7 @@ import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.TextComponent; import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.ItemUtil; import net.runelite.client.util.Text; @PluginDescriptor( @@ -254,10 +253,8 @@ public class ClueScrollPlugin extends Plugin // Check if item was removed from inventory if (clue != null && clueItemId != null) { - final Stream items = Arrays.stream(event.getItemContainer().getItems()); - // Check if clue was removed from inventory - if (items.noneMatch(item -> itemManager.getItemComposition(item.getId()).getId() == clueItemId)) + if (!ItemUtil.containsItemId(event.getItemContainer().getItems(), clueItemId)) { resetClue(true); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java index 995c6b90e0..34d036ae5a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java @@ -28,15 +28,12 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.util.AbstractMap; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.stream.Stream; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.runelite.api.Client; import net.runelite.api.InventoryID; -import net.runelite.api.Item; import static net.runelite.api.ItemID.TORN_CLUE_SCROLL_PART_1; import static net.runelite.api.ItemID.TORN_CLUE_SCROLL_PART_2; import static net.runelite.api.ItemID.TORN_CLUE_SCROLL_PART_3; @@ -48,6 +45,7 @@ import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; 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.util.ItemUtil; import net.runelite.client.util.Text; @Getter @@ -127,21 +125,19 @@ public class ThreeStepCrypticClue extends ClueScroll implements TextClueScroll, if (event.getItemContainer() == client.getItemContainer(InventoryID.INVENTORY)) { boolean success = false; - success |= checkForPart(event, itemManager, TORN_CLUE_SCROLL_PART_1, 0); - success |= checkForPart(event, itemManager, TORN_CLUE_SCROLL_PART_2, 1); - success |= checkForPart(event, itemManager, TORN_CLUE_SCROLL_PART_3, 2); + success |= checkForPart(event, TORN_CLUE_SCROLL_PART_1, 0); + success |= checkForPart(event, TORN_CLUE_SCROLL_PART_2, 1); + success |= checkForPart(event, TORN_CLUE_SCROLL_PART_3, 2); return success; } return false; } - private boolean checkForPart(final ItemContainerChanged event, ItemManager itemManager, int clueScrollPart, int index) + private boolean checkForPart(final ItemContainerChanged event, int clueScrollPart, int index) { - final Stream items = Arrays.stream(event.getItemContainer().getItems()); - // If we have the part then that step is done - if (items.anyMatch(item -> itemManager.getItemComposition(item.getId()).getId() == clueScrollPart)) + if (ItemUtil.containsItemId(event.getItemContainer().getItems(), clueScrollPart)) { final Map.Entry entry = clueSteps.get(index); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java index 2f55bf8158..aa4db54c50 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java @@ -25,6 +25,7 @@ */ package net.runelite.client.plugins.fishing; +import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; import java.time.Duration; import java.time.Instant; @@ -43,7 +44,6 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; 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.NPC; @@ -69,6 +69,7 @@ import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.xptracker.XpTrackerPlugin; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.ItemUtil; @PluginDescriptor( name = "Fishing", @@ -87,6 +88,15 @@ public class FishingPlugin extends Plugin private Instant trawlerStartTime; + private static final ImmutableSet FISHING_TOOLS = ImmutableSet.of( + ItemID.DRAGON_HARPOON, ItemID.INFERNAL_HARPOON, ItemID.INFERNAL_HARPOON_UNCHARGED, ItemID.HARPOON, + ItemID.BARBTAIL_HARPOON, ItemID.BIG_FISHING_NET, ItemID.SMALL_FISHING_NET, ItemID.SMALL_FISHING_NET_6209, + ItemID.FISHING_ROD, ItemID.FLY_FISHING_ROD, ItemID.BARBARIAN_ROD, ItemID.OILY_FISHING_ROD, + ItemID.LOBSTER_POT, ItemID.KARAMBWAN_VESSEL, ItemID.KARAMBWAN_VESSEL_3159, + ItemID.CORMORANTS_GLOVE, ItemID.CORMORANTS_GLOVE_22817, + ItemID.PEARL_FISHING_ROD, ItemID.PEARL_FLY_FISHING_ROD, ItemID.PEARL_BARBARIAN_ROD + ); + @Getter(AccessLevel.PACKAGE) private final FishingSession session = new FishingSession(); @@ -234,39 +244,7 @@ public class FishingPlugin extends Plugin return false; } - for (Item item : itemContainer.getItems()) - { - if (item == null) - { - continue; - } - switch (item.getId()) - { - case ItemID.DRAGON_HARPOON: - case ItemID.INFERNAL_HARPOON: - case ItemID.INFERNAL_HARPOON_UNCHARGED: - case ItemID.HARPOON: - case ItemID.BARBTAIL_HARPOON: - case ItemID.BIG_FISHING_NET: - case ItemID.SMALL_FISHING_NET: - case ItemID.SMALL_FISHING_NET_6209: - case ItemID.FISHING_ROD: - case ItemID.FLY_FISHING_ROD: - case ItemID.PEARL_BARBARIAN_ROD: - case ItemID.PEARL_FISHING_ROD: - case ItemID.PEARL_FLY_FISHING_ROD: - case ItemID.BARBARIAN_ROD: - case ItemID.OILY_FISHING_ROD: - case ItemID.LOBSTER_POT: - case ItemID.KARAMBWAN_VESSEL: - case ItemID.KARAMBWAN_VESSEL_3159: - case ItemID.CORMORANTS_GLOVE: - case ItemID.CORMORANTS_GLOVE_22817: - return true; - } - } - - return false; + return ItemUtil.containsAnyItemId(itemContainer.getItems(), FISHING_TOOLS); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/PrayerPotion.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/PrayerPotion.java index 4c0bfff6a1..bd2fbfa4b6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/PrayerPotion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/potions/PrayerPotion.java @@ -24,13 +24,16 @@ */ package net.runelite.client.plugins.itemstats.potions; +import com.google.common.collect.ImmutableSet; import net.runelite.api.Client; +import net.runelite.api.EquipmentInventorySlot; import net.runelite.api.InventoryID; import net.runelite.api.Item; import net.runelite.api.ItemContainer; import net.runelite.api.ItemID; import net.runelite.client.plugins.itemstats.StatBoost; import static net.runelite.client.plugins.itemstats.stats.Stats.PRAYER; +import net.runelite.client.util.ItemUtil; public class PrayerPotion extends StatBoost { @@ -42,8 +45,11 @@ public class PrayerPotion extends StatBoost this.delta = delta; } - private static final int RING_SLOT = 12; - private static final int CAPE_SLOT = 1; + private static final ImmutableSet HOLY_WRENCH_IDS = ImmutableSet.of( + ItemID.HOLY_WRENCH, ItemID.PRAYER_CAPE, ItemID.PRAYER_CAPET, ItemID.MAX_CAPE, ItemID.MAX_CAPE_13342, + // No idea what these are + ItemID.PRAYER_CAPE_10643, ItemID.MAX_CAPE_13282 + ); @Override public int heals(Client client) @@ -54,40 +60,18 @@ public class PrayerPotion extends StatBoost if (equipContainer != null) { Item[] equip = equipContainer.getItems(); + final int ring = ItemUtil.safeGetItemIdAtIndex(equip, EquipmentInventorySlot.RING.getSlotIdx()); + final int cape = ItemUtil.safeGetItemIdAtIndex(equip, EquipmentInventorySlot.CAPE.getSlotIdx()); - hasHolyWrench |= equip.length > RING_SLOT && equip[RING_SLOT].getId() == ItemID.RING_OF_THE_GODS_I; - if (equip.length > CAPE_SLOT) - { - int cape = equip[CAPE_SLOT].getId(); - hasHolyWrench |= cape == ItemID.PRAYER_CAPE; - hasHolyWrench |= cape == ItemID.PRAYER_CAPET; - hasHolyWrench |= cape == ItemID.PRAYER_CAPE_10643; // No idea what this is - hasHolyWrench |= cape == ItemID.MAX_CAPE; - hasHolyWrench |= cape == ItemID.MAX_CAPE_13282; // Or these - hasHolyWrench |= cape == ItemID.MAX_CAPE_13342; - } + hasHolyWrench |= ring == ItemID.RING_OF_THE_GODS_I; + hasHolyWrench |= HOLY_WRENCH_IDS.contains(cape); } if (!hasHolyWrench) { ItemContainer invContainer = client.getItemContainer(InventoryID.INVENTORY); if (invContainer != null) { - for (Item itemStack : invContainer.getItems()) - { - int item = itemStack.getId(); - hasHolyWrench |= item == ItemID.HOLY_WRENCH; - hasHolyWrench |= item == ItemID.PRAYER_CAPE; - hasHolyWrench |= item == ItemID.PRAYER_CAPET; - hasHolyWrench |= item == ItemID.PRAYER_CAPE_10643; - hasHolyWrench |= item == ItemID.MAX_CAPE; - hasHolyWrench |= item == ItemID.MAX_CAPE_13282; - hasHolyWrench |= item == ItemID.MAX_CAPE_13342; - - if (hasHolyWrench) - { - break; - } - } + hasHolyWrench = ItemUtil.containsAnyItemId(invContainer.getItems(), HOLY_WRENCH_IDS); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java index 9a3908f7d3..138ee3d9ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java @@ -49,9 +49,9 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "Rogues' Den", - description = "Mark tiles and clickboxes to help traverse the maze", - tags = {"agility", "maze", "minigame", "overlay", "thieving"} + name = "Rogues' Den", + description = "Mark tiles and clickboxes to help traverse the maze", + tags = {"agility", "maze", "minigame", "overlay", "thieving"} ) public class RoguesDenPlugin extends Plugin { @@ -168,4 +168,4 @@ public class RoguesDenPlugin extends Plugin obstaclesTile.put(newObject, tile); } } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/util/ItemUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ItemUtil.java new file mode 100644 index 0000000000..c3cfeb599e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/ItemUtil.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2018, 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.util; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nullable; +import net.runelite.api.Item; +import net.runelite.http.api.loottracker.GameItem; + +/** + * Utility class for Item arrays. + */ +public class ItemUtil +{ + /** + * Converts itemArray into a GameItem collection limited to the passed ids + * Consolidates all matching Item's qty, by id + * @param itemArray item array to work on + * @param ids item ids to include in result + * @return Map of GameItem by item id + */ + public static Map toGameItemMap(Item[] itemArray, @Nullable Set ids) + { + final Map map = new HashMap<>(); + for (Item i : itemArray) + { + final int id = i.getId(); + if (ids == null || ids.contains(id)) + { + int qty = i.getQuantity(); + if (map.containsKey(id)) + { + qty += map.get(id).getQty(); + } + map.put(id, new GameItem(id, qty)); + } + } + + return map; + } + + /** + * Converts itemArray into a GameItem collection + * Consolidates all matching Item's qty, by id + * @param itemArray item array to work on + * @return Map of GameItem by item id + */ + public static Map toGameItemMap(Item[] itemArray) + { + return toGameItemMap(itemArray, null); + } + + /** + * Checks that the itemArray contains the all of the requested ids + * @param itemArray item array to work on + * @param ids item ids to check for + * @return true if itemArray contains all requested item ids + */ + public static boolean containsAllItemIds(Item[] itemArray, Set ids) + { + final Set found = new HashSet<>(); + for (Item i : itemArray) + { + final int id = i.getId(); + if (ids.contains(id)) + { + found.add(id); + // Early break if possible + if (found.size() == ids.size()) + { + return true; + } + } + + } + + return found.size() == ids.size(); + } + + /** + * Checks if itemArray contains any item id that also exists in ids + * @param itemArray item array to work on + * @param ids item ids to check for + * @return true if any item in itemArray contains any id from ids + */ + public static boolean containsAnyItemId(Item[] itemArray, Set ids) + { + for (Item i : itemArray) + { + final int id = i.getId(); + if (ids.contains(id)) + { + return true; + } + } + + return false; + } + + /** + * Checks if any item id in itemArray matches itemID + * @param itemArray item array to work on + * @param itemID item id to check for + * @return true if any item in itemArray matches itemID + */ + public static boolean containsItemId(Item[] itemArray, int itemID) + { + for (Item i : itemArray) + { + if (i.getId() == itemID) + { + return true; + } + } + + return false; + } + + /** + * Returns null if index is bigger than array otherwise array content. + * @param itemArray item array to check + * @param index index to grab + * @return null if index is bigger than array otherwise array content + */ + public static Item safeGetItemAtIndex(Item[] itemArray, int index) + { + if (itemArray.length <= index) + { + return null; + } + + return itemArray[index]; + } + + /** + * Returns -1 if index is bigger than array otherwise array contents `id` value + * @param itemArray item array to check + * @param index index to grab + * @return -1 if index is bigger than array otherwise array contents `id` value + */ + public static Integer safeGetItemIdAtIndex(Item[] itemArray, int index) + { + if (itemArray.length <= index) + { + return -1; + } + + return itemArray[index].getId(); + } + + /** + * Checks that the itemArray contains all requestedItems. Must contain >= the requested qty for each id + * Uses GameItem to represent the requestedItems since we can't easily create Item instances + * @param itemArray item array to check against + * @param requestedItems Collection of GameItems which contain the item id & minimum qty + * @return true if contains all requestedItems + */ + public static boolean containsAllGameItems(Item[] itemArray, Collection requestedItems) + { + final Map map = toGameItemMap(itemArray, null); + for (GameItem i : requestedItems) + { + final int id = i.getId(); + GameItem item = map.get(id); + if (item == null) + { + return false; + } + + if (item.getQty() < i.getQty()) + { + return false; + } + } + + return true; + } + + /** + * Checks that the itemArray contains all requestedItems. Must contain >= the requested qty for each id + * Uses GameItem to represent the requestedItems since we can't easily create Item instances + * @param itemArray item array to check against + * @param requestedItems GameItem(s) to request + * @return true if contains all requestedItems + */ + public static boolean containsAllGameItems(Item[] itemArray, GameItem... requestedItems) + { + return containsAllGameItems(itemArray, Arrays.asList(requestedItems)); + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/util/ItemUtilTest.java b/runelite-client/src/test/java/net/runelite/client/util/ItemUtilTest.java new file mode 100644 index 0000000000..f69238896d --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/util/ItemUtilTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2018, 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.util; + +import com.google.common.collect.ImmutableSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import net.runelite.api.Item; +import net.runelite.api.ItemID; +import net.runelite.http.api.loottracker.GameItem; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ItemUtilTest +{ + private static final Set SOME_IDS = ImmutableSet.of(ItemID.MITHRIL_BAR, ItemID.DRAGON_BONES); + private static final Set WRONG_IDS = ImmutableSet.of(ItemID.SCYTHE_OF_VITUR, ItemID.TWISTED_BOW); + private static final Set MIX_IDS = ImmutableSet.of( + ItemID.MITHRIL_BAR, ItemID.DRAGON_BONES, + ItemID.SCYTHE_OF_VITUR, ItemID.TWISTED_BOW + ); + + private static final Map SOME_MAP = new HashMap<>(); + private static final Map ALL_MAP = new HashMap<>(); + + private static final Item[] items = new Item[6]; + + static + { + SOME_MAP.put(ItemID.MITHRIL_BAR, new GameItem(ItemID.MITHRIL_BAR, 6)); + SOME_MAP.put(ItemID.DRAGON_BONES, new GameItem(ItemID.DRAGON_BONES, 2)); + + ALL_MAP.putAll(SOME_MAP); + ALL_MAP.put(ItemID.COINS_995, new GameItem(ItemID.COINS_995, 1000)); + ALL_MAP.put(ItemID.CHEWED_BONES, new GameItem(ItemID.CHEWED_BONES, 1)); + + items[0] = createItem(ItemID.MITHRIL_BAR, 3); + items[1] = createItem(ItemID.DRAGON_BONES, 1); + items[2] = createItem(ItemID.COINS_995, 1000); + + items[3] = createItem(ItemID.MITHRIL_BAR, 3); + items[4] = createItem(ItemID.DRAGON_BONES, 1); + items[5] = createItem(ItemID.CHEWED_BONES, 1); + } + + private static Item createItem(int id, int qty) + { + Item i = mock(Item.class); + when(i.getId()) + .thenReturn(id); + when(i.getQuantity()) + .thenReturn(qty); + + return i; + } + + @Test + public void toGameItemMap() + { + Map itemMap = ItemUtil.toGameItemMap(items, SOME_IDS); + assertEquals(SOME_MAP, itemMap); + assertNotEquals(ALL_MAP, itemMap); + + Map itemMap2 = ItemUtil.toGameItemMap(items); + assertNotEquals(SOME_MAP, itemMap2); + assertEquals(ALL_MAP, itemMap2); + } + + @Test + public void containsAllItemIds() + { + assertTrue(ItemUtil.containsAllItemIds(items, SOME_IDS)); + assertFalse(ItemUtil.containsAllItemIds(items, WRONG_IDS)); + assertFalse(ItemUtil.containsAllItemIds(items, MIX_IDS)); + } + + @Test + public void containsAnyItemId() + { + assertTrue(ItemUtil.containsAnyItemId(items, SOME_IDS)); + assertFalse(ItemUtil.containsAnyItemId(items, WRONG_IDS)); + assertTrue(ItemUtil.containsAnyItemId(items, MIX_IDS)); + } + + @Test + public void containsItemId() + { + assertTrue(ItemUtil.containsItemId(items, ItemID.COINS_995)); + assertFalse(ItemUtil.containsItemId(items, ItemID.TWISTED_BOW)); + } + + @Test + public void containsAllGameItems() + { + assertTrue(ItemUtil.containsAllGameItems(items, SOME_MAP.values())); + assertTrue(ItemUtil.containsAllGameItems(items, ALL_MAP.values())); + + Collection wrongItems = new ArrayList<>(SOME_MAP.values()); + wrongItems.add(new GameItem(ItemID.TWISTED_BOW, 1)); + assertFalse(ItemUtil.containsAllGameItems(items, wrongItems)); + + assertFalse(ItemUtil.containsAllGameItems(items, new GameItem(ItemID.MITHRIL_BAR, 7))); + assertTrue(ItemUtil.containsAllGameItems(items, new GameItem(ItemID.MITHRIL_BAR, 6))); + assertTrue(ItemUtil.containsAllGameItems(items, new GameItem(ItemID.MITHRIL_BAR, 5))); + assertFalse(ItemUtil.containsAllGameItems(items, new GameItem(ItemID.MITHRIL_BAR, 5), new GameItem(ItemID.TWISTED_BOW, 1))); + } +}