From f6f66cddaa398fe04572f088a265aadc90a88636 Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Tue, 26 Nov 2024 16:33:42 +0000 Subject: [PATCH 01/10] feat: Added Potion Storage as container --- .../com/questhelper/QuestHelperPlugin.java | 6 + .../bank/banktab/PotionStorage.java | 315 ++++++++++++++++++ .../managers/QuestBankManager.java | 4 +- .../managers/QuestContainerManager.java | 3 + .../requirements/item/ItemRequirement.java | 13 +- .../requirements/item/TrackedContainers.java | 1 + 6 files changed, 338 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/questhelper/bank/banktab/PotionStorage.java diff --git a/src/main/java/com/questhelper/QuestHelperPlugin.java b/src/main/java/com/questhelper/QuestHelperPlugin.java index ff19fc6697..a738c54ce4 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); 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..2479cac349 --- /dev/null +++ b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java @@ -0,0 +1,315 @@ +/* + * 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 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.MenuOptionClicked; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WidgetClosed; +import net.runelite.api.widgets.ComponentID; +import net.runelite.api.widgets.InterfaceID; +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 BANKTAB_POTIONSTORE = 15; + static final int COMPONENTS_PER_POTION = 5; + + private final Client client; + private final ItemManager itemManager; + private final BankSearch bankSearch; + + private Potion[] potions; + 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 (potionStoreVars != null && potionStoreVars.contains(varbitChanged.getVarpId())) + { + cachePotions = true; + layout = true; // trigger a bank rebuild as the qty has changed + } + } + + @Subscribe + public void onWidgetClosed(WidgetClosed event) + { + if (event.getGroupId() == InterfaceID.BANK && event.isUnload()) + { + log.debug("Invalidating potions"); + potions = null; + } + } + + 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()]; + 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; + + if (log.isDebugEnabled()) + { +// log.debug("Potion store has {} doses of {}", p.doses, itemManager.getItemComposition(p.itemId).getName()); + } + } + + ++potionsIdx; + } + } + + for (Potion potion : potions) + { + if (potion != null) + { + String name = itemManager.getItemComposition(potion.itemId).getName(); + if (name.contains("Hunter")) + { +// System.out.println(itemManager.getItemComposition(potion.itemId).getName()); +// System.out.println(potion.doses); + } + } + } +// System.out.println(Arrays.toString(potions)); + } + + public Item[] getItems() + { + if (potions == null) + { + return new Item[0]; + } + + List items = new ArrayList<>(); + + for (Potion potion : potions) + { + var potionEnum = potion.potionEnum; + // TODO: An issue due to potentially wanting a specific potion, or to default to full potion + int potionItemId = potionEnum.getIntValue(potion.withdrawDoses); + int quantity = potion.doses / potion.withdrawDoses; + items.add(new Item(potionItemId, quantity)); + } + + return items.toArray(new Item[0]); + } + + int matches(Set bank, int itemId) + { + if (potions == null) + { + return -1; + } + + for (Potion potion : potions) + { + if (potion == null) + { + continue; + } + + var potionEnum = potion.potionEnum; + int potionItemId1 = potionEnum.getIntValue(1); + int potionItemId2 = potionEnum.getIntValue(2); + int potionItemId3 = potionEnum.getIntValue(3); + int potionItemId4 = potionEnum.getIntValue(4); + + if (potionItemId1 == itemId || potionItemId2 == itemId || potionItemId3 == itemId || potionItemId4 == itemId) + { + int potionStoreItem = potionEnum.getIntValue(potion.withdrawDoses); + + if (log.isDebugEnabled()) + { + log.debug("Item {} matches a potion from potion store {}", itemId, itemManager.getItemComposition(potionStoreItem).getName()); + } + + return potionStoreItem; + } + } + + return -1; + } + + int count(int itemId) + { + if (potions == null) + { + return 0; + } + + for (Potion potion : potions) + { + if (potion != null && potion.itemId == itemId) + { + return potion.doses / potion.withdrawDoses; + } + } + return 0; + } + + int find(int itemId) + { + if (potions == null) + { + return -1; + } + + int potionIdx = 0; + for (Potion potion : potions) + { + ++potionIdx; + if (potion != null && potion.itemId == itemId) + { + return potionIdx - 1; + } + } + return -1; + } + + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) + { + // Update widget index of the menu so withdraws work in laid out tabs. + if (event.getParam1() == ComponentID.BANK_ITEM_CONTAINER && questBankTabInterface.isQuestTabActive()) + { + MenuEntry menu = event.getMenuEntry(); + 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 = find(w.getItemId()); + if (idx > -1) + { + prepareWidgets(); + menu.setParam1(ComponentID.BANK_POTIONSTORE_CONTENT); + menu.setParam0(idx * COMPONENTS_PER_POTION); + } + } + } + } + + 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/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..4cadb51558 100644 --- a/src/main/java/com/questhelper/requirements/item/ItemRequirement.java +++ b/src/main/java/com/questhelper/requirements/item/ItemRequirement.java @@ -540,7 +540,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 +560,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 +612,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 } From bd502ebad617dd81ff1325db07ddfe993f76274c Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Tue, 26 Nov 2024 17:12:43 +0000 Subject: [PATCH 02/10] feat: Filter non helper items on bank filter --- .../bank/banktab/QuestBankTab.java | 80 ++++++++++++++----- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index 7211cd17fc..dc0824db74 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -33,23 +33,13 @@ 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 lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; import net.runelite.api.events.ClientTick; import net.runelite.api.events.GrandExchangeSearched; import net.runelite.api.events.MenuOptionClicked; @@ -67,12 +57,18 @@ 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.plugins.banktags.BankTag; +import net.runelite.client.plugins.banktags.tabs.Layout; import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.Text; +import static net.runelite.client.plugins.banktags.BankTagsPlugin.*; + @Singleton +@Slf4j public class QuestBankTab { private static final int ITEMS_PER_ROW = 8; @@ -115,6 +111,12 @@ 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<>(); @@ -142,6 +144,19 @@ public void shutDown() } } + 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() { questBankTabInterface.refreshTab(); @@ -177,16 +192,13 @@ 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. if (questBankTabInterface.isQuestTabActive()) { Widget bankTitle = client.getWidget(ComponentID.BANK_TITLE_BAR); @@ -201,6 +213,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 +239,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 From 17bbdacee3a368c92def6777647c5d4db60931d3 Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Tue, 26 Nov 2024 17:13:09 +0000 Subject: [PATCH 03/10] feat: Potion Storage works with sidebar --- .../com/questhelper/QuestHelperPlugin.java | 1 + .../bank/banktab/PotionStorage.java | 41 +++---------- .../banktab/QuestHelperBankTagService.java | 58 ++++++++++++++++--- 3 files changed, 59 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/questhelper/QuestHelperPlugin.java b/src/main/java/com/questhelper/QuestHelperPlugin.java index a738c54ce4..bcf4d8b4e2 100644 --- a/src/main/java/com/questhelper/QuestHelperPlugin.java +++ b/src/main/java/com/questhelper/QuestHelperPlugin.java @@ -289,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/PotionStorage.java b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java index 2479cac349..02f407c367 100644 --- a/src/main/java/com/questhelper/bank/banktab/PotionStorage.java +++ b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java @@ -28,6 +28,7 @@ import javax.inject.Inject; import javax.inject.Singleton; +import com.questhelper.managers.QuestContainerManager; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -35,9 +36,7 @@ import net.runelite.api.events.ClientTick; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; -import net.runelite.api.events.WidgetClosed; import net.runelite.api.widgets.ComponentID; -import net.runelite.api.widgets.InterfaceID; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetType; import net.runelite.client.eventbus.Subscribe; @@ -57,7 +56,7 @@ class Potion @Slf4j public class PotionStorage { - static final int BANKTAB_POTIONSTORE = 15; + static final int TOTAL_POTIONS_VARBIT = 4286; static final int COMPONENTS_PER_POTION = 5; private final Client client; @@ -65,7 +64,7 @@ public class PotionStorage private final BankSearch bankSearch; private Potion[] potions; - boolean cachePotions; + public boolean cachePotions; private boolean layout; private Set potionStoreVars; @@ -77,7 +76,7 @@ public void onClientTick(ClientTick event) { if (cachePotions) { -// log.debug("Rebuilding potions"); + log.debug("Rebuilding potions"); cachePotions = false; rebuildPotions(); @@ -106,23 +105,13 @@ public void onClientTick(ClientTick event) @Subscribe public void onVarbitChanged(VarbitChanged varbitChanged) { - if (potionStoreVars != null && potionStoreVars.contains(varbitChanged.getVarpId())) + 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 } } - @Subscribe - public void onWidgetClosed(WidgetClosed event) - { - if (event.getGroupId() == InterfaceID.BANK && event.isUnload()) - { - log.debug("Invalidating potions"); - potions = null; - } - } - private void rebuildPotions() { var potionStorePotions = client.getEnum(EnumID.POTIONSTORE_POTIONS); @@ -147,30 +136,13 @@ private void rebuildPotions() p.doses = doses; p.withdrawDoses = withdrawDoses; potions[potionsIdx] = p; - - if (log.isDebugEnabled()) - { -// log.debug("Potion store has {} doses of {}", p.doses, itemManager.getItemComposition(p.itemId).getName()); - } } ++potionsIdx; } } - for (Potion potion : potions) - { - if (potion != null) - { - String name = itemManager.getItemComposition(potion.itemId).getName(); - if (name.contains("Hunter")) - { -// System.out.println(itemManager.getItemComposition(potion.itemId).getName()); -// System.out.println(potion.doses); - } - } - } -// System.out.println(Arrays.toString(potions)); + QuestContainerManager.getPotionData().update(client.getTickCount(), getItems()); } public Item[] getItems() @@ -184,6 +156,7 @@ public Item[] getItems() for (Potion potion : potions) { + if (potion == null) continue; var potionEnum = potion.potionEnum; // TODO: An issue due to potentially wanting a specific potion, or to default to full potion int potionItemId = potionEnum.getIntValue(potion.withdrawDoses); diff --git a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java index ca935ffcb3..fa8a0380a8 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,6 +36,8 @@ import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; + +import net.runelite.api.Client; import net.runelite.api.InventoryID; import net.runelite.api.ItemContainer; @@ -48,10 +48,54 @@ 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(); + + ArrayList sortedItems = getPluginBankTagItemsForSections(false); + + if (sortedItems == null) + { + return null; + } + + 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 -> !taggedItemsForBank.contains(id)) + .forEach(taggedItemsForBank::add); + return taggedItemsForBank; + } public ArrayList itemsToTag() { + if (client.getTickCount() <= lastTickUpdated) + { + return taggedItems; + } + + lastTickUpdated = client.getTickCount(); + ArrayList sortedItems = getPluginBankTagItemsForSections(true); if (sortedItems == null) @@ -59,7 +103,7 @@ public ArrayList itemsToTag() return null; } - ArrayList flattenedList = new ArrayList<>(); + taggedItems = new ArrayList<>(); sortedItems.stream() .map(BankTabItems::getItems) @@ -67,9 +111,9 @@ public ArrayList itemsToTag() .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; + .filter(id -> !taggedItems.contains(id)) + .forEach(taggedItems::add); + return taggedItems; } public ArrayList getPluginBankTagItemsForSections(boolean onlyGetMissingItems) From 43542e90f7027924035db3512aae3559fda64bbb Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Wed, 27 Nov 2024 00:47:56 +0000 Subject: [PATCH 04/10] feat: Potion storage works for bank Also adds performance improvements by making all items rather than finding items in the bank, like the core tags Layouts now do. Additionally, only renders the quest items and not the entire bank to further speed things up. --- .../questhelper/bank/banktab/BankTabItem.java | 2 +- .../bank/banktab/PotionStorage.java | 67 +-- .../bank/banktab/QuestBankTab.java | 539 +++++++++--------- .../bank/banktab/QuestBankTabInterface.java | 21 +- .../banktab/QuestHelperBankTagService.java | 19 +- .../requirements/item/ItemRequirement.java | 3 +- 6 files changed, 286 insertions(+), 365 deletions(-) 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 index 02f407c367..814580dbab 100644 --- a/src/main/java/com/questhelper/bank/banktab/PotionStorage.java +++ b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java @@ -167,42 +167,6 @@ public Item[] getItems() return items.toArray(new Item[0]); } - int matches(Set bank, int itemId) - { - if (potions == null) - { - return -1; - } - - for (Potion potion : potions) - { - if (potion == null) - { - continue; - } - - var potionEnum = potion.potionEnum; - int potionItemId1 = potionEnum.getIntValue(1); - int potionItemId2 = potionEnum.getIntValue(2); - int potionItemId3 = potionEnum.getIntValue(3); - int potionItemId4 = potionEnum.getIntValue(4); - - if (potionItemId1 == itemId || potionItemId2 == itemId || potionItemId3 == itemId || potionItemId4 == itemId) - { - int potionStoreItem = potionEnum.getIntValue(potion.withdrawDoses); - - if (log.isDebugEnabled()) - { - log.debug("Item {} matches a potion from potion store {}", itemId, itemManager.getItemComposition(potionStoreItem).getName()); - } - - return potionStoreItem; - } - } - - return -1; - } - int count(int itemId) { if (potions == null) @@ -239,36 +203,7 @@ int find(int itemId) return -1; } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - // Update widget index of the menu so withdraws work in laid out tabs. - if (event.getParam1() == ComponentID.BANK_ITEM_CONTAINER && questBankTabInterface.isQuestTabActive()) - { - MenuEntry menu = event.getMenuEntry(); - 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 = find(w.getItemId()); - if (idx > -1) - { - prepareWidgets(); - menu.setParam1(ComponentID.BANK_POTIONSTORE_CONTENT); - menu.setParam0(idx * COMPONENTS_PER_POTION); - } - } - } - } - - void prepareWidgets() + 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. diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index dc0824db74..402d7903da 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -40,18 +40,13 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.*; -import net.runelite.api.events.ClientTick; 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; @@ -60,11 +55,10 @@ import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.banktags.BankTag; -import net.runelite.client.plugins.banktags.tabs.Layout; import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.Text; +import static com.questhelper.bank.banktab.PotionStorage.COMPONENTS_PER_POTION; import static net.runelite.client.plugins.banktags.BankTagsPlugin.*; @Singleton @@ -78,8 +72,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; @@ -87,7 +79,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 @@ -119,8 +110,6 @@ public class QuestBankTab private final HashMap widgetItems = new HashMap<>(); - private final HashMap fakeToRealItem = new HashMap<>(); - public void startUp() { if (questHelper.getSelectedQuest() != null) @@ -134,16 +123,8 @@ 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); @@ -199,6 +180,7 @@ public void onScriptPreFired(ScriptPreFired event) int scriptId = event.getScriptId(); if (scriptId == ScriptID.BANKMAIN_FINISHBUILDING) { + resetWidgets(); if (questBankTabInterface.isQuestTabActive()) { Widget bankTitle = client.getWidget(ComponentID.BANK_TITLE_BAR); @@ -276,31 +258,83 @@ 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 > -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 (addedWidgets.isEmpty()) return; + Widget parent = addedWidgets.get(0).getParent(); + if (parent == null) return; + + parent.setChildren(Arrays.copyOf(parent.getChildren(), 1248)); + parent.revalidate(); + + addedWidgets.clear(); } @Subscribe @@ -320,15 +354,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; } @@ -349,16 +374,7 @@ public void onScriptPostFired(ScriptPostFired event) return; } - if (!addedWidgets.isEmpty()) - { - - for (Widget addedWidget : addedWidgets) - { - addedWidget.setHidden(true); - } - addedWidgets.clear(); - } - fakeToRealItem.clear(); + removeAddedWidgets(); Widget[] containerChildren = itemContainer.getDynamicChildren(); @@ -379,6 +395,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) { @@ -397,11 +419,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 @@ -421,18 +442,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(); @@ -447,9 +465,123 @@ 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.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; @@ -465,96 +597,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; @@ -597,37 +696,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 @@ -638,14 +706,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; @@ -662,136 +730,55 @@ private Point placeItem(Widget widget, int totalItemsAdded, int totalSectionsHei widget.revalidate(); } - return new Point(adjXOffset, adjYOffset); + new Point(adjXOffset, adjYOffset); } - private Widget createGraphic(Widget container, int spriteId, int width, int height, int x, int y) + private void handleFakeItemClick(BankTabItem bankTabItem) { - 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; - } - - private Widget createMissingItem(Widget container, BankTabItem bankTabItem, int x, int y) - { - 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) + String quantity = QuantityFormatter.formatNumber(bankTabItem.getQuantity()) + " x "; + if (bankTabItem.getQuantity() == -1) { - itemIDs = Collections.singletonList(bankTabItem.getItemRequirement().getDisplayItemId()); - } - - if (itemIDs.size() == 0) - { - 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.getText().isEmpty()) { - widget.setText(bankTabItem.getDetails()); + message.append(ChatColorType.NORMAL) + .append(" " + bankTabItem.getText() + "."); } - 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); @@ -807,11 +794,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 fa8a0380a8..ceb06141bf 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java @@ -25,6 +25,7 @@ package com.questhelper.bank.banktab; 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; @@ -40,6 +41,7 @@ import net.runelite.api.Client; import net.runelite.api.InventoryID; import net.runelite.api.ItemContainer; +import net.runelite.api.ItemID; @Singleton public class QuestHelperBankTagService @@ -132,9 +134,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()); } @@ -237,19 +237,14 @@ 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(itemIds.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/requirements/item/ItemRequirement.java b/src/main/java/com/questhelper/requirements/item/ItemRequirement.java index 4cadb51558..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; } From a8b5b319679c8f537ce2b6ceaab6ef98717b4c18 Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Wed, 27 Nov 2024 01:09:39 +0000 Subject: [PATCH 05/10] fix: Added more dynamic bank trimming --- .../com/questhelper/bank/banktab/QuestBankTab.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index 402d7903da..45e21b08f5 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -110,6 +110,8 @@ public class QuestBankTab private final HashMap widgetItems = new HashMap<>(); + private int originalContainerChildren = -1; + public void startUp() { if (questHelper.getSelectedQuest() != null) @@ -327,11 +329,13 @@ private void resetWidgets() private void removeAddedWidgets() { + if (originalContainerChildren == -1) return; + if (addedWidgets.isEmpty()) return; Widget parent = addedWidgets.get(0).getParent(); if (parent == null) return; - parent.setChildren(Arrays.copyOf(parent.getChildren(), 1248)); + parent.setChildren(Arrays.copyOf(parent.getChildren(), originalContainerChildren)); parent.revalidate(); addedWidgets.clear(); @@ -363,6 +367,8 @@ public void onScriptPostFired(ScriptPostFired event) return; } + removeAddedWidgets(); + if (!questBankTabInterface.isQuestTabActive()) { return; @@ -373,8 +379,8 @@ public void onScriptPostFired(ScriptPostFired event) { return; } - - removeAddedWidgets(); + Widget[] children = itemContainer.getChildren(); + if (children != null && originalContainerChildren == -1) originalContainerChildren = children.length; Widget[] containerChildren = itemContainer.getDynamicChildren(); From 16fee0192069b56113ad617df29ef95d475d2554 Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Wed, 27 Nov 2024 01:13:39 +0000 Subject: [PATCH 06/10] fix: Add null check for quest bank trimming --- src/main/java/com/questhelper/bank/banktab/QuestBankTab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index 45e21b08f5..a34631cf1b 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -334,7 +334,7 @@ private void removeAddedWidgets() 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(); From 36f2e92cd98ac80ba434383fb035d7bf04ebabc2 Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Wed, 27 Nov 2024 09:43:05 +0000 Subject: [PATCH 07/10] fix: Remove duplicate code in QuestHelperBankTagService --- .../banktab/QuestHelperBankTagService.java | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java index ceb06141bf..ebce512458 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java @@ -25,7 +25,6 @@ package com.questhelper.bank.banktab; 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; @@ -39,9 +38,6 @@ import javax.inject.Singleton; import net.runelite.api.Client; -import net.runelite.api.InventoryID; -import net.runelite.api.ItemContainer; -import net.runelite.api.ItemID; @Singleton public class QuestHelperBankTagService @@ -69,24 +65,7 @@ public ArrayList itemsToTagForBank() lastTickUpdatedForBank = client.getTickCount(); - ArrayList sortedItems = getPluginBankTagItemsForSections(false); - - if (sortedItems == null) - { - return null; - } - - 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 -> !taggedItemsForBank.contains(id)) - .forEach(taggedItemsForBank::add); - return taggedItemsForBank; + return getItemsFromTabs(false); } public ArrayList itemsToTag() @@ -98,24 +77,29 @@ public ArrayList itemsToTag() lastTickUpdated = client.getTickCount(); - ArrayList sortedItems = getPluginBankTagItemsForSections(true); + return getItemsFromTabs(true); + } + + private ArrayList getItemsFromTabs(boolean onlyGetMissingItems) + { + ArrayList sortedItems = getPluginBankTagItemsForSections(onlyGetMissingItems); if (sortedItems == null) { return null; } - taggedItems = 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 -> !taggedItems.contains(id)) - .forEach(taggedItems::add); - return taggedItems; + .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) From 8b292a30b1f626f53d24322229138954a35e10bd Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Wed, 27 Nov 2024 09:58:35 +0000 Subject: [PATCH 08/10] fix: Use right bank item name and details --- .../java/com/questhelper/bank/banktab/QuestBankTab.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index a34631cf1b..1d376e0faa 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -502,7 +502,7 @@ private void drawItem(Widget c, int item, int qty, BankTabItem bankTabItem) // Effectively avoid dragging c.setDragDeadTime(1000); - c.setName("" + def.getName() + ""); + c.setName("" + bankTabItem.getText() + ""); c.clearActions(); // Jagex Placeholder @@ -753,10 +753,10 @@ private void handleFakeItemClick(BankTabItem bankTabItem) .append(Text.removeTags(bankTabItem.getText())) .append("."); - if (!bankTabItem.getText().isEmpty()) + if (!bankTabItem.getDetails().isEmpty()) { message.append(ChatColorType.NORMAL) - .append(" " + bankTabItem.getText() + "."); + .append(" " + bankTabItem.getDetails() + "."); } chatMessageManager.queue(QueuedMessage.builder() From 5bd1a71c02195dcd8793725f1424fd0269c9b7a0 Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Wed, 27 Nov 2024 10:30:12 +0000 Subject: [PATCH 09/10] fix: Apply item finding to all items for bank --- .../questhelper/bank/banktab/QuestBankTab.java | 5 +++-- .../bank/banktab/QuestHelperBankTagService.java | 16 +++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index 1d376e0faa..1749d74806 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -502,7 +502,7 @@ private void drawItem(Widget c, int item, int qty, BankTabItem bankTabItem) // Effectively avoid dragging c.setDragDeadTime(1000); - c.setName("" + bankTabItem.getText() + ""); + c.setName("" + def.getName() + ""); c.clearActions(); // Jagex Placeholder @@ -519,6 +519,7 @@ else if (qty == 0) c.setOpacity(120); c.setItemQuantity(0); c.setItemQuantityMode(1); + c.setText("" + bankTabItem.getText() + ""); c.setAction(1, "Details"); } else @@ -753,7 +754,7 @@ private void handleFakeItemClick(BankTabItem bankTabItem) .append(Text.removeTags(bankTabItem.getText())) .append("."); - if (!bankTabItem.getDetails().isEmpty()) + if (bankTabItem.getDetails() != null && !bankTabItem.getDetails().isEmpty()) { message.append(ChatColorType.NORMAL) .append(" " + bankTabItem.getDetails() + "."); diff --git a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java index ebce512458..c894a921a8 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestHelperBankTagService.java @@ -206,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)); } @@ -220,8 +216,14 @@ else if (!itemRequirement.getDisplayItemIds().contains(-1)) private BankTabItem makeBankTabItem(ItemRequirement item) { List itemIds = item.getDisplayItemIds(); - - Integer displayId = itemIds.stream().filter(this::hasItemInBankOrPotionStorage).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); } From 316b6bf4fe1c8c06abab0ac68a0ace05ba0b63db Mon Sep 17 00:00:00 2001 From: Zoinkwiz Date: Wed, 27 Nov 2024 10:47:09 +0000 Subject: [PATCH 10/10] feat: Added vial support for potion storage --- .../bank/banktab/PotionStorage.java | 38 +++++++++++++++---- .../bank/banktab/QuestBankTab.java | 9 ++++- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/questhelper/bank/banktab/PotionStorage.java b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java index 814580dbab..de9f052061 100644 --- a/src/main/java/com/questhelper/bank/banktab/PotionStorage.java +++ b/src/main/java/com/questhelper/bank/banktab/PotionStorage.java @@ -34,7 +34,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.*; import net.runelite.api.events.ClientTick; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.widgets.ComponentID; import net.runelite.api.widgets.Widget; @@ -57,6 +56,7 @@ class Potion 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; @@ -116,7 +116,7 @@ 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()]; + potions = new Potion[potionStorePotions.size() + potionStoreUnfinishedPotions.size() + 1]; int potionsIdx = 0; for (EnumComposition e : new EnumComposition[]{potionStorePotions, potionStoreUnfinishedPotions}) { @@ -142,6 +142,14 @@ private void rebuildPotions() } } + // 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()); } @@ -158,10 +166,16 @@ public Item[] getItems() { if (potion == null) continue; var potionEnum = potion.potionEnum; - // TODO: An issue due to potentially wanting a specific potion, or to default to full potion - int potionItemId = potionEnum.getIntValue(potion.withdrawDoses); - int quantity = potion.doses / potion.withdrawDoses; - items.add(new Item(potionItemId, quantity)); + 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]); @@ -178,7 +192,12 @@ int count(int itemId) { if (potion != null && potion.itemId == itemId) { - return potion.doses / potion.withdrawDoses; + if (potion.withdrawDoses != 0) + { + return potion.doses / potion.withdrawDoses; + } + + return potion.doses; } } return 0; @@ -191,6 +210,11 @@ int find(int itemId) return -1; } + if (itemId == ItemID.VIAL) + { + return VIAL_IDX; + } + int potionIdx = 0; for (Potion potion : potions) { diff --git a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java index 1749d74806..20b1564f14 100644 --- a/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java +++ b/src/main/java/com/questhelper/bank/banktab/QuestBankTab.java @@ -59,6 +59,7 @@ 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 @@ -293,7 +294,13 @@ public void onMenuOptionClicked(MenuOptionClicked event) } idx = potionStorage.find(w.getItemId()); - if (idx > -1) + 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);