diff --git a/src/main/java/com/questhelper/QuestHelperPlugin.java b/src/main/java/com/questhelper/QuestHelperPlugin.java index ff19fc6697..bcf4d8b4e2 100644 --- a/src/main/java/com/questhelper/QuestHelperPlugin.java +++ b/src/main/java/com/questhelper/QuestHelperPlugin.java @@ -29,6 +29,7 @@ import com.google.inject.Injector; import com.google.inject.Provides; import com.questhelper.bank.banktab.BankTabItems; +import com.questhelper.bank.banktab.PotionStorage; import com.questhelper.managers.*; import com.questhelper.panel.QuestHelperPanel; import com.questhelper.questhelpers.QuestHelper; @@ -72,6 +73,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.bank.BankSearch; +import net.runelite.client.plugins.banktags.tabs.Layout; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.components.colorpicker.ColorPickerManager; @@ -154,6 +156,9 @@ public class QuestHelperPlugin extends Plugin @Inject PlayerStateManager playerStateManager; + @Inject + PotionStorage potionStorage; + @Inject public SkillIconManager skillIconManager; @@ -177,6 +182,7 @@ protected void startUp() throws IOException { questBankManager.startUp(injector, eventBus); QuestContainerManager.getBankData().setSpecialMethodToObtainItems(() -> questBankManager.getBankItems().toArray(new Item[0])); + QuestContainerManager.getPotionData().setSpecialMethodToObtainItems(() -> potionStorage.getItems()); eventBus.register(worldMapAreaManager); injector.injectMembers(playerStateManager); @@ -283,6 +289,7 @@ public void onGameStateChanged(final GameStateChanged event) GlobalFakeObjects.createNpcs(client, runeliteObjectManager, configManager, config); newVersionManager.updateChatWithNotificationIfNewVersion(); questBankManager.setUnknownInitialState(); + potionStorage.cachePotions = true; clientThread.invokeAtTickEnd(() -> { questManager.setupRequirements(); questManager.setupOnLogin(); diff --git a/src/main/java/com/questhelper/bank/banktab/BankTabItem.java b/src/main/java/com/questhelper/bank/banktab/BankTabItem.java index a19ddc33a0..9b76c2bb1e 100644 --- a/src/main/java/com/questhelper/bank/banktab/BankTabItem.java +++ b/src/main/java/com/questhelper/bank/banktab/BankTabItem.java @@ -67,7 +67,7 @@ public BankTabItem(ItemRequirement item) this.text = item.getName(); this.itemIDs = Collections.singletonList(item.getId()); this.details = item.getTooltip(); - this.displayID = null; + this.displayID = -1; this.itemRequirement = item; } } diff --git a/src/main/java/com/questhelper/bank/banktab/PotionStorage.java b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java new file mode 100644 index 0000000000..de9f052061 --- /dev/null +++ b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2024, Adam + * 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 com.questhelper.bank.banktab; + +import java.util.*; +import javax.inject.Inject; +import javax.inject.Singleton; + +import com.questhelper.managers.QuestContainerManager; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.widgets.ComponentID; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetType; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.bank.BankSearch; + +class Potion +{ + EnumComposition potionEnum; + int itemId; + int doses; + int withdrawDoses; +} + +@Singleton +@RequiredArgsConstructor(onConstructor = @__(@Inject)) +@Slf4j +public class PotionStorage +{ + static final int TOTAL_POTIONS_VARBIT = 4286; + static final int VIAL_IDX = 514; + static final int COMPONENTS_PER_POTION = 5; + + private final Client client; + private final ItemManager itemManager; + private final BankSearch bankSearch; + + private Potion[] potions; + public boolean cachePotions; + private boolean layout; + private Set potionStoreVars; + + @Setter + private QuestBankTabInterface questBankTabInterface; + + @Subscribe + public void onClientTick(ClientTick event) + { + if (cachePotions) + { + log.debug("Rebuilding potions"); + cachePotions = false; + rebuildPotions(); + + Widget w = client.getWidget(ComponentID.BANK_POTIONSTORE_CONTENT); + if (w != null && potionStoreVars == null) + { + // cache varps that the potion store rebuilds on + int[] trigger = w.getVarTransmitTrigger(); + potionStoreVars = new HashSet<>(); + Arrays.stream(trigger).forEach(potionStoreVars::add); + } + + if (layout) + { + layout = false; + if (questBankTabInterface.isQuestTabActive()) + { + bankSearch.layoutBank(); + } + } + } + } + + // Use varp change event instead of a widget change listener so that we can recache the potions prior to + // the cs2 vm running. + @Subscribe + public void onVarbitChanged(VarbitChanged varbitChanged) + { + if (TOTAL_POTIONS_VARBIT == varbitChanged.getVarpId() || potionStoreVars != null && potionStoreVars.contains(varbitChanged.getVarpId())) + { + cachePotions = true; + layout = true; // trigger a bank rebuild as the qty has changed + } + } + + private void rebuildPotions() + { + var potionStorePotions = client.getEnum(EnumID.POTIONSTORE_POTIONS); + var potionStoreUnfinishedPotions = client.getEnum(EnumID.POTIONSTORE_UNFINISHED_POTIONS); + potions = new Potion[potionStorePotions.size() + potionStoreUnfinishedPotions.size() + 1]; + int potionsIdx = 0; + for (EnumComposition e : new EnumComposition[]{potionStorePotions, potionStoreUnfinishedPotions}) + { + for (int potionEnumId : e.getIntVals()) + { + var potionEnum = client.getEnum(potionEnumId); + client.runScript(ScriptID.POTIONSTORE_DOSES, potionEnumId); + int doses = client.getIntStack()[0]; + client.runScript(ScriptID.POTIONSTORE_WITHDRAW_DOSES, potionEnumId); + int withdrawDoses = client.getIntStack()[0]; + + if (doses > 0 && withdrawDoses > 0) + { + Potion p = new Potion(); + p.potionEnum = potionEnum; + p.itemId = potionEnum.getIntValue(withdrawDoses); + p.doses = doses; + p.withdrawDoses = withdrawDoses; + potions[potionsIdx] = p; + } + + ++potionsIdx; + } + } + + // Add vial + Potion p = new Potion(); + p.potionEnum = null; + p.itemId = ItemID.VIAL; + p.doses = client.getVarpValue(4286); + p.withdrawDoses = 0; + potions[potions.length - 1] = p; + + QuestContainerManager.getPotionData().update(client.getTickCount(), getItems()); + } + + public Item[] getItems() + { + if (potions == null) + { + return new Item[0]; + } + + List items = new ArrayList<>(); + + for (Potion potion : potions) + { + if (potion == null) continue; + var potionEnum = potion.potionEnum; + if (potionEnum != null) + { + int potionItemId = potionEnum.getIntValue(potion.withdrawDoses); + int quantity = potion.doses / potion.withdrawDoses; + items.add(new Item(potionItemId, quantity)); + } + else + { + items.add(new Item(potion.itemId, potion.doses)); + } + } + + return items.toArray(new Item[0]); + } + + int count(int itemId) + { + if (potions == null) + { + return 0; + } + + for (Potion potion : potions) + { + if (potion != null && potion.itemId == itemId) + { + if (potion.withdrawDoses != 0) + { + return potion.doses / potion.withdrawDoses; + } + + return potion.doses; + } + } + return 0; + } + + int find(int itemId) + { + if (potions == null) + { + return -1; + } + + if (itemId == ItemID.VIAL) + { + return VIAL_IDX; + } + + int potionIdx = 0; + for (Potion potion : potions) + { + ++potionIdx; + if (potion != null && potion.itemId == itemId) + { + return potionIdx - 1; + } + } + return -1; + } + + public void prepareWidgets() + { + // if the potion store hasn't been opened yet, the client components won't have been made yet. + // they need to exist for the click to work correctly. + Widget potStoreContent = client.getWidget(ComponentID.BANK_POTIONSTORE_CONTENT); + if (potStoreContent.getChildren() == null) + { + int childIdx = 0; + for (int i = 0; i < potions.length; ++i) // NOPMD: ForLoopCanBeForeach + { + for (int j = 0; j < COMPONENTS_PER_POTION; ++j) + { + potStoreContent.createChild(childIdx++, WidgetType.GRAPHIC); + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index 7211cd17fc..20b1564f14 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -33,46 +33,37 @@ import com.questhelper.requirements.item.ItemRequirement; import java.awt.Color; import java.awt.Point; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; -import net.runelite.api.ChatMessageType; -import net.runelite.api.Client; -import net.runelite.api.FontID; -import net.runelite.api.ItemID; -import net.runelite.api.ScriptEvent; -import net.runelite.api.ScriptID; -import net.runelite.api.SpriteID; -import net.runelite.api.VarClientStr; -import net.runelite.api.events.ClientTick; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; import net.runelite.api.events.GrandExchangeSearched; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptPostFired; import net.runelite.api.events.ScriptPreFired; import net.runelite.api.events.WidgetLoaded; -import net.runelite.api.widgets.ComponentID; -import net.runelite.api.widgets.InterfaceID; -import net.runelite.api.widgets.JavaScriptCallback; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetType; +import net.runelite.api.widgets.*; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.Text; +import static com.questhelper.bank.banktab.PotionStorage.COMPONENTS_PER_POTION; +import static com.questhelper.bank.banktab.PotionStorage.VIAL_IDX; +import static net.runelite.client.plugins.banktags.BankTagsPlugin.*; + @Singleton +@Slf4j public class QuestBankTab { private static final int ITEMS_PER_ROW = 8; @@ -82,8 +73,6 @@ public class QuestBankTab private static final int LINE_VERTICAL_SPACING = 5; private static final int LINE_HEIGHT = 2; private static final int TEXT_HEIGHT = 15; - private static final int ITEM_HEIGHT = 32; - private static final int ITEM_WIDTH = 36; private static final int EMPTY_BANK_SLOT_ID = 6512; private static final int MAX_RESULT_COUNT = 250; @@ -91,7 +80,6 @@ public class QuestBankTab private static final int CROSS_SPRITE_ID = 1216; private static final int TICK_SPRITE_ID = 1217; - private final ArrayList addedWidgets = new ArrayList<>(); @Inject @@ -115,9 +103,15 @@ public class QuestBankTab @Inject private QuestHelperPlugin questHelper; + @Inject + private PotionStorage potionStorage; + + @Inject + private QuestHelperBankTagService questHelperBankTagService; + private final HashMap widgetItems = new HashMap<>(); - private final HashMap fakeToRealItem = new HashMap<>(); + private int originalContainerChildren = -1; public void startUp() { @@ -132,14 +126,19 @@ public void shutDown() { clientThread.invokeLater(questBankTabInterface::destroy); clientThread.invokeLater(geButtonWidget::destroy); - if (!addedWidgets.isEmpty()) - { - for (Widget addedWidget : addedWidgets) - { - addedWidget.setHidden(true); - } - addedWidgets.clear(); - } + clientThread.invokeLater(this::removeAddedWidgets); + } + public void register(EventBus eventBus) + { + potionStorage.setQuestBankTabInterface(questBankTabInterface); + eventBus.register(potionStorage); + eventBus.register(this); + } + + public void unregister(EventBus eventBus) + { + eventBus.unregister(potionStorage); + eventBus.unregister(this); } public void refreshBankTab() @@ -177,16 +176,14 @@ public void updateGrandExchangeResults() client.setGeSearchResultIds(Shorts.toArray(ids)); } + @Subscribe public void onScriptPreFired(ScriptPreFired event) { int scriptId = event.getScriptId(); - if (scriptId == ScriptID.BANKMAIN_FINISHBUILDING) { - // Since we apply tag tab search filters even when the bank is not in search mode, - // bankkmain_build will reset the bank title to "The Bank of Gielinor". So apply our - // own title. + resetWidgets(); if (questBankTabInterface.isQuestTabActive()) { Widget bankTitle = client.getWidget(ComponentID.BANK_TITLE_BAR); @@ -201,6 +198,12 @@ public void onScriptPreFired(ScriptPreFired event) bankTitle.setText("Tab Quest Helper"); } } + + // Since the script vm isn't reentrant, we can't call into POTIONSTORE_DOSES/POTIONSTORE_WITHDRAW_DOSES + // from bankmain_finishbuilding for the layout. Instead, we record all of the potions on client tick, + // which is after this is run, but before the var/inv transmit listeners run, so that we will have + // them by the time the inv transmit listener runs. + potionStorage.cachePotions = true; } } else if (scriptId == ScriptID.BANKMAIN_SEARCH_TOGGLE) @@ -221,6 +224,32 @@ public void onScriptCallbackEvent(ScriptCallbackEvent event) { intStack[intStackSize - 1] = questBankTabInterface.isQuestTabActive() ? 1 : 0; } + else if ("bankSearchFilter".equals(eventName)) + { + final int itemId = intStack[intStackSize - 1]; + if (!questBankTabInterface.isQuestTabActive()) + { + return; + } + + if (itemId == -1) + { + // item -1 always passes on a laid out tab so items can be dragged to it + return; + } + List items = questHelperBankTagService.itemsToTagForBank(); + if (itemId > -1 && items.contains(itemId)) + { + // return true + intStack[intStackSize - 2] = 1; + } + else + { + // if the item isn't tagged we return false to prevent the item matching if the item name happens + // to contain the tag name. + intStack[intStackSize - 2] = 0; + } + } } @Subscribe @@ -232,31 +261,91 @@ public void onWidgetLoaded(WidgetLoaded event) } } - @Subscribe - public void onClientTick(ClientTick clientTick) + @Subscribe(priority = -1) + public void onMenuOptionClicked(MenuOptionClicked event) { - if (!questBankTabInterface.isQuestTabActive() || questBankTabInterface.isHidden()) return; + questBankTabInterface.handleClick(event); - net.runelite.api.Point mousePoint = client.getMouseCanvasPosition(); - if (fakeToRealItem.isEmpty()) + // Update widget index of the menu so withdraws work in laid out tabs. + if (event.getParam1() == ComponentID.BANK_ITEM_CONTAINER && questBankTabInterface.isQuestTabActive()) { - return; + MenuEntry menu = event.getMenuEntry(); + if ("Details".equals(menu.getOption())) + { + event.consume(); + + Widget widget = event.getWidget(); + if (widget == null) return; + BankTabItem bankTabItem = widgetItems.get(widget); + if (bankTabItem == null) return; + handleFakeItemClick(bankTabItem); + return; + } + + Widget w = menu.getWidget(); + if (w != null && w.getItemId() > -1) + { + ItemContainer bank = client.getItemContainer(InventoryID.BANK); + int idx = bank.find(w.getItemId()); + if (idx > -1 && menu.getParam0() != idx) + { + menu.setParam0(idx); + return; + } + + idx = potionStorage.find(w.getItemId()); + if (idx == VIAL_IDX) + { + potionStorage.prepareWidgets(); + menu.setParam1(ComponentID.BANK_POTIONSTORE_CONTENT); + menu.setParam0(VIAL_IDX); + } + else if (idx > -1) + { + potionStorage.prepareWidgets(); + menu.setParam1(ComponentID.BANK_POTIONSTORE_CONTENT); + menu.setParam0(idx * COMPONENTS_PER_POTION); + } + } } + } + + private void resetWidgets() + { + // We adjust the bank item container children's sizes in layouts, + // however they are only initially set when the bank is opened, + // so we have to reset them each time the bank is built. + Widget w = client.getWidget(ComponentID.BANK_ITEM_CONTAINER); + if (w == null || w.getChildren() == null) return; - for (BankWidget bankWidget : fakeToRealItem.keySet()) + for (Widget c : w.getChildren()) { - if (bankWidget.isPointOverWidget(mousePoint)) + if (c.getOriginalHeight() < BANK_ITEM_HEIGHT) { - bankWidget.swap(fakeToRealItem.get(bankWidget)); - return; + break; + } + + if (c.getOriginalWidth() != BANK_ITEM_WIDTH || c.getOriginalHeight() != BANK_ITEM_HEIGHT) + { + c.setOriginalWidth(BANK_ITEM_WIDTH); + c.setOriginalHeight(BANK_ITEM_HEIGHT); + c.revalidate(); } } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void removeAddedWidgets() { - questBankTabInterface.handleClick(event); + if (originalContainerChildren == -1) return; + + if (addedWidgets.isEmpty()) return; + Widget parent = addedWidgets.get(0).getParent(); + if (parent == null) return; + if (parent.getChildren() == null) return; + parent.setChildren(Arrays.copyOf(parent.getChildren(), originalContainerChildren)); + parent.revalidate(); + + addedWidgets.clear(); } @Subscribe @@ -276,15 +365,6 @@ public void onScriptPostFired(ScriptPostFired event) { client.getIntStack()[client.getIntStackSize() - 1] = 1; // true } - if (!addedWidgets.isEmpty()) - { - for (Widget addedWidget : addedWidgets) - { - addedWidget.setHidden(true); - } - addedWidgets.clear(); - } - fakeToRealItem.clear(); return; } @@ -294,6 +374,8 @@ public void onScriptPostFired(ScriptPostFired event) return; } + removeAddedWidgets(); + if (!questBankTabInterface.isQuestTabActive()) { return; @@ -304,17 +386,8 @@ public void onScriptPostFired(ScriptPostFired event) { return; } - - if (!addedWidgets.isEmpty()) - { - - for (Widget addedWidget : addedWidgets) - { - addedWidget.setHidden(true); - } - addedWidgets.clear(); - } - fakeToRealItem.clear(); + Widget[] children = itemContainer.getChildren(); + if (children != null && originalContainerChildren == -1) originalContainerChildren = children.length; Widget[] containerChildren = itemContainer.getDynamicChildren(); @@ -335,6 +408,12 @@ private void sortBankTabItems(Widget itemContainer, Widget[] containerChildren, { int totalSectionsHeight = 0; + widgetItems.clear(); + + // Hide all widgets as we'll be making our own using them + hideBankWidgets(itemContainer, containerChildren); + + List itemList = new ArrayList<>(); for (Widget itemWidget : containerChildren) { @@ -353,11 +432,10 @@ else if (!itemWidget.isHidden() && } List bankItemTexts = new ArrayList<>(); - HashMap itemIDsAdded = new HashMap<>(); for (BankTabItems bankTabItems : newLayout) { - totalSectionsHeight = addPluginTabSection(itemContainer, bankTabItems, itemList, totalSectionsHeight, bankItemTexts, itemIDsAdded); + totalSectionsHeight = addPluginTabSection(itemContainer, bankTabItems, totalSectionsHeight, bankItemTexts); } // We add item texts after all items are added so they always overlay @@ -377,18 +455,15 @@ else if (!itemWidget.isHidden() && { Widget realItemInInventorySprite = createIcon(itemContainer, bankText.spriteID, - 10, - 10, - bankText.spriteX, + bankText.spriteX, bankText.spriteY ); addedWidgets.add(realItemInInventorySprite); } + currentWidgetToUse = 0; } - totalSectionsHeight = addGeneralSection(itemContainer, itemList, totalSectionsHeight); - final Widget bankItemContainer = client.getWidget(ComponentID.BANK_ITEM_CONTAINER); if (bankItemContainer == null) return; int itemContainerHeight = bankItemContainer.getHeight(); @@ -403,9 +478,124 @@ else if (!itemWidget.isHidden() && itemContainerScroll)); } - private int addPluginTabSection(Widget itemContainer, BankTabItems items, List itemIds, - int totalSectionsHeight, List bankItemTexts, - HashMap itemIDsAdded) + private void hideBankWidgets(Widget itemContainer, Widget[] containerChildren) + { + for (int i = 0; i < containerChildren.length; ++i) + { + Widget widget = itemContainer.getChild(i); + if (widget == null) continue; + + // ~bankmain_drawitem uses 6512 for empty item slots + if (!widget.isSelfHidden() && + (widget.getItemId() > -1 && widget.getItemId() != NullItemID.NULL_6512) || + (widget.getSpriteId() == SpriteID.RESIZEABLE_MODE_SIDE_PANEL_BACKGROUND || widget.getText().contains("Tab")) + ) + { + widget.setHidden(true); + } + } + } + + private void drawItem(Widget c, int item, int qty, BankTabItem bankTabItem) + { + if (item > -1 && item != ItemID.BANK_FILLER) + { + ItemComposition def = client.getItemDefinition(item); + + c.setItemId(item); + c.setItemQuantity(qty); + c.setItemQuantityMode(1); + + // Effectively avoid dragging + c.setDragDeadTime(1000); + + c.setName("" + def.getName() + ""); + c.clearActions(); + + // Jagex Placeholder + if (def.getPlaceholderTemplateId() >= 0 && def.getPlaceholderId() >= 0) + { + c.setItemQuantity(qty); + c.setOpacity(120); + c.setAction(8 - 1, "Release"); + c.setAction(10 - 1, "Examine"); + } + // Layout placeholder + else if (qty == 0) + { + c.setOpacity(120); + c.setItemQuantity(0); + c.setItemQuantityMode(1); + c.setText("" + bankTabItem.getText() + ""); + c.setAction(1, "Details"); + } + else + { + int quantityType = client.getVarbitValue(Varbits.BANK_QUANTITY_TYPE); + int requestQty = client.getVarbitValue(Varbits.BANK_REQUESTEDQUANTITY); + // ~script2759 + String suffix; + switch (quantityType) + { + default: + suffix = "1"; + break; + case 1: + suffix = "5"; + break; + case 2: + suffix = "10"; + break; + case 3: + suffix = Integer.toString(Math.max(1, requestQty)); + break; + case 4: + suffix = "All"; + break; + } + c.setAction(0, "Withdraw-" + suffix); + if (quantityType != 0) + { + c.setAction(1, "Withdraw-1"); + } + c.setAction(2, "Withdraw-5"); + c.setAction(3, "Withdraw-10"); + if (requestQty > 0) + { + c.setAction(4, "Withdraw-" + requestQty); + } + c.setAction(5, "Withdraw-X"); + c.setAction(6, "Withdraw-All"); + c.setAction(7, "Withdraw-All-but-1"); + if (client.getVarbitValue(Varbits.BANK_LEAVEPLACEHOLDERS) == 0) + { + c.setAction(8, "Placeholder"); + } + c.setAction(9, "Examine"); + + c.setOpacity(0); + } + + c.setOnDragListener(ScriptID.BANKMAIN_DRAGSCROLL, ScriptEvent.WIDGET_ID, ScriptEvent.WIDGET_INDEX, ScriptEvent.MOUSE_X, ScriptEvent.MOUSE_Y, ComponentID.BANK_SCROLLBAR, 0); + c.setOnDragCompleteListener((JavaScriptCallback) ev -> {}); + } + else + { + // pad size to not leave a gap between items + c.setOriginalWidth(BANK_ITEM_WIDTH + BANK_ITEM_X_PADDING); + c.setOriginalHeight(BANK_ITEM_HEIGHT + BANK_ITEM_Y_PADDING); + c.clearActions(); + c.setItemId(-1); + c.setItemQuantity(0); + c.setOnDragListener((Object[]) null); + c.setOnDragCompleteListener((Object[]) null); + } + widgetItems.put(c, bankTabItem); + c.setHidden(false); + c.revalidate(); + } + + private int addPluginTabSection(Widget itemContainer, BankTabItems items, int totalSectionsHeight, List bankItemTexts) { int newHeight = totalSectionsHeight; @@ -421,96 +611,63 @@ private int addPluginTabSection(Widget itemContainer, BankTabItems items, List items, List itemIds, - int totalSectionsHeight, List bankItemTexts, - HashMap itemIDsAdded) + private int count(ItemContainer bank, int itemId) { - int totalItemsAdded = 0; - // Loop through all items in section - for (BankTabItem bankTabItem : items) + int count = bank.count(itemId); + if (count > 0) { - boolean foundItem = false; + return count; + } + return potionStorage.count(itemId); + } - // If item exists, move it to correct pos + append a quantity required string - if (!Collections.disjoint(itemIds, bankTabItem.getItemIDs())) - { - // Loop through all widgets to find there's a real item in bank - for (Widget widget : itemContainer.getDynamicChildren()) - { - if (!widget.isHidden() && widget.getOpacity() != 150 && (bankTabItem.getItemIDs().contains(widget.getItemId()))) - { - foundItem = true; + int currentWidgetToUse = 0; - Point point = placeItem(widget, totalItemsAdded, totalSectionsHeight); - widget.setItemQuantityMode(1); - widgetItems.put(widget, bankTabItem); + // Returns number of items added in partial section + private int createPartialSection(List items, int totalSectionsHeight, List bankItemTexts) + { + int totalItemsAdded = 0; - if (bankTabItem.getQuantity() > 0) - { - makeBankText(widget.getItemQuantity(), bankTabItem.getQuantity(), point.x, point.y, bankTabItem.getItemRequirement(), bankItemTexts); - } + ItemContainer bank = client.getItemContainer(InventoryID.BANK); + if (bank == null) return totalSectionsHeight; + Widget bankItemContainer = client.getWidget(ComponentID.BANK_ITEM_CONTAINER); + if (bankItemContainer == null) return totalSectionsHeight; - totalItemsAdded++; - itemIds.removeAll(Collections.singletonList(widget.getItemId())); - itemIDsAdded.put(widget.getItemId(), new BankWidget(widget)); - break; - } - } + for (BankTabItem item : items) + { + int itemId = item.getDisplayID(); + if (itemId == -1) + { + continue; } - if (!foundItem) + Widget c = bankItemContainer.getChild(currentWidgetToUse); + if (c == null) { - // calculate correct item position as if this was a normal tab - int adjXOffset = (totalItemsAdded % ITEMS_PER_ROW) * ITEM_HORIZONTAL_SPACING + ITEM_ROW_START; - int adjYOffset = totalSectionsHeight + (totalItemsAdded / ITEMS_PER_ROW) * ITEM_VERTICAL_SPACING; - - Widget fakeItemWidget; - // Have list of all real items + text. Do check to see if any of those items - // Match the ItemIDs - if (Collections.disjoint(itemIDsAdded.keySet(), bankTabItem.getItemIDs())) - { - fakeItemWidget = createMissingItem(itemContainer, bankTabItem, adjXOffset, adjYOffset); - itemIds.removeAll(bankTabItem.getItemIDs()); - } - else - { - List result = bankTabItem.getItemIDs().stream() - .distinct() - .filter(itemIDsAdded.keySet()::contains) - .collect(Collectors.toList()); - - BankWidget realItemWidget = itemIDsAdded.get((result.get(0))); - - fakeItemWidget = createDuplicateItem(itemContainer, bankTabItem, - realItemWidget.getItemQuantity(), adjXOffset, adjYOffset); - - fakeToRealItem.put(new BankWidget(fakeItemWidget), realItemWidget); - } - - if (bankTabItem.getQuantity() > 0) - { - makeBankText(fakeItemWidget.getItemQuantity(), bankTabItem.getQuantity(), adjXOffset, adjYOffset, bankTabItem.getItemRequirement(), bankItemTexts); - } - - widgetItems.put(fakeItemWidget, bankTabItem); - addedWidgets.add(fakeItemWidget); - - totalItemsAdded++; + return totalSectionsHeight; + } + drawItem(c, itemId, count(bank, itemId), item); + placeItem(c, totalItemsAdded, totalSectionsHeight); + // move item + if (item.getQuantity() > 0) + { + makeBankText(c.getItemQuantity(), item.getQuantity(), c.getOriginalX(), c.getOriginalY(), item.getItemRequirement(), bankItemTexts); } + + currentWidgetToUse++; + totalItemsAdded++; } int newHeight = totalSectionsHeight + (totalItemsAdded / ITEMS_PER_ROW) * ITEM_VERTICAL_SPACING; @@ -553,37 +710,6 @@ private void makeBankText(int currentQuantity, int goalQuantity, int baseX, int } } - private int addGeneralSection(Widget itemContainer, List items, int totalSectionsHeight) - { - int totalItemsAdded = 0; - - if (items.isEmpty()) - { - return totalSectionsHeight; - } - - for (Integer itemID : items) - { - for (Widget widget : itemContainer.getDynamicChildren()) - { - if (!widget.isHidden() && widget.getOpacity() != 150 && widget.getItemId() == itemID) - { - if (totalItemsAdded == 0) - { - totalSectionsHeight = addSectionHeader(itemContainer, "General", totalSectionsHeight); - } - - placeItem(widget, totalItemsAdded, totalSectionsHeight); - totalItemsAdded++; - } - } - } - int newHeight = totalSectionsHeight + (totalItemsAdded / ITEMS_PER_ROW) * ITEM_VERTICAL_SPACING; - newHeight = totalItemsAdded % ITEMS_PER_ROW != 0 ? newHeight + ITEM_VERTICAL_SPACING : newHeight; - - return newHeight; - } - private int addSubSectionHeader(Widget itemContainer, String title, int totalSectionsHeight) { addedWidgets.add(createText(itemContainer, title, new Color(228, 216, 162).getRGB(), (ITEMS_PER_ROW * ITEM_HORIZONTAL_SPACING) + ITEM_ROW_START @@ -594,14 +720,14 @@ private int addSubSectionHeader(Widget itemContainer, String title, int totalSec private int addSectionHeader(Widget itemContainer, String title, int totalSectionsHeight) { - addedWidgets.add(createGraphic(itemContainer, SpriteID.RESIZEABLE_MODE_SIDE_PANEL_BACKGROUND, ITEMS_PER_ROW * ITEM_HORIZONTAL_SPACING, LINE_HEIGHT, ITEM_ROW_START, totalSectionsHeight)); + addedWidgets.add(createGraphic(itemContainer, SpriteID.RESIZEABLE_MODE_SIDE_PANEL_BACKGROUND, ITEM_ROW_START, totalSectionsHeight)); addedWidgets.add(createText(itemContainer, title, new Color(228, 216, 162).getRGB(), (ITEMS_PER_ROW * ITEM_HORIZONTAL_SPACING) + ITEM_ROW_START , TEXT_HEIGHT, ITEM_ROW_START, totalSectionsHeight + LINE_VERTICAL_SPACING)); return totalSectionsHeight + LINE_VERTICAL_SPACING + TEXT_HEIGHT; } - private Point placeItem(Widget widget, int totalItemsAdded, int totalSectionsHeight) + private void placeItem(Widget widget, int totalItemsAdded, int totalSectionsHeight) { int adjYOffset = totalSectionsHeight + (totalItemsAdded / ITEMS_PER_ROW) * ITEM_VERTICAL_SPACING; int adjXOffset = (totalItemsAdded % ITEMS_PER_ROW) * ITEM_HORIZONTAL_SPACING + ITEM_ROW_START; @@ -618,136 +744,55 @@ private Point placeItem(Widget widget, int totalItemsAdded, int totalSectionsHei widget.revalidate(); } - return new Point(adjXOffset, adjYOffset); - } - - private Widget createGraphic(Widget container, int spriteId, int width, int height, int x, int y) - { - Widget widget = container.createChild(-1, WidgetType.GRAPHIC); - widget.setOriginalWidth(width); - widget.setOriginalHeight(height); - widget.setOriginalX(x); - widget.setOriginalY(y); - - widget.setSpriteId(spriteId); - - widget.revalidate(); - - return widget; + new Point(adjXOffset, adjYOffset); } - private Widget createMissingItem(Widget container, BankTabItem bankTabItem, int x, int y) + private void handleFakeItemClick(BankTabItem bankTabItem) { - Widget widget = container.createChild(-1, WidgetType.GRAPHIC); - widget.setItemQuantityMode(1); // quantity of 1 still shows number - widget.setOriginalWidth(ITEM_WIDTH); - widget.setOriginalHeight(ITEM_HEIGHT); - widget.setOriginalX(x); - widget.setOriginalY(y); - - List itemIDs = bankTabItem.getItemIDs(); - if (bankTabItem.getItemRequirement().getDisplayItemId() != null) - { - itemIDs = Collections.singletonList(bankTabItem.getItemRequirement().getDisplayItemId()); - } - - if (itemIDs.size() == 0) + String quantity = QuantityFormatter.formatNumber(bankTabItem.getQuantity()) + " x "; + if (bankTabItem.getQuantity() == -1) { - itemIDs.add(ItemID.CAKE_OF_GUIDANCE); + quantity = "some "; } + final ChatMessageBuilder message = new ChatMessageBuilder() + .append("You need ") + .append(ChatColorType.HIGHLIGHT) + .append(quantity) + .append(Text.removeTags(bankTabItem.getText())) + .append("."); - widget.setItemId(itemIDs.get(0)); - widget.setName("" + bankTabItem.getText() + ""); - if (bankTabItem.getDetails() != null) + if (bankTabItem.getDetails() != null && !bankTabItem.getDetails().isEmpty()) { - widget.setText(bankTabItem.getDetails()); + message.append(ChatColorType.NORMAL) + .append(" " + bankTabItem.getDetails() + "."); } - widget.setItemQuantity(0); - widget.setOpacity(150); - widget.setOnOpListener(ScriptID.NULL); - widget.setHasListener(true); - - addTabActions(widget); - - widget.revalidate(); - return widget; + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.ITEM_EXAMINE) + .runeLiteFormattedMessage(message.build()) + .build()); } - private Widget createDuplicateItem(Widget container, BankTabItem bankTabItem, int quantity, int x, int y) + private Widget createGraphic(Widget container, int spriteId, int x, int y) { + final int WIDTH = ITEMS_PER_ROW * ITEM_HORIZONTAL_SPACING; Widget widget = container.createChild(-1, WidgetType.GRAPHIC); - widget.setItemQuantityMode(1); // quantity of 1 still shows number - widget.setOriginalWidth(ITEM_WIDTH); - widget.setOriginalHeight(ITEM_HEIGHT); + widget.setOriginalWidth(WIDTH); + widget.setOriginalHeight(QuestBankTab.LINE_HEIGHT); widget.setOriginalX(x); widget.setOriginalY(y); - widget.setBorderType(1); - - List itemIDs = bankTabItem.getItemIDs(); - if (bankTabItem.getDisplayID() != null) - { - itemIDs = Collections.singletonList(bankTabItem.getDisplayID()); - } - widget.setItemId(itemIDs.get(0)); - widget.setName("" + bankTabItem.getText() + ""); - if (bankTabItem.getDetails() != null) - { - widget.setText(bankTabItem.getDetails()); - } - widget.setItemQuantity(quantity); - widget.setOnOpListener(ScriptID.NULL); - widget.setHasListener(true); + widget.setSpriteId(spriteId); widget.revalidate(); return widget; } - private void addTabActions(Widget w) - { - w.setAction(1, "Details"); - - w.setOnOpListener((JavaScriptCallback) this::handleFakeItemClick); - } - - private void handleFakeItemClick(ScriptEvent event) - { - Widget widget = event.getSource(); - if (widget.getItemId() != -1) - { - String name = widget.getName(); - BankTabItem item = widgetItems.get(widget); - - String quantity = QuantityFormatter.formatNumber(item.getQuantity()) + " x "; - if (item.getQuantity() == -1) - { - quantity = "some "; - } - final ChatMessageBuilder message = new ChatMessageBuilder() - .append("You need ") - .append(ChatColorType.HIGHLIGHT) - .append(quantity) - .append(Text.removeTags(name)) - .append("."); - - if (!widget.getText().isEmpty()) - { - message.append(ChatColorType.NORMAL) - .append(" " + widget.getText() + "."); - } - - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.ITEM_EXAMINE) - .runeLiteFormattedMessage(message.build()) - .build()); - } - } - private Widget createText(Widget container, String text, int color, int width, int height, int x, int y) { Widget widget = container.createChild(-1, WidgetType.TEXT); + widget.setOriginalWidth(width); widget.setOriginalHeight(height); widget.setOriginalX(x); @@ -763,11 +808,13 @@ private Widget createText(Widget container, String text, int color, int width, i return widget; } - private Widget createIcon(Widget container, int spriteID, int width, int height, int x, int y) + private Widget createIcon(Widget container, int spriteID, int x, int y) { + final int WIDTH = 10; + final int HEIGHT = 10; Widget widget = container.createChild(-1, WidgetType.GRAPHIC); - widget.setOriginalWidth(width); - widget.setOriginalHeight(height); + widget.setOriginalWidth(WIDTH); + widget.setOriginalHeight(HEIGHT); widget.setOriginalX(x); widget.setOriginalY(y); diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTabInterface.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTabInterface.java index 758b721c1d..23a031f112 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTabInterface.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTabInterface.java @@ -29,14 +29,7 @@ import javax.inject.Inject; import lombok.Getter; import lombok.Setter; -import net.runelite.api.Client; -import net.runelite.api.ScriptEvent; -import net.runelite.api.ScriptID; -import net.runelite.api.SoundEffectID; -import net.runelite.api.SpriteID; -import net.runelite.api.VarClientInt; -import net.runelite.api.VarClientStr; -import net.runelite.api.Varbits; +import net.runelite.api.*; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.ComponentID; import net.runelite.api.widgets.JavaScriptCallback; @@ -49,6 +42,8 @@ public class QuestBankTabInterface { private static final String VIEW_TAB = "View tab "; + private static final int BANKTAB_POTIONSTORE = 15; + @Setter @Getter private boolean questTabActive = false; @@ -135,8 +130,9 @@ public void handleClick(MenuOptionClicked event) // If click a base tab, close boolean clickedTabTag = menuOption.startsWith("View tab") && !event.getMenuTarget().equals("quest-helper"); + boolean clickPotionStorage = menuOption.startsWith("Potion store"); boolean clickedOtherTab = menuOption.equals("View all items") || menuOption.startsWith("View tag tab"); - if (questTabActive && (clickedTabTag || clickedOtherTab)) + if (questTabActive && (clickedTabTag || clickedOtherTab || clickPotionStorage)) { closeTab(); } @@ -221,6 +217,13 @@ private void activateTab() return; } + if (client.getVarbitValue(Varbits.CURRENT_BANK_TAB) == BANKTAB_POTIONSTORE) + { + // Opening a tag tab with the potion store open would leave the store open in the bankground, + // making deposits not work. Force close the potion store. + client.menuAction(-1, ComponentID.BANK_POTION_STORE, MenuAction.CC_OP, 1, -1, "Potion store", ""); + } + questBackgroundWidget.setSpriteId(SpriteID.UNKNOWN_BUTTON_SQUARE_SMALL_SELECTED); questBackgroundWidget.revalidate(); questTabActive = true; diff --git a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java index ca935ffcb3..c894a921a8 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java @@ -24,9 +24,7 @@ */ package com.questhelper.bank.banktab; -import com.questhelper.bank.QuestBank; import com.questhelper.QuestHelperPlugin; -import com.questhelper.managers.QuestContainerManager; import com.questhelper.panel.PanelDetails; import com.questhelper.requirements.item.ItemRequirement; import com.questhelper.requirements.item.ItemRequirements; @@ -38,8 +36,8 @@ import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; -import net.runelite.api.InventoryID; -import net.runelite.api.ItemContainer; + +import net.runelite.api.Client; @Singleton public class QuestHelperBankTagService @@ -48,28 +46,60 @@ public class QuestHelperBankTagService private QuestHelperPlugin plugin; @Inject - private QuestBank questBank; + private Client client; + + ArrayList taggedItems; + + ArrayList taggedItemsForBank; + + int lastTickUpdated = 0; + + int lastTickUpdatedForBank = 0; + + public ArrayList itemsToTagForBank() + { + if (client.getTickCount() <= lastTickUpdatedForBank) + { + return taggedItemsForBank; + } + + lastTickUpdatedForBank = client.getTickCount(); + + return getItemsFromTabs(false); + } public ArrayList itemsToTag() { - ArrayList sortedItems = getPluginBankTagItemsForSections(true); + if (client.getTickCount() <= lastTickUpdated) + { + return taggedItems; + } + + lastTickUpdated = client.getTickCount(); + + return getItemsFromTabs(true); + } + + private ArrayList getItemsFromTabs(boolean onlyGetMissingItems) + { + ArrayList sortedItems = getPluginBankTagItemsForSections(onlyGetMissingItems); if (sortedItems == null) { return null; } - ArrayList flattenedList = new ArrayList<>(); + taggedItemsForBank = new ArrayList<>(); sortedItems.stream() - .map(BankTabItems::getItems) - .flatMap(Collection::stream) - .map(BankTabItem::getItemIDs) - .flatMap(Collection::stream) - .filter(Objects::nonNull) // filter non-null just in case any Integer get in the list - .filter(id -> !flattenedList.contains(id)) - .forEach(flattenedList::add); - return flattenedList; + .map(BankTabItems::getItems) + .flatMap(Collection::stream) + .map(BankTabItem::getItemIDs) + .flatMap(Collection::stream) + .filter(Objects::nonNull) // filter non-null just in case any Integer get in the list + .filter(id -> !taggedItemsForBank.contains(id)) + .forEach(taggedItemsForBank::add); + return taggedItemsForBank; } public ArrayList getPluginBankTagItemsForSections(boolean onlyGetMissingItems) @@ -88,9 +118,7 @@ public ArrayList getPluginBankTagItemsForSections(boolean onlyGetM { recommendedItems = recommendedItems.stream() .filter(Objects::nonNull) - .filter(i -> (!onlyGetMissingItems - || !i.checkWithBank(plugin.getClient())) - && i.shouldDisplayText(plugin.getClient())) + .filter(i -> (!onlyGetMissingItems || !i.checkWithBank(plugin.getClient())) && i.shouldDisplayText(plugin.getClient())) .collect(Collectors.toList()); } @@ -178,11 +206,7 @@ private void getItemsFromRequirement(List pluginItems, ItemRequirem } else { - if (itemRequirement.getDisplayItemId() != null) - { - pluginItems.add(new BankTabItem(realItem)); - } - else if (!itemRequirement.getDisplayItemIds().contains(-1)) + if (itemRequirement.getDisplayItemId() != null || !itemRequirement.getDisplayItemIds().contains(-1)) { pluginItems.add(makeBankTabItem(realItem)); } @@ -192,20 +216,21 @@ else if (!itemRequirement.getDisplayItemIds().contains(-1)) private BankTabItem makeBankTabItem(ItemRequirement item) { List itemIds = item.getDisplayItemIds(); - - Integer displayId = itemIds.stream().filter(this::hasItemInBank).findFirst().orElse(itemIds.get(0)); + Integer displayId = itemIds.stream() + .filter(this::hasItemInBankOrPotionStorage) + .findFirst() + .orElse(item.getAllIds().stream() + .filter(this::hasItemInBankOrPotionStorage) + .findFirst() + .orElse(item.getAllIds().get(0)) + ); return new BankTabItem(item, displayId); } - public boolean hasItemInBank(int itemID) + public boolean hasItemInBankOrPotionStorage(int itemID) { - ItemContainer bankContainer = plugin.getClient().getItemContainer(InventoryID.BANK); - if (bankContainer == null) - { - return false; - } - - return bankContainer.contains(itemID); + ItemRequirement tmpReq = new ItemRequirement("tmp", itemID); + return tmpReq.checkWithBank(client); } } diff --git a/src/main/java/com/questhelper/managers/QuestBankManager.java b/src/main/java/com/questhelper/managers/QuestBankManager.java index cc306899a2..0b935efba5 100644 --- a/src/main/java/com/questhelper/managers/QuestBankManager.java +++ b/src/main/java/com/questhelper/managers/QuestBankManager.java @@ -58,12 +58,12 @@ public void startUp(Injector injector, EventBus eventBus) { questBankTab.startUp(); injector.injectMembers(questBankTab); - eventBus.register(questBankTab); + questBankTab.register(eventBus); } public void shutDown(EventBus eventBus) { - eventBus.unregister(questBankTab); + questBankTab.unregister(eventBus); questBankTab.shutDown(); } diff --git a/src/main/java/com/questhelper/managers/QuestContainerManager.java b/src/main/java/com/questhelper/managers/QuestContainerManager.java index c9141907fe..bffc2b8049 100644 --- a/src/main/java/com/questhelper/managers/QuestContainerManager.java +++ b/src/main/java/com/questhelper/managers/QuestContainerManager.java @@ -37,4 +37,7 @@ public class QuestContainerManager @Getter private final static ItemAndLastUpdated bankData = new ItemAndLastUpdated(TrackedContainers.BANK); + + @Getter + private final static ItemAndLastUpdated potionData = new ItemAndLastUpdated(TrackedContainers.POTION_STORAGE); } diff --git a/src/main/java/com/questhelper/requirements/item/ItemRequirement.java b/src/main/java/com/questhelper/requirements/item/ItemRequirement.java index bee8379194..2a761763de 100644 --- a/src/main/java/com/questhelper/requirements/item/ItemRequirement.java +++ b/src/main/java/com/questhelper/requirements/item/ItemRequirement.java @@ -110,6 +110,7 @@ public class ItemRequirement extends AbstractRequirement protected Requirement additionalOptions; + Map knownContainerStates = new HashMap<>(); { for (TrackedContainers value : TrackedContainers.values()) @@ -389,10 +390,8 @@ public String getDisplayText() return text.toString(); } - // IDEA: Have a central event which lets you know diff on inventory public void setAdditionalOptions(Requirement additionalOptions) { - // TODO: Need to register / unregister through centralised ActiveRequirementsManager this.additionalOptions = additionalOptions; } @@ -540,7 +539,8 @@ private boolean checkContainersOnPlayer(Client client) public boolean checkWithBank(Client client) { - return checkContainers(client, QuestContainerManager.getEquippedData(), QuestContainerManager.getInventoryData(), QuestContainerManager.getBankData()); + return checkContainers(client, QuestContainerManager.getEquippedData(), QuestContainerManager.getInventoryData(), QuestContainerManager.getBankData() + , QuestContainerManager.getPotionData()); } public Color getColorConsideringBank(Client client, QuestHelperConfig config) @@ -559,6 +559,10 @@ else if (this.checkContainersOnPlayer(client)) { color = Color.WHITE; } + if (color == config.failColour() && this.checkContainers(client, QuestContainerManager.getPotionData())) + { + color = Color.CYAN; + } return color; } @@ -607,7 +611,11 @@ private ItemAndLastUpdated[] containersToCheckDefault() containers.add(QuestContainerManager.getEquippedData()); if (!equip) containers.add(QuestContainerManager.getInventoryData()); - if (shouldCheckBank) containers.add(QuestContainerManager.getBankData()); + if (shouldCheckBank) + { + containers.add(QuestContainerManager.getBankData()); + containers.add(QuestContainerManager.getPotionData()); + } return containers.toArray(new ItemAndLastUpdated[0]); } diff --git a/src/main/java/com/questhelper/requirements/item/TrackedContainers.java b/src/main/java/com/questhelper/requirements/item/TrackedContainers.java index a952a90263..fcea25cf2b 100644 --- a/src/main/java/com/questhelper/requirements/item/TrackedContainers.java +++ b/src/main/java/com/questhelper/requirements/item/TrackedContainers.java @@ -29,5 +29,6 @@ public enum TrackedContainers EQUIPPED, INVENTORY, BANK, + POTION_STORAGE, UNDEFINED }