diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync index 98091843fe1..8c8874920d4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync @@ -8,16 +8,22 @@ # Use the quest-helper update scripts to manage synchronization. # Current sync position - this is the last external commit that has been integrated -5539626281a502ba8c44fe59b8b57bce32fe4f16 +ae1f441248b9742c1eaa667b18052785eb6ed058 # Sync metadata (for script reference) -# External repo HEAD at last check: 5539626281a502ba8c44fe59b8b57bce32fe4f16 -# Last sync date: 2025-08-29 -# Sync method: automated script with manual package transformation -# Integration branch: quest-helper-update-20250829_063754 -# Local commit: cb416ef02a (quest-helper: polish Enakhras Lament) +# External repo HEAD at last check: ae1f441248b9742c1eaa667b18052785eb6ed058 +# Last sync date: 2026-07-19 +# Sync method: upstream source mirror with manual package transformation and Microbot hook preservation +# Integration branch: local workspace +# Local commit: pending # Sync history log: +# 2026-07-19 - Complete sync to upstream ae1f4412 (Quest Helper 4.16.1 source) +# - Mirrored upstream src/main/java and src/main/resources into the Microbot package +# - Preserved Microbot QuestScript, custom quest logic, config toggles, and agent-server start hook +# - Package transformation: com.questhelper -> net.runelite.client.plugins.microbot.questhelper +# - Status: SUCCESS +# # 2025-08-29 07:14:46 - Applied commit 55396262 (Polish enahkras lament #2294) # - Enhanced EnakhrasLament.java with better code organization # - Fixed Shadow Room brazier puzzle sequence and locations @@ -43,9 +49,9 @@ # - Status: INITIALIZED # Integration status -# Current external version: 4.10.0+ +# Current external version: 4.16.1 # Integration health: HEALTHY -# Last validation: 2025-08-29 +# Last validation: 2026-07-19 # Compilation status: SUCCESS # Package transformation: COMPLETE -# Sync file location: CORRECT (moved from project root) \ No newline at end of file +# Sync file location: CORRECT (moved from project root) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java index 78c6ae488c1..22715fc5bb9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java @@ -46,6 +46,8 @@ public interface QuestHelperConfig extends Config String QUEST_HELPER_GROUP = "questhelper"; String QUEST_BACKGROUND_GROUP = "questhelpervars"; String QUEST_HELPER_SIDEBAR_ORDER_KEY_START = "quest-sidebar-order-"; + /** Per-helper persisted manual step skips (JSON map of stable slot id to true). */ + String QUEST_HELPER_MANUAL_SKIPS_KEY_PREFIX = "manual-step-skips-"; enum QuestOrdering implements Comparator { @@ -237,32 +239,33 @@ enum InventoryItemHighlightStyle } @ConfigSection( - position = 0, - name = "Microbot", - description = "Microbot Options", - closedByDefault = false + position = 0, + name = "Microbot", + description = "Microbot Options", + closedByDefault = false ) String microbotSection = "microbotSection"; - @ConfigItem( - keyName = "TurnOn", - name = "Enable QuestHelper", - description = "Enable the quest helper that will automatically help with quests.", - section = microbotSection + keyName = "TurnOn", + name = "Enable QuestHelper", + description = "Enable the quest helper that will automatically help with quests.", + section = microbotSection ) - default boolean startStopQuestHelper() { + default boolean startStopQuestHelper() + { return true; } @ConfigItem( - keyName = "obtainMissingItems", - name = "Obtain Missing Items", - description = "Controls whether the quest helper automatically obtains missing items from the bank and Grand Exchange. 'Ask' will prompt you the first time items are needed.", - section = microbotSection, - position = 1 + keyName = "obtainMissingItems", + name = "Obtain Missing Items", + description = "Controls whether the quest helper automatically obtains missing items from the bank and Grand Exchange. 'Ask' will prompt you the first time items are needed.", + section = microbotSection, + position = 1 ) - default ObtainMissingItemsOption obtainMissingItems() { + default ObtainMissingItemsOption obtainMissingItems() + { return ObtainMissingItemsOption.ASK; } @@ -332,14 +335,15 @@ public String toString() } @ConfigItem( - keyName = "valeTotemsWoodType", - name = "Vale Totems wood type", - description = "Which wood type the quester should gather for the Vale Totems miniquest. " + - "Must match the wood you used to build the totem. " + - "Leave on 'Ask me' to be prompted the first time the quest runs.", - section = microbotSection + keyName = "valeTotemsWoodType", + name = "Vale Totems wood type", + description = "Which wood type the quester should gather for the Vale Totems miniquest. " + + "Must match the wood you used to build the totem. " + + "Leave on 'Ask me' to be prompted the first time the quest runs.", + section = microbotSection ) - default ValeTotemsWoodType valeTotemsWoodType() { + default ValeTotemsWoodType valeTotemsWoodType() + { return ValeTotemsWoodType.ASK; } @@ -791,6 +795,25 @@ default boolean showCompletedQuests() return false; } + enum RegionFilterVisibility + { + AUTO, + SHOW, + HIDE + } + + @ConfigItem( + keyName = "regionFilterVisibility", + name = "Region filtering", + description = "Controls when the league region filter is shown. Auto shows it only on league worlds.", + position = 5, + section = filterSection + ) + default RegionFilterVisibility regionFilterVisibility() + { + return RegionFilterVisibility.AUTO; + } + @ConfigSection( position = 5, name = "Development", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java index 3f272b847cf..f1b8c045ec9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java @@ -29,9 +29,9 @@ import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Provides; -import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankTabItems; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.PotionStorage; +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.QuestBankTabInterface; import net.runelite.client.plugins.microbot.questhelper.managers.*; import net.runelite.client.plugins.microbot.questhelper.panel.QuestHelperPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; @@ -39,6 +39,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.Cheerer; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.GlobalFakeObjects; +import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.RuneliteConfigSetter; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.RuneliteObjectManager; import net.runelite.client.plugins.microbot.questhelper.statemanagement.PlayerStateManager; import net.runelite.client.plugins.microbot.questhelper.tools.Icon; @@ -49,7 +50,7 @@ import net.runelite.api.events.*; import net.runelite.api.gameval.InventoryID; import net.runelite.api.gameval.VarPlayerID; -import net.runelite.client.RuneLite; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; @@ -60,9 +61,11 @@ import net.runelite.client.events.RuneScapeProfileChanged; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SkillIconManager; +import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.bank.BankSearch; +import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.components.colorpicker.ColorPickerManager; @@ -101,6 +104,7 @@ public class QuestHelperPlugin extends Plugin @Inject private ClientThread clientThread; + @Getter @Inject private EventBus eventBus; @@ -162,6 +166,17 @@ public class QuestHelperPlugin extends Plugin @Inject public SkillIconManager skillIconManager; + @Inject + public SpriteManager spriteManager; + + @Inject + private QuestBankTabInterface questBankTabInterface; + + public boolean fullCrate; + + @Inject + QuestScript questScript; + private QuestHelperPanel panel; private NavigationButton navButton; @@ -170,9 +185,9 @@ public class QuestHelperPlugin extends Plugin private final Collection configEvents = Arrays.asList("orderListBy", "filterListBy", "questDifficulty", "showCompletedQuests"); private final Collection configItemEvents = Arrays.asList("highlightNeededQuestItems", "highlightNeededMiniquestItems", "highlightNeededAchievementDiaryItems"); - public boolean fullCrate; - @Inject - QuestScript questScript; + + @Getter + private boolean inCutscene = false; @Provides QuestHelperConfig getConfig(ConfigManager configManager) @@ -234,6 +249,7 @@ protected void startUp() throws IOException @Override protected void shutDown() { + questScript.shutdown(); runeliteObjectManager.shutDown(); eventBus.unregister(playerStateManager); @@ -260,6 +276,7 @@ protected void shutDown() public void onGameTick(GameTick event) { questBankManager.loadInitialStateFromConfig(client); + playerStateManager.loadInitialStateFromConfig(); questManager.updateQuestState(); } @@ -314,6 +331,7 @@ public void onGameStateChanged(final GameStateChanged event) questBankManager.saveBankToConfig(); SwingUtilities.invokeLater(() -> panel.refresh(Collections.emptyList(), true, new HashMap<>())); questBankManager.emptyState(); + playerStateManager.emptyState(); questManager.shutDownQuest(true); profileChanged = true; } @@ -325,7 +343,10 @@ public void onGameStateChanged(final GameStateChanged event) GlobalFakeObjects.createNpcs(client, runeliteObjectManager, configManager, config); newVersionManager.updateChatWithNotificationIfNewVersion(); questBankManager.setUnknownInitialState(); + playerStateManager.setUnknownInitialState(); potionStorage.updateCachedPotions = true; + boolean isLeague = client.getWorldType().contains(WorldType.SEASONAL); + SwingUtilities.invokeLater(() -> panel.updateRegionFilterVisibility(isLeague)); clientThread.invokeAtTickEnd(() -> { questManager.setupRequirements(); questManager.setupOnLogin(); @@ -342,6 +363,11 @@ private void onRuneScapeProfileChanged(RuneScapeProfileChanged ev) @Subscribe public void onVarbitChanged(VarbitChanged event) { + if (event.getVarbitId() == VarbitID.CUTSCENE_STATUS) + { + this.inCutscene = event.getValue() == 1; + } + if (!(client.getGameState() == GameState.LOGGED_IN)) { return; @@ -376,6 +402,12 @@ public void onConfigChanged(ConfigChanged event) return; } + if ("regionFilterVisibility".equals(event.getKey())) + { + boolean isLeague = client.getWorldType().contains(WorldType.SEASONAL); + SwingUtilities.invokeLater(() -> panel.updateRegionFilterVisibility(isLeague)); + } + if (configEvents.contains(event.getKey()) || event.getKey().contains("skillfilter")) { clientThread.invokeLater(questManager::updateQuestList); @@ -452,6 +484,37 @@ else if (developerMode && commandExecuted.getCommand().equals("qh-inv")) } log.debug(String.valueOf(inv)); } + else if (developerMode && commandExecuted.getCommand().equals("qh")) + { + var args = commandExecuted.getArguments(); + if (args.length == 0) + { + return; + } + var subCommand = args[0]; + if (subCommand.equals("container")) + { + if (args.length < 2) + { + return; + } + var container = args[1]; + switch (container) + { + case "keyring": + var keyringItems = QuestContainerManager.getKeyRingData().getItems(); + for (var item : keyringItems) + { + log.debug("Key ring item: {}", item); + } + break; + } + } + else if (subCommand.equals("cheer")) + { + addCheerer(); + } + } } @Subscribe(priority = 100) @@ -470,6 +533,11 @@ public List getPluginBankTagItemsForSections() return questBankManager.getBankTagService().getPluginBankTagItemsForSections(false); } + public boolean isBankTabOpen() + { + return questBankTabInterface.isQuestTabActive(); + } + public @Nullable QuestHelper getSelectedQuest() { return questManager.getSelectedQuest(); @@ -530,7 +598,8 @@ public void onMenuEntryAdded(MenuEntryAdded event) @Subscribe public void onChatMessage(ChatMessage chatMessage) { - if (chatMessage.getMessage().equals("The crate is full of bananas.")) { + if (chatMessage.getMessage().equals("The crate is full of bananas.")) + { fullCrate = true; } if (config.showFan() && chatMessage.getType() == ChatMessageType.GAMEMESSAGE) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java index 90c88c4c779..041de959ee4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java @@ -34,10 +34,12 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.*; import net.runelite.api.events.*; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.InventoryID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarClientID; +import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.ItemQuantityMode; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; @@ -55,13 +57,15 @@ import javax.inject.Inject; import javax.inject.Singleton; -import java.awt.*; import java.awt.Point; -import java.util.*; +import java.awt.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; +import static net.runelite.client.plugins.microbot.questhelper.bank.banktab.PotionStorage.COMPONENTS_PER_POTION; +import static net.runelite.client.plugins.microbot.questhelper.bank.banktab.PotionStorage.VIAL_IDX; import static net.runelite.client.plugins.banktags.BankTagsPlugin.*; @Singleton diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java index 849b9d7035c..32e6be9e82d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java @@ -132,10 +132,6 @@ public void handleClick(MenuOptionClicked event) return; } String menuOption = event.getMenuOption(); - if (menuOption == null) - { - return; - } // If click a base tab, close boolean clickedTabTag = menuOption.startsWith("View tab") && !event.getMenuTarget().equals("quest-helper"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java index 48d4486ff53..fc2b9b77ddc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java @@ -32,6 +32,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.api.Client; import net.runelite.api.gameval.ItemID; +import net.runelite.client.config.ConfigManager; import javax.inject.Inject; import javax.inject.Singleton; @@ -50,6 +51,9 @@ public class QuestHelperBankTagService @Inject private Client client; + @Inject + private ConfigManager configManager; + ArrayList taggedItems; ArrayList taggedItemsForBank; @@ -221,14 +225,18 @@ private void getItemsFromRequirement(List pluginItems, ItemRequirem else if (itemRequirement instanceof KeyringRequirement) { KeyringRequirement keyringRequirement = (KeyringRequirement) itemRequirement; - KeyringRequirement fakeRequirement = new KeyringRequirement(keyringRequirement.getName(), plugin.getConfigManager(), - keyringRequirement.getKeyringCollection()); - if (keyringRequirement.hasKeyOnKeyRing()) + var keyringCollection = keyringRequirement.getKeyringCollection(); + var fakeRequirement = keyringRequirement.copy(); + if (keyringCollection.hasKeyOnKeyRing(configManager)) { fakeRequirement.addAlternates(ItemID.FAVOUR_KEY_RING); + // NOTE: If the key is on your key ring _AND_ in your bank, we will still suggest using the key ring. + pluginItems.add(new BankTabItem(fakeRequirement, ItemID.FAVOUR_KEY_RING)); + } + else + { + pluginItems.add(makeBankTabItem(fakeRequirement)); } - pluginItems.add(makeBankTabItem(fakeRequirement)); - } else { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bikeshedder/BikeShedder.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bikeshedder/BikeShedder.java deleted file mode 100644 index 67222f288e5..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bikeshedder/BikeShedder.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2024, pajlada - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.bikeshedder; - -import com.google.common.collect.ImmutableMap; -import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.collections.TeleportCollections; -import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; -import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.player.SpellbookRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.Spellbook; -import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.client.plugins.microbot.questhelper.steps.widget.NormalSpells; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - -public class BikeShedder extends BasicQuestHelper -{ - private DetailedQuestStep moveToLumbridge; - private DetailedQuestStep confuseHans; - private DetailedQuestStep equipLightbearer; - - private ItemRequirement anyLog; - private ObjectStep useLogOnBush; - - private ItemRequirement oneCoin; - private ItemRequirement manyCoins; - private ObjectStep useCoinOnBush; - private ObjectStep useManyCoinsOnBush; - - private ItemRequirement varrockTeleport; - private ItemRequirement ardougneTeleport; - private ItemRequirement faladorTeleport; - - private Zone conditionalRequirementZone; - private ZoneRequirement conditionalRequirementZoneRequirement; - private ZoneRequirement conditionalRequirementZoneSouthRequirement; - private ZoneRequirement conditionalRequirementZoneNorthRequirement; - private ItemRequirement conditionalRequirementCoins; - private DetailedQuestStep conditionalRequirementLookAtCoins; - private ItemRequirement conditionalRequirementGoldBar; - private WidgetTextRequirement lookAtCooksAssistantRequirement; - private DetailedQuestStep lookAtCooksAssistant; - private WidgetTextRequirement lookAtCooksAssistantTextRequirement; - private ZoneRequirement byStaircaseInSunrisePalace; - private ObjectStep goDownstairsInSunrisePalace; - private DetailedQuestStep haveRunes; - private ItemRequirement lightbearer; - private ItemRequirement elemental30Unique; - private ItemRequirement elemental30; - private ItemRequirement anyCoins; - private ItemStep getCoins; - - // Sailing - private NpcStep talkToNpcOnBoat; - private NpcStep talkToKlarenceFromShip; - private ObjectStep useSalvagingHook; - private ObjectStep useObjectOffBoat; - private ZoneRequirement onBoat1; - private ZoneRequirement onBoat2; - private ZoneRequirement onBoat3; - private ZoneRequirement onBoat4; - - @Override - public Map loadSteps() - { - var lumbridge = new Zone(new WorldPoint(3217, 3210, 0), new WorldPoint(3226, 3228, 0)); - var outsideLumbridge = new ZoneRequirement(false, lumbridge); - moveToLumbridge.setHighlightZone(lumbridge); - var steps = new ConditionalStep(this, confuseHans); - - // aldarin bank - var plankNoBank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); - { - // Do not check bank for plank - var plankStep = new DetailedQuestStep(this, "Plank requirement will not check bank", plankNoBank); - var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will not check bank (Requirement used as conditional step passed)", plankNoBank); - var cPlankStep = new ConditionalStep(this, plankStep); - cPlankStep.addStep(plankNoBank, plankStepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2926, 0)), cPlankStep); - } - - { - // Check bank for plank using alsoCheckBank - var plank = plankNoBank.alsoCheckBank(); - plank.setName("Plank (check bank 1)"); - var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 1", plank); - var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 1 (Requirement used as conditional step passed)", plank); - var cPlankStep = new ConditionalStep(this, plankStep); - cPlankStep.addStep(plank, plankStepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2925, 0)), cPlankStep); - } - - { - // Check bank for plank using setShouldCheckBank - var plank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); - plank.setShouldCheckBank(true); - plank.setName("Plank (check bank 2)"); - var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 2", plank); - var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 2 (Requirement used as conditional step passed)", plank); - var cPlankStep = new ConditionalStep(this, plankStep); - cPlankStep.addStep(plank, plankStepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2924, 0)), cPlankStep); - } - - // mistrock bank - { - // does not need to be equipped - var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); - var step = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped", blueWizardHat); - var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped (Requirement used as conditional step passed)", blueWizardHat); - var cStep = new ConditionalStep(this, step); - cStep.addStep(blueWizardHat, stepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1383, 2866, 0)), cStep); - } - - { - // must be equipped - var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); - blueWizardHat.setMustBeEquipped(true); - var step = new DetailedQuestStep(this, "Blue wizard hat, must be equipped", blueWizardHat); - var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, must be equipped (Requirement used as conditional step passed)", blueWizardHat); - var cStep = new ConditionalStep(this, step); - cStep.addStep(blueWizardHat, stepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1382, 2866, 0)), cStep); - } - - // Boat - steps.addStep(onBoat1, talkToNpcOnBoat); - steps.addStep(onBoat2, talkToKlarenceFromShip); - steps.addStep(onBoat3, useSalvagingHook); - steps.addStep(onBoat4, useObjectOffBoat); - - steps.addStep(byStaircaseInSunrisePalace, goDownstairsInSunrisePalace); - steps.addStep(outsideLumbridge, moveToLumbridge); - steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3218, 0)), haveRunes); - steps.addStep(new ZoneRequirement(new WorldPoint(3222, 3218, 0)), equipLightbearer); - steps.addStep(new ZoneRequirement(new WorldPoint(3223, 3218, 0)), useLogOnBush); - steps.addStep(new ZoneRequirement(new WorldPoint(3222, 3217, 0)), useCoinOnBush); - steps.addStep(new ZoneRequirement(new WorldPoint(3223, 3216, 0)), useManyCoinsOnBush); - steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3216, 0)), getCoins); - steps.addStep(conditionalRequirementZoneRequirement, conditionalRequirementLookAtCoins); - steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3221, 0)), lookAtCooksAssistant); - - return new ImmutableMap.Builder() - .put(-1, steps) - .build(); - } - - @Override - protected void setupRequirements() - { - moveToLumbridge = new DetailedQuestStep(this, new WorldPoint(3221, 3218, 0), "Move to outside Lumbridge Castle"); - - var normalSpellbook = new SpellbookRequirement(Spellbook.NORMAL); - - confuseHans = new NpcStep(this, NpcID.HANS, new WorldPoint(3221, 3218, 0), "Cast Confuse on Hans", normalSpellbook); - confuseHans.addSpellHighlight(NormalSpells.CONFUSE); - - lightbearer = new ItemRequirement("Lightbearer", ItemID.LIGHTBEARER).highlighted(); - equipLightbearer = new DetailedQuestStep(this, "Equip a Lightbearer", lightbearer.equipped()); - - anyLog = new ItemRequirement("Any log", ItemCollections.LOGS_FOR_FIRE).highlighted(); - - useLogOnBush = new ObjectStep(this, ObjectID.PVPW_ARMOURSTAND_BUSH, new WorldPoint(3223, 3217, 0), "Use log on bush", anyLog); - useLogOnBush.addIcon(ItemID.LOGS); - - varrockTeleport = TeleportCollections.VARROCK_TELEPORT.getItemRequirement(); - ardougneTeleport = TeleportCollections.ARDOUGNE_TELEPORT.getItemRequirement(); - faladorTeleport = TeleportCollections.FALADOR_TELEPORT.getItemRequirement(); - - oneCoin = new ItemRequirement("Coins", ItemCollections.COINS, 1); - oneCoin.setHighlightInInventory(true); - useCoinOnBush = new ObjectStep(this, ObjectID.PVPW_ARMOURSTAND_BUSH, new WorldPoint(3223, 3217, 0), "Use coins on the bush.", oneCoin); - useCoinOnBush.addIcon(ItemID.COINS); - - manyCoins = new ItemRequirement("Coins", ItemCollections.COINS, 100); - manyCoins.setHighlightInInventory(true); - useManyCoinsOnBush = new ObjectStep(this, ObjectID.PVPW_ARMOURSTAND_BUSH, new WorldPoint(3223, 3217, 0), "Use many coins on the bush.", manyCoins); - useManyCoinsOnBush.addIcon(ItemID.COINS); - - conditionalRequirementZone = new Zone(new WorldPoint(3223, 3221, 0), new WorldPoint(3223, 3223, 0)); - conditionalRequirementZoneRequirement = new ZoneRequirement(conditionalRequirementZone); - conditionalRequirementZoneSouthRequirement = new ZoneRequirement(new WorldPoint(3223, 3221, 0)); - conditionalRequirementZoneNorthRequirement = new ZoneRequirement(new WorldPoint(3223, 3223, 0)); - - conditionalRequirementCoins = new ItemRequirement("Coins", ItemCollections.COINS, 50); - conditionalRequirementCoins.setTooltip("Obtained by robbing a bank"); - conditionalRequirementCoins.setHighlightInInventory(true); - conditionalRequirementCoins.setConditionToHide(conditionalRequirementZoneSouthRequirement); - - conditionalRequirementGoldBar = new ItemRequirement("Gold Bar", ItemID.GOLD_BAR, 1); - conditionalRequirementGoldBar.setTooltip("Obtained by robbing a bank"); - conditionalRequirementGoldBar.setHighlightInInventory(true); - conditionalRequirementGoldBar.setConditionToHide(or(conditionalRequirementZoneNorthRequirement, conditionalRequirementZoneSouthRequirement)); - - conditionalRequirementLookAtCoins = new DetailedQuestStep(this, "Admire the coins in your inventory.", conditionalRequirementCoins); - - lookAtCooksAssistantRequirement = new WidgetTextRequirement(InterfaceID.Questjournal.TITLE, "Cook's Assistant"); - lookAtCooksAssistantRequirement.setDisplayText("Cook's Assistant quest journal open"); - lookAtCooksAssistantTextRequirement = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "he now lets me use his high quality range"); - lookAtCooksAssistantTextRequirement.setDisplayText("Cook's Assistant quest journal open & received reward (checking text)"); - lookAtCooksAssistant = new DetailedQuestStep(this, "Open the Cook's Assistant quest journal. You must have started the quest for this test to work.", lookAtCooksAssistantRequirement, lookAtCooksAssistantTextRequirement); - - var upstairsInSunrisePalace = new Zone(new WorldPoint(1684, 3162, 1), new WorldPoint(1691, 3168, 1)); - byStaircaseInSunrisePalace = new ZoneRequirement(upstairsInSunrisePalace); - goDownstairsInSunrisePalace = new ObjectStep(getQuest().getQuestHelper(), ObjectID.CIVITAS_PALACE_STAIRS_DOWN, new WorldPoint(1690, 3164, 1), "Climb downstairs, ensure stairs are well highlighted!"); - - - var fire30 = new ItemRequirement("Fire runes", ItemID.FIRERUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 63)); - var air30 = new ItemRequirement("Air runes", ItemID.AIRRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 66)); - var water30 = new ItemRequirement("Water runes", ItemID.WATERRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 56)); - var earth30 = new ItemRequirement("Earth runes", ItemID.EARTHRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 60)); - elemental30Unique = new ItemRequirements(LogicType.OR, "Elemental runes as ItemRequirements OR", air30, water30, earth30, fire30); - elemental30Unique.addAlternates(ItemID.FIRERUNE, ItemID.EARTHRUNE, ItemID.AIRRUNE); - elemental30 = new ItemRequirement("Elemental rune as ItemRequirement", List.of(ItemID.AIRRUNE, ItemID.EARTHRUNE, ItemID.WATERRUNE, - ItemID.FIRERUNE), 30); - elemental30.setTooltip("You have potato"); - haveRunes = new DetailedQuestStep(this, "Compare rune checks for ItemRequirement and ItemRequirements with OR.", elemental30, elemental30Unique); - - anyCoins = new ItemRequirement("Coins", ItemCollections.COINS); - getCoins = new ItemStep(this, new WorldPoint(3224, 3215, 0), "Get coins", anyCoins); - - // Sailing - - var zones1 = new Zone[] { - new Zone(new WorldPoint(3843, 6402, 1), new WorldPoint(3844, 6402, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6389, 1), new WorldPoint(3876, 6389, 1)), - new Zone(new WorldPoint(3842, 6365, 1), new WorldPoint(3860, 6365, 1)), - new Zone(new WorldPoint(3843, 6354, 1), new WorldPoint(3884, 6354, 1)) - }; - onBoat1 = new ZoneRequirement(zones1); - - var zones2 = new Zone[] { - new Zone(new WorldPoint(3843, 6403, 1), new WorldPoint(3844, 6403, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6390, 1), new WorldPoint(3876, 6390, 1)), - new Zone(new WorldPoint(3842, 6366, 1), new WorldPoint(3860, 6366, 1)), - new Zone(new WorldPoint(3843, 6355, 1), new WorldPoint(3884, 6355, 1)) - }; - onBoat2 = new ZoneRequirement(zones2); - - var zones3 = new Zone[] { - new Zone(new WorldPoint(3843, 6404, 1), new WorldPoint(3844, 6404, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6391, 1), new WorldPoint(3876, 6391, 1)), - new Zone(new WorldPoint(3842, 6367, 1), new WorldPoint(3860, 6367, 1)), - new Zone(new WorldPoint(3843, 6356, 1), new WorldPoint(3884, 6356, 1)) - }; - onBoat3 = new ZoneRequirement(zones3); - - var zones4 = new Zone[] { - new Zone(new WorldPoint(3843, 6405, 1), new WorldPoint(3844, 6405, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6312, 1), new WorldPoint(3876, 6392, 1)), - new Zone(new WorldPoint(3842, 6368, 1), new WorldPoint(3860, 6368, 1)), - new Zone(new WorldPoint(3843, 6357, 1), new WorldPoint(3884, 6357, 1)) - }; - onBoat4 = new ZoneRequirement(zones4); - - talkToNpcOnBoat = new NpcStep(this, NpcID.SAILING_INTRO_ANNE_BOAT, "Talk to a ship NPC."); - List shipNpcs = new ArrayList<>(); - for (int i = NpcID.SAILING_CREW_GENERIC_1_WORLD; i <= NpcID.SAILING_CREW_GHOST_JENKINS_CARGO_3; i++) - { - shipNpcs.add(i); - } - talkToNpcOnBoat.addHighlightZones(zones1); - talkToNpcOnBoat.addAlternateNpcs(shipNpcs.toArray(new Integer[0])); - - talkToKlarenceFromShip = new NpcStep(this, NpcID.KLARENSE, new WorldPoint(3046, 3205, 0), "Klarence off the ship."); - talkToKlarenceFromShip.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); - talkToKlarenceFromShip.addHighlightZones(zones2); - List salvagingHookIds = new ArrayList<>(); - for (int i = ObjectID.SAILING_INTRO_SALVAGING_HOOK; i <= ObjectID.SALVAGING_HOOK_LARGE_DRAGON_B; i++) - { - salvagingHookIds.add(i); - } - - useSalvagingHook = new ObjectStep(this, ObjectID.SAILING_INTRO_SALVAGING_HOOK, "Use the salvaging hook."); - useSalvagingHook.addAlternateObjects(salvagingHookIds.toArray(new Integer[0])); - useSalvagingHook.addHighlightZones(zones3); - - useObjectOffBoat = new ObjectStep(this, ObjectID.DRAGONSHIPGANGPLANK_ON, new WorldPoint(3047, 3205, 0), "Click Klarense's gangplank."); - useObjectOffBoat.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); - useObjectOffBoat.addHighlightZones(zones4); - } - - @Override - public List getItemRecommended() { - return Arrays.asList(varrockTeleport, ardougneTeleport, faladorTeleport, elemental30, elemental30Unique); - } - - @Override - public List getPanels() - { - var panels = new ArrayList(); - - panels.add(new PanelDetails("Move to Lumbridge", List.of(moveToLumbridge))); - panels.add(new PanelDetails("Normal Spellbook", List.of(confuseHans))); - panels.add(new PanelDetails("Equip Lightbearer", List.of(equipLightbearer), List.of(lightbearer))); - panels.add(new PanelDetails("Use log on mysterious bush", List.of(useLogOnBush), List.of(anyLog))); - panels.add(new PanelDetails("Use coins on mysterious bush", List.of(useCoinOnBush, useManyCoinsOnBush), List.of(oneCoin, manyCoins))); - panels.add(new PanelDetails("Conditional requirement", List.of(conditionalRequirementLookAtCoins), List.of(conditionalRequirementCoins, conditionalRequirementGoldBar))); - panels.add(new PanelDetails("Item step", List.of(getCoins), List.of(anyCoins))); - panels.add(new PanelDetails("Quest state", List.of(lookAtCooksAssistant), List.of(lookAtCooksAssistantRequirement, lookAtCooksAssistantTextRequirement))); - panels.add(new PanelDetails("Ensure staircase upstairs in Sunrise Palace is highlighted", List.of(goDownstairsInSunrisePalace), List.of())); - panels.add(new PanelDetails("Sailing", List.of(talkToNpcOnBoat, talkToKlarenceFromShip, useSalvagingHook, useObjectOffBoat), List.of())); - - return panels; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java index 37a15faf427..4fe8c70dff3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java @@ -243,6 +243,39 @@ public enum ItemCollections ItemID.WILDERNESS_SWORD_ELITE )), + THROWING_KNIVES("Throwing Knives", ImmutableList.of( + ItemID.BRONZE_KNIFE, ItemID.BRONZE_KNIFE_P, ItemID.BRONZE_KNIFE_P_, ItemID.BRONZE_KNIFE_P__, + ItemID.IRON_KNIFE, ItemID.IRON_KNIFE_P, ItemID.IRON_KNIFE_P_, ItemID.IRON_KNIFE_P__, + ItemID.STEEL_KNIFE, ItemID.STEEL_KNIFE_P, ItemID.STEEL_KNIFE_P_, ItemID.STEEL_KNIFE_P__, + ItemID.BLACK_KNIFE, ItemID.BLACK_KNIFE_P, ItemID.BLACK_KNIFE_P_, ItemID.BLACK_KNIFE_P__, + ItemID.MITHRIL_KNIFE, ItemID.MITHRIL_KNIFE_P, ItemID.MITHRIL_KNIFE_P_, ItemID.MITHRIL_KNIFE_P__, + ItemID.ADAMANT_KNIFE, ItemID.ADAMANT_KNIFE_P, ItemID.ADAMANT_KNIFE_P_, ItemID.ADAMANT_KNIFE_P__, + ItemID.RUNE_KNIFE, ItemID.RUNE_KNIFE_P, ItemID.RUNE_KNIFE_P_, ItemID.RUNE_KNIFE_P__, + ItemID.DRAGON_KNIFE, ItemID.DRAGON_KNIFE_P, ItemID.DRAGON_KNIFE_P_, ItemID.DRAGON_KNIFE_P__ + )), + + DARTS("Darts", ImmutableList.of( + ItemID.BRONZE_DART, ItemID.BRONZE_DART_P, ItemID.BRONZE_DART_P_, ItemID.BRONZE_DART_P__, + ItemID.IRON_DART, ItemID.IRON_DART_P, ItemID.IRON_DART_P_, ItemID.IRON_DART_P__, + ItemID.STEEL_DART, ItemID.STEEL_DART_P, ItemID.STEEL_DART_P_, ItemID.STEEL_DART_P__, + ItemID.BLACK_DART, ItemID.BLACK_DART_P, ItemID.BLACK_DART_P_, ItemID.BLACK_DART_P__, + ItemID.MITHRIL_DART, ItemID.MITHRIL_DART_P, ItemID.MITHRIL_DART_P_, ItemID.MITHRIL_DART_P__, + ItemID.ADAMANT_DART, ItemID.ADAMANT_DART_P, ItemID.ADAMANT_DART_P_, ItemID.ADAMANT_DART_P__, + ItemID.RUNE_DART, ItemID.RUNE_DART_P, ItemID.RUNE_DART_P_, ItemID.RUNE_DART_P__, + ItemID.AMETHYST_DART, ItemID.AMETHYST_DART_P, ItemID.AMETHYST_DART_P_, ItemID.AMETHYST_DART_P__, + ItemID.DRAGON_DART, ItemID.DRAGON_DART_P, ItemID.DRAGON_DART_P_, ItemID.DRAGON_DART_P__ + )), + + THROWING_AXES("Throwing Axes", ImmutableList.of( + ItemID.BRONZE_THROWNAXE, + ItemID.IRON_THROWNAXE, + ItemID.STEEL_THROWNAXE, + ItemID.MITHRIL_THROWNAXE, + ItemID.ADAMNT_THROWNAXE, + ItemID.RUNE_THROWNAXE, + ItemID.DRAGON_THROWNAXE + )), + METAL_ARROWS(ImmutableList.of( ItemID.RUNE_ARROW, ItemID.ADAMANT_ARROW, @@ -2211,6 +2244,25 @@ public enum ItemCollections ItemID.WILDBLOOD_HOP_SEED )), + /// Things you can slash webs with that are safe to bring to wildy + SLASH_WEB_KNIFE(ImmutableList.of( + ItemID.KNIFE, + ItemID.WILDERNESS_SWORD_ELITE, + ItemID.WILDERNESS_SWORD_HARD, + ItemID.WILDERNESS_SWORD_MEDIUM, + ItemID.WILDERNESS_SWORD_EASY + )), + + BOAT_REPAIR_KITS(ImmutableList.of( + ItemID.BOAT_REPAIR_KIT_ROSEWOOD, + ItemID.BOAT_REPAIR_KIT_IRONWOOD, + ItemID.BOAT_REPAIR_KIT_CAMPHOR, + ItemID.BOAT_REPAIR_KIT_MAHOGANY, + ItemID.BOAT_REPAIR_KIT_TEAK, + ItemID.BOAT_REPAIR_KIT_OAK, + ItemID.BOAT_REPAIR_KIT + )), + BUSH_SEEDS(ImmutableList.of( ItemID.REDBERRY_BUSH_SEED, ItemID.CADAVABERRY_BUSH_SEED, @@ -2252,6 +2304,13 @@ public enum ItemCollections ItemID.CA_OFFHAND_EASY )), + ARDOUGNE_CLOAK(ImmutableList.of( + ItemID.ARDY_CAPE_EASY, + ItemID.ARDY_CAPE_MEDIUM, + ItemID.ARDY_CAPE_HARD, + ItemID.ARDY_CAPE_ELITE + )), + PROSPECTOR_HELMET(ImmutableList.of( ItemID.MOTHERLODE_REWARD_HAT, ItemID.FOSSIL_MOTHERLODE_REWARD_HAT, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java index aae9f687d59..341738056a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java @@ -24,16 +24,11 @@ */ package net.runelite.client.plugins.microbot.questhelper.collections; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import lombok.Getter; import net.runelite.api.gameval.ItemID; import net.runelite.client.config.ConfigManager; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - public enum KeyringCollection { SHINY_KEY(ItemID.IKOV_SHINYKEY), @@ -50,14 +45,18 @@ public enum KeyringCollection ENCHANTED_KEY(ItemID.MAKINGHISTORY_KEY), NEW_KEY(ItemID.MOURNING_EXCAVATION_KEY); + private final String CONFIG_GROUP = QuestHelperConfig.QUEST_BACKGROUND_GROUP; + @Getter private final int itemID; + KeyringCollection(int itemID) { this.itemID = itemID; } - public String toChatText() + /// The name of this key as seen in the chat box. + public String chatboxText() { return name().toLowerCase().replaceAll("_", " "); } @@ -67,19 +66,20 @@ public String runeliteName() return name().toLowerCase().replaceAll("_", ""); } - public static List allKeyRequirements(ConfigManager configManager) + public boolean hasKeyOnKeyRing(ConfigManager configManager) { - List keys = new ArrayList<>(); - for (KeyringCollection keyringCollection : Collections.unmodifiableList(Arrays.asList(values()))) - { - keys.add(new KeyringRequirement(configManager, keyringCollection)); - } + var value = configManager.getRSProfileConfiguration(CONFIG_GROUP, runeliteName()); - return keys; + return "true".equals(value); } - public KeyringRequirement getRequirement(ConfigManager configManager) + public void setHasKeyOnKeyRing(ConfigManager configManager, boolean value) { - return new KeyringRequirement(configManager, this); + if (configManager.getRSProfileKey() == null) + { + return; + } + + configManager.setRSProfileConfiguration(CONFIG_GROUP, runeliteName(), value ? "true" : "false"); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java index 5e57251dafe..258d034304e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java @@ -29,7 +29,7 @@ public ItemRequirement getItemRequirement() ItemRequirement varrockRunes = new ItemRequirements("Varrock teleport runes", new ItemRequirement("Law rune", ItemID.LAWRUNE, 1), new ItemRequirement("Air rune", ItemID.AIRRUNE, 3), - new ItemRequirement("Water rune", ItemID.WATERRUNE, 1) + new ItemRequirement("Fire rune", ItemID.FIRERUNE, 1) ); return new ItemRequirements(LogicType.OR, "Teleport to Varrock. Varrock teleport tablet/spell, Chronicle, Ring of Wealth (Grand Exchange [2])", varrockTele, varrockRunes); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/ConfigKeys.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/ConfigKeys.java deleted file mode 100644 index 5a7402bf71e..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/ConfigKeys.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2024, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.config; - -import lombok.Getter; - -public enum ConfigKeys -{ - // Barbarian Training Enums - BARBARIAN_TRAINING_STARTED_FISHING("barbariantrainingstartedfishing"), - BARBARIAN_TRAINING_STARTED_HARPOON("barbariantrainingstartedharpoon"), - BARBARIAN_TRAINING_STARTED_SEED_PLANTING("barbariantrainingstartedseedplanting"), - BARBARIAN_TRAINING_STARTED_POT_SMASHING("barbariantrainingstartedpotsmashing"), - BARBARIAN_TRAINING_STARTED_FIREMAKING("barbariantrainingstartedfiremaking"), - BARBARIAN_TRAINING_STARTED_PYREMAKING("barbariantrainingstartedpyremaking"), - BARBARIAN_TRAINING_STARTED_HERBLORE("barbariantrainingstartedherblore"), - BARBARIAN_TRAINING_STARTED_SPEAR("barbariantrainingstartedspear"), - BARBARIAN_TRAINING_STARTED_HASTA("barbariantrainingstartedhasta"), - - // Finished Barbarian Training Enums - BARBARIAN_TRAINING_FINISHED_FISHING("barbariantrainingfinishedfishing"), - BARBARIAN_TRAINING_FINISHED_HARPOON("barbariantrainingfinishedharpoon"), - BARBARIAN_TRAINING_FINISHED_SEED_PLANTING("barbariantrainingfinishedseedplanting"), - BARBARIAN_TRAINING_FINISHED_POT_SMASHING("barbariantrainingfinishedpotsmashing"), - BARBARIAN_TRAINING_FINISHED_FIREMAKING("barbariantrainingfinishedfiremaking"), - BARBARIAN_TRAINING_FINISHED_PYREMAKING("barbariantrainingfinishedpyremaking"), - BARBARIAN_TRAINING_FINISHED_SPEAR("barbariantrainingfinishedspear"), - BARBARIAN_TRAINING_FINISHED_HASTA("barbariantrainingfinishedhasta"), - BARBARIAN_TRAINING_FINISHED_HERBLORE("barbariantrainingfinishedherblore"), - - // Mid-conditions - BARBARIAN_TRAINING_PLANTED_SEED("barbariantrainingplantedseed"), - BARBARIAN_TRAINING_SMASHED_POT("barbariantrainingsmashedpot"), - BARBARIAN_TRAINING_BOW_FIRE("barbariantrainingbowfire"), - BARBARIAN_TRAINING_PYRE_MADE("barbariantrainingpyremade"), - BARBARIAN_TRAINING_BARBFISHED("barbariantrainingbarbfished"), - BARBARIAN_TRAINING_HARPOONED_FISH("barbariantrainingharpoonedfish"), - BARBARIAN_TRAINING_MADE_POTION("barbariantrainingmadepotion"), - BARBARIAN_TRAINING_MADE_SPEAR("barbariantrainingmadespear"), - BARBARIAN_TRAINING_MADE_HASTA("barbariantrainingmadehasta"); - - @Getter - final String key; - - ConfigKeys(String key) - { - this.key = key; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/RegionHintArrowRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/LeagueFiltering.java similarity index 56% rename from runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/RegionHintArrowRequirement.java rename to runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/LeagueFiltering.java index 6d58100b98b..7328abe2540 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/RegionHintArrowRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/LeagueFiltering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Zoinkwiz + * Copyright (c) 2026, Syrif * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,43 +22,34 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.client.plugins.microbot.questhelper.requirements; +package net.runelite.client.plugins.microbot.questhelper.config; -import net.runelite.api.Client; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueQuestRegions; +import net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueRegion; -public class RegionHintArrowRequirement extends SimpleRequirement -{ - private final Zone zone; +import java.util.EnumSet; - public RegionHintArrowRequirement(WorldPoint worldPoint) - { - assert(worldPoint != null); - this.zone = new Zone(worldPoint, worldPoint); - } +/** + * Filters quests by league regions selected in the panel UI. + * When no regions are selected, all quests pass. When regions are selected, + * only quests completable with those regions are shown. + */ +public class LeagueFiltering +{ + private static EnumSet selectedRegions = null; - public RegionHintArrowRequirement(Zone zone) + public static void setSelectedRegions(EnumSet regions) { - assert(zone != null); - this.zone = zone; + selectedRegions = (regions == null || regions.isEmpty()) ? null : regions; } - public boolean check(Client client) + public static boolean passesLeagueFilter(QuestHelper questHelper) { - WorldPoint hintArrowPoint = client.getHintArrowPoint(); - if (hintArrowPoint == null) + if (selectedRegions == null) { - return false; + return true; } - - WorldPoint wp = QuestPerspective.getWorldPointConsideringWorldView(client, client.getTopLevelWorldView(), hintArrowPoint); - if (wp == null) - { - return false; - } - - return zone.contains(wp); + return LeagueQuestRegions.isCompletableWith(questHelper.getQuest(), selectedRegions); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/domain/QuetzalDestination.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/domain/QuetzalDestination.java new file mode 100644 index 00000000000..bfd66ce012f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/domain/QuetzalDestination.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2026, pajlada + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.domain; + +import lombok.RequiredArgsConstructor; + +/// Mapping from quetzal destinations to the model ID used in the quetzal map widget. +/// +/// See {@link net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight#createQuetzalHighlight} +@RequiredArgsConstructor +public enum QuetzalDestination +{ + CIVITAS_ILLA_FORTIS(51208), + THE_TEOMAT(51205), + SUNSET_COAST(51187), + HUNTER_GUILD(51185), + ALDARIN(54547), + QUETZACALLI_GORGE(54539), + TAL_TEKLAN(56665); + + public final int modelID; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java index c7fab86e217..7b46a4c89a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java @@ -41,6 +41,8 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -49,9 +51,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; -import java.util.ArrayList; -import java.util.List; - public class ArdougneEasy extends ComplexStateQuestHelper { // Required items @@ -279,7 +278,7 @@ public List getPanels() sections.add(PanelDetails.lockedPanel( "Identify Sword", notIdentifySword, - identifySword, + identifySwordTask, List.of( identifySword ), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java index 09d5b1c2468..63c427560f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java @@ -119,11 +119,11 @@ public QuestStep loadStep() doElite.addStep(notPickHero, pickHeroTask); runeCrossbowTask = new ConditionalStep(this, spinString); - runeCrossbowTask.addStep(new Conditions(madeString, crossbowString), moveToYan); - runeCrossbowTask.addStep(new Conditions(inYanille, madeString, crossbowString), smithLimbs); - runeCrossbowTask.addStep(new Conditions(inYanille, madeLimbs, crossbowString, runeLimbs), fletchStock); - runeCrossbowTask.addStep(new Conditions(inYanille, madeStock, crossbowString, runeLimbs, yewStock), makeUnstrungCross); runeCrossbowTask.addStep(new Conditions(inYanille, madeCrossU, runeCrossbowU, crossbowString), runeCrossbow); + runeCrossbowTask.addStep(new Conditions(inYanille, madeStock, crossbowString, runeLimbs, yewStock), makeUnstrungCross); + runeCrossbowTask.addStep(new Conditions(inYanille, madeLimbs, crossbowString, runeLimbs), fletchStock); + runeCrossbowTask.addStep(new Conditions(inYanille, madeString, crossbowString), smithLimbs); + runeCrossbowTask.addStep(new Conditions(madeString, crossbowString), moveToYan); doElite.addStep(notRuneCrossbow, runeCrossbowTask); return doElite; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java index d08ea96525e..cee94899a40 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java @@ -187,7 +187,7 @@ protected void setupRequirements() var hasCompletedSOTE = new QuestRequirement(QuestHelperQuest.SONG_OF_THE_ELVES, QuestState.FINISHED); - newKey = new KeyringRequirement("New key", configManager, KeyringCollection.NEW_KEY).showConditioned(notDeathRune).isNotConsumed().hideConditioned(hasCompletedSOTE); + newKey = new KeyringRequirement("New key", KeyringCollection.NEW_KEY).showConditioned(notDeathRune).isNotConsumed().hideConditioned(hasCompletedSOTE); newKey.setTooltip("Another can be found on the desk in the south-east room of the Mourner HQ basement."); mournerBoots = new ItemRequirement("Mourner boots", ItemID.MOURNING_MOURNER_BOOTS).isNotConsumed().hideConditioned(hasCompletedSOTE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java index 78ae2a463cc..1a8c9e4ebf5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java @@ -52,7 +52,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import net.runelite.client.game.FishingSpot; import java.util.ArrayList; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java index cf00c7c3de8..99af7a2e11e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java @@ -39,8 +39,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java index ae515eed2ab..61129b38e2e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java @@ -225,7 +225,7 @@ public List getItemRequirements() { return Arrays.asList(rawPie, waterRune.quantity(6), bloodRune.quantity(2), deathRune.quantity(4), dragonDartTip, feather, kqHead, mahoganyPlank.quantity(2), goldLeaves.quantity(2), coins.quantity(50000), saw, - hammer, kqHead); + hammer); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java index 05cd374f162..a53d8be127d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java @@ -157,7 +157,7 @@ protected void setupRequirements() //Required bucket = new ItemRequirement("Bucket", ItemID.BUCKET_EMPTY).showConditioned(notFilledWater).isNotConsumed(); - tiara = new ItemRequirement("Silver Tiara", ItemID.TIARA).showConditioned(notMindTiara); + tiara = new ItemRequirement("Tiara", ItemID.TIARA).showConditioned(notMindTiara); mindTalisman = new ItemRequirement("Mind Talisman", ItemID.MIND_TALISMAN).showConditioned(notMindTiara); hammer = new ItemRequirement("Hammer", ItemID.HAMMER).showConditioned(new Conditions(LogicType.OR, notMotherloadMine, notBluriteLimbs)).isNotConsumed(); pickaxe = new ItemRequirement("Any Pickaxe", ItemCollections.PICKAXES) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java index 950d2727f99..114ddbe74da 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java @@ -50,7 +50,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java index ff4824e6a6a..43b00dee037 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java @@ -51,7 +51,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java index 3826ed23878..1a670253cf4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java @@ -52,7 +52,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; @@ -443,7 +447,10 @@ public List getItemRewards() @Override public List getUnlockRewards() { - return Arrays.asList(new UnlockReward("Improved rate of gaining approval on Miscellania.")); + return Arrays.asList( + new UnlockReward("Improved rate of gaining approval on Miscellania."), + new UnlockReward("Unlocking infinite charges for your lyre with Fossegrimen costs 600 of each fish rather than 800") + ); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java index 7b17d45795d..ac75ab0c37b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java @@ -40,6 +40,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; @@ -53,16 +54,19 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; public class KandarinEasy extends ComplexStateQuestHelper { // Items required - ItemRequirement combatGear, bigFishingNet, coins, juteSeed, seedDibber, rake, batteredKey, + ItemRequirement combatGear, bigFishingNet, coins, juteSeed, seedDibber, rake, spade, batteredKey, emptyFishbowl, fishBowl, seaweed, fishBowlSeaweed, tinyNet, genericFishbowl; // Items recommended @@ -79,7 +83,7 @@ public class KandarinEasy extends ComplexStateQuestHelper QuestStep killFire, killEarth, killWater, killAir; - NpcStep catchMackerel, killEle; + NpcStep catchMackerel; Zone workshop; @@ -127,8 +131,7 @@ public QuestStep loadStep() killEleTask.addStep(new Conditions(inWorkshop, killedFire, killedEarth, killedWater), killAir); killEleTask.addStep(new Conditions(inWorkshop, killedFire, killedEarth), killWater); killEleTask.addStep(new Conditions(inWorkshop, killedFire), killEarth); - killEleTask.addStep(new Conditions(inWorkshop), killFire); - killEleTask.addStep(inWorkshop, killEle); + killEleTask.addStep(inWorkshop, killFire); doEasy.addStep(notKillEle, killEleTask); plantJuteTask = new ConditionalStep(this, plantJute); @@ -175,8 +178,11 @@ protected void setupRequirements() seaweed = new ItemRequirement("Seaweed", ItemID.SEAWEED).showConditioned(notPetFish); juteSeed = new ItemRequirement("Jute seeds", ItemID.JUTE_SEED).showConditioned(notPlantJute); rake = new ItemRequirement("Rake", ItemID.RAKE).showConditioned(notPlantJute).isNotConsumed(); - seedDibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(notPlantJute).isNotConsumed(); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY).showConditioned(notKillEle).isNotConsumed(); + var needSeedDibber = not(new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, 3)); + seedDibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(and(notPlantJute, needSeedDibber)).isNotConsumed(); + spade = new ItemRequirement("Spade (if existing plant in hops patch)", ItemID.SPADE).showConditioned(notPlantJute).isNotConsumed(); + + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY).showConditioned(notKillEle).isNotConsumed(); batteredKey.setTooltip("You can get another by searching the bookcase in the house south of the Elemental " + "Workshop, then reading the book you get from it"); @@ -227,18 +233,14 @@ public void setupSteps() "Speak with Sherlock west of Catherby."); moveToWorkshop = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_SPIRALSTAIRSTOP, new WorldPoint(2711, 3498, 0), "Enter the Elemental Workshop in Seers' Village.", batteredKey, combatGear, food); - killEle = new NpcStep(this, NpcID.ELEMENTAL_FIRE, new WorldPoint(2719, 9889, 0), - "Kill one of each of the 4 elementals.", combatGear, food); - killEle.addAlternateNpcs(NpcID.ELEMENTAL_WATER, NpcID.ELEMENTAL_AIR, NpcID.ELEMENTAL_EARTH); killFire = new NpcStep(this, NpcID.ELEMENTAL_FIRE, new WorldPoint(2719, 9877, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); + "Kill one of the fire elementals.", true, combatGear, food); killEarth = new NpcStep(this, NpcID.ELEMENTAL_EARTH, new WorldPoint(2700, 9903, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); + "Kill one of the earth elementals. Only the roaming ones work for this.", true, combatGear, food); killWater = new NpcStep(this, NpcID.ELEMENTAL_WATER, new WorldPoint(2719, 9903, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); + "Kill one of the water elementals.", true, combatGear, food); killAir = new NpcStep(this, NpcID.ELEMENTAL_AIR, new WorldPoint(2735, 9891, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); - killEle.addSubSteps(killFire, killEarth, killWater, killAir); + "Kill one of the air elementals.", true, combatGear, food); buyStew = new NpcStep(this, NpcID.FORESTERS_BARTENDER, new WorldPoint(2691, 3494, 0), "Talk with the bartender in Seers' Village and buy a stew.", coins.quantity(20)); @@ -247,7 +249,7 @@ public void setupSteps() "Play the organ in Seers' Village Church."); plantJute = new ObjectStep(this, ObjectID.FARMING_HOPS_PATCH_4, new WorldPoint(2669, 3523, 0), "Plant 3 jute seeds in the hops patch north west of Seers' Village.", juteSeed.quantity(3), - seedDibber, rake); + seedDibber, rake, spade); plantJute.addIcon(ItemID.JUTE_SEED); cupTea = new NpcStep(this, NpcID.BROTHER_GALAHAD, new WorldPoint(2612, 3474, 0), "Talk with Galahad west of McGrubor's Wood until he gives you some tea."); @@ -264,7 +266,7 @@ public void setupSteps() public List getItemRequirements() { return Arrays.asList(coins.quantity(33), bigFishingNet, juteSeed.quantity(3), - seedDibber, rake, batteredKey, genericFishbowl, seaweed, combatGear); + seedDibber, rake, spade, batteredKey, genericFishbowl, seaweed, combatGear); } @Override @@ -354,14 +356,14 @@ public List getPanels() buyStewSteps.setLockingStep(buyStewTask); allSteps.add(buyStewSteps); - PanelDetails killElesSteps = new PanelDetails("Defeat Elementals", Arrays.asList(moveToWorkshop, killEle), + PanelDetails killElesSteps = new PanelDetails("Defeat Elementals", Arrays.asList(moveToWorkshop, killFire, killEarth, killWater, killAir), eleWorkI, batteredKey, combatGear, food); killElesSteps.setDisplayCondition(notKillEle); killElesSteps.setLockingStep(killEleTask); allSteps.add(killElesSteps); PanelDetails plantJuteSteps = new PanelDetails("Plant Jute", Collections.singletonList(plantJute), - new SkillRequirement(Skill.FARMING, 13, true), juteSeed.quantity(3), seedDibber, rake); + new SkillRequirement(Skill.FARMING, 13, true), juteSeed.quantity(3), seedDibber, rake, spade); plantJuteSteps.setDisplayCondition(notPlantJute); plantJuteSteps.setLockingStep(plantJuteTask); allSteps.add(plantJuteSteps); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java index 976de10deda..41134fa0bbe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java @@ -147,7 +147,7 @@ protected void setupRequirements() spade = new ItemRequirement("Spade", ItemID.SPADE).showConditioned(notPickDwarf).isNotConsumed(); rake = new ItemRequirement("Rake", ItemID.RAKE).showConditioned(notPickDwarf).isNotConsumed(); compost = new ItemRequirement("Any compost", ItemCollections.COMPOST).showConditioned(notPickDwarf); - harpoon = new ItemRequirement("Harpoon", ItemID.HARPOON).showConditioned(not5Shark).isNotConsumed(); + harpoon = new ItemRequirement("Harpoon", ItemCollections.HARPOONS).showConditioned(not5Shark).isNotConsumed(); cookingGaunt = new ItemRequirement("Cooking gauntlets", ItemID.GAUNTLETS_OF_COOKING).showConditioned(not5Shark).isNotConsumed(); stamPot = new ItemRequirement("Stamina potion (2)", ItemID._2DOSESTAMINA).showConditioned(notStamMix); caviar = new ItemRequirement("Caviar", ItemID.BRUT_CAVIAR).showConditioned(notStamMix); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java index f7df8c3107c..304f5709b5c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java @@ -174,7 +174,7 @@ protected void setupRequirements() Conditions not70Agility = new Conditions(LogicType.NOR, new SkillRequirement(Skill.AGILITY, 70, true)); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, notWaterOrb)).isNotConsumed(); dustyKey.setTooltip("You can get this by killing the Jailer in the Black Knights Base in Taverley Dungeon and" + " using the key he drops to enter the jail cell there to talk to Velrak for the dusty key"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java index af183ee3e36..4954a507115 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java @@ -55,11 +55,14 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; public class KandarinMedium extends ComplexStateQuestHelper { @@ -187,7 +190,7 @@ protected void setupRequirements() hornDust = new ItemRequirement("Horn Dust", ItemID.UNICORN_HORN_DUST, 1).showConditioned(notSuperAnti); vialOfWater = new ItemRequirement("Vial of water", ItemID.VIAL_WATER, 1).showConditioned(notSuperAnti); iritLeaf = new ItemRequirement("Irit leaf", ItemID.IRIT_LEAF, 1).showConditioned(notSuperAnti); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, notGrapOb)).isNotConsumed(); dustyKey.setTooltip("You can get this by killing the Jailer in the Black Knights Base in Taverley Dungeon and" + " using the key he drops to enter the jail cell there to talk to Velrak for the dusty key"); @@ -198,11 +201,12 @@ protected void setupRequirements() bowString = new ItemRequirement("Bow string", ItemID.BOW_STRING).showConditioned(notStringMaple); limpSeed = new ItemRequirement("Limpwurt seed", ItemID.LIMPWURT_SEED).showConditioned(notPickLimp); rake = new ItemRequirement("Rake", ItemID.RAKE).showConditioned(notPickLimp).isNotConsumed(); - seedDib = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(notPickLimp).isNotConsumed(); + var needSeedDibber = not(new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, 3)); + seedDib = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(and(notPickLimp, needSeedDibber)).isNotConsumed(); primedMind = new ItemRequirement("Mind bar", ItemID.ELEM_MIND_BAR).showConditioned(notMindHelm); hammer = new ItemRequirement("Hammer", ItemID.HAMMER).showConditioned(notMindHelm).isNotConsumed(); beatenBook = new ItemRequirement("Beaten Book", ItemID.ELEMENTAL_WORKSHOP_HELM_BOOK).showConditioned(notMindHelm); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY).showConditioned(notMindHelm); + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY).showConditioned(notMindHelm); batteredKey.setTooltip("You can get another by searching the bookcase in the house south of the Elemental " + "Workshop, then reading the book you get from it"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java index 8dcecb38164..35c3f769571 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java @@ -206,18 +206,18 @@ public List getPanels() { List allSteps = new ArrayList<>(); - PanelDetails palmSteps = new PanelDetails("Check Palm Tree Health", Collections.singletonList(checkPalm), - new SkillRequirement(Skill.FARMING, 68, true), palmTreeSapling, rake, spade); - palmSteps.setDisplayCondition(notCheckedPalm); - palmSteps.setLockingStep(checkedPalmTask); - allSteps.add(palmSteps); - PanelDetails calquatSteps = new PanelDetails("Check Calquat Tree Health", Collections.singletonList(checkCalquat), farming72, calquatSapling, rake, spade); calquatSteps.setDisplayCondition(notCheckedCalquat); calquatSteps.setLockingStep(checkedCalquatTask); allSteps.add(calquatSteps); + PanelDetails palmSteps = new PanelDetails("Check Palm Tree Health", Collections.singletonList(checkPalm), + new SkillRequirement(Skill.FARMING, 68, true), palmTreeSapling, rake, spade); + palmSteps.setDisplayCondition(notCheckedPalm); + palmSteps.setLockingStep(checkedPalmTask); + allSteps.add(palmSteps); + PanelDetails equipCapeSteps = new PanelDetails("Equip Fire / Infernal Cape", Collections.singletonList(equipCape), fireCapeOrInfernal); equipCapeSteps.setDisplayCondition(notEquippedCape); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java index 5326e82b359..5885eef1856 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java @@ -73,7 +73,7 @@ public class KaramjaMedium extends BasicQuestHelper Requirement grandTree, taiBwoWannaiTrio, dragonSlayerI, shiloVillage, junglePotion; - QuestStep enterAgilityArena, tag2Pillars, enterVolcano, returnThroughWall, useCart, doCleanup, makeSpiderStick, cookSpider, + QuestStep enterAgilityArena, tagPillar, enterVolcano, returnThroughWall, useCart, doCleanup, makeSpiderStick, cookSpider, climbUpToBoat, travelToKhazard, cutTeak, cutMahogany, catchKarambwanji, catchKarambwan, getMachete, flyToKaramja, growFruitTree, trapGraahk, chopVines, crossLava, climbBrimhavenStaircase, charterFromShipyard, mineRedTopaz, enterCrandor, enterBrimDungeonVine, enterBrimDungeonLava, enterBrimDungeonStairs, claimReward; @@ -108,7 +108,7 @@ public Map loadSteps() doMedium.addStep(notEnteredCrandor, enteredCrandorTask); claimedTicketTask = new ConditionalStep(this, enterAgilityArena); - claimedTicketTask.addStep(inAgilityArena, tag2Pillars); + claimedTicketTask.addStep(inAgilityArena, tagPillar); doMedium.addStep(notClaimedTicket, claimedTicketTask); usedCartTask = new ConditionalStep(this, useCart); @@ -269,7 +269,7 @@ public void setupSteps() enterAgilityArena = new ObjectStep(this, ObjectID.AGILITYARENA_LADDERDOWN, new WorldPoint(2809, 3194, 0), "Pay Cap'n Izzy" + " No Beard 200 coins and enter the Agility Arena in Brimhaven.", coins.quantity(200)); - tag2Pillars = new DetailedQuestStep(this, "Tag 2 marked pillars in a row."); + tagPillar = new DetailedQuestStep(this, "Tag a marked pillar."); enterVolcano = new ObjectStep(this, ObjectID.VOLCANO_ENTRANCE, new WorldPoint(2857, 3169, 0), "Enter the Karamja Volcano."); returnThroughWall = new ObjectStep(this, ObjectID.DRAGONSECRETDOOR, new WorldPoint(2836, 9600, 0), "Return back through the shortcut."); @@ -289,9 +289,12 @@ public void setupSteps() travelToKhazard.addSubSteps(climbUpToBoat); cutTeak = new ObjectStep(this, ObjectID.TEAKTREE, new WorldPoint(2822, 3078, 0), "Chop a teak tree down either in" + " the Hardwood Grove in Tai Bwo Wannai or in the Kharazi Jungle (requires Legends' Quest started).", axe, tradingSticks.quantity(100)); + ((ObjectStep) cutTeak).addAlternateObjects(ObjectID.TEAKTREE_UPDATE); + cutTeak.addDialogStep("Okay, I'll pay 100 trading sticks to enter."); cutMahogany = new ObjectStep(this, ObjectID.MAHOGANYTREE, new WorldPoint(2820, 3080, 0), "Chop a mahogany tree " + "down either in the Hardwood Grove in Tai Bwo Wannai or in the Kharazi Jungle (requires Legends' Quest started).", axe, tradingSticks.quantity(100)); + cutMahogany.addDialogStep("Okay, I'll pay 100 trading sticks to enter."); catchKarambwanji = new NpcStep(this, NpcID._0_43_47_KARAMBWANJI, new WorldPoint(2791,3019,0), "Using your small fishing net, catch some raw karambwanji just south of Tai Bwo Wannai, or buy some from the GE.", smallFishingNet); catchKarambwan = new NpcStep(this, NpcID._0_45_48_KARAMBWAN, new WorldPoint(2899, 3119, 0), @@ -413,7 +416,7 @@ public List getPanels() allSteps.add(enteredCrandorSteps); PanelDetails enterAgiSteps = new PanelDetails("Claim a ticket in The Agility Arena", - Arrays.asList(enterAgilityArena, tag2Pillars), coins.quantity(200)); + Arrays.asList(enterAgilityArena, tagPillar), coins.quantity(200)); enterAgiSteps.setDisplayCondition(notClaimedTicket); enterAgiSteps.setLockingStep(claimedTicketTask); allSteps.add(enterAgiSteps); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java index 53fed369b33..64669b15045 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java @@ -43,7 +43,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java index 901115012d8..2bc2bca010d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java @@ -256,7 +256,7 @@ public void onGameTick(GameTick event) public void setupSteps() { // Travel to Fairy Ring - travelFairyRing = new ObjectStep(this, ObjectID.POH_FAIRY_RING, new WorldPoint(2658, 3230, 0), + travelFairyRing = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, new WorldPoint(2658, 3230, 0), "Travel from any fairy ring to south of Mount Karuulm (CIR).", dramenStaff.highlighted()); // Kill a lizardman diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java index 5b15a57d47e..6b380f2a13d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java @@ -46,7 +46,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; @@ -289,7 +293,6 @@ public List getItemRecommended() public List getGeneralRequirements() { List reqs = new ArrayList<>(); - reqs.add(new SkillRequirement(Skill.AGILITY, 10, true)); reqs.add(new SkillRequirement(Skill.FIREMAKING, 15, true)); reqs.add(new SkillRequirement(Skill.FISHING, 15, true)); reqs.add(new SkillRequirement(Skill.MINING, 15, true)); @@ -332,8 +335,7 @@ public List getPanels() { List allSteps = new ArrayList<>(); - PanelDetails draynorRooftopsSteps = new PanelDetails("Draynor Rooftops", Collections.singletonList(drayAgi), - new SkillRequirement(Skill.AGILITY, 10, true)); + PanelDetails draynorRooftopsSteps = new PanelDetails("Draynor Rooftops", Collections.singletonList(drayAgi)); draynorRooftopsSteps.setDisplayCondition(notDrayAgi); draynorRooftopsSteps.setLockingStep(drayAgiTask); allSteps.add(draynorRooftopsSteps); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java index 20ddcfdeafa..6e500500299 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java index 8936535a4cb..ad2e31c1844 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java @@ -29,6 +29,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.ComplexRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; @@ -291,15 +292,16 @@ public List getGeneralRequirements() if (questHelperPlugin.getPlayerStateManager().getAccountType().isAnyIronman()) { - // 47 Farming is required to get a Watermelon for the scarecrow step - reqs.add(new SkillRequirement(Skill.FARMING, 47, true)); + // 47 Farming or completion of Troubled Tortugans is required to get a Watermelon for the scarecrow step + reqs.add(new ComplexRequirement(LogicType.OR, "47 Farming OR Finished Troubled Tortugans for a watermelon", + new QuestRequirement(QuestHelperQuest.TROUBLED_TORTUGANS, QuestState.FINISHED), + new SkillRequirement(Skill.FARMING, 47, true))); } else { reqs.add(new SkillRequirement(Skill.FARMING, 23, true)); } - reqs.add(ghostsAhoy); reqs.add(natureSpirit); return reqs; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java index 0645bf64be9..c723aed03f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java @@ -48,7 +48,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java index 7e2fdc8a675..837d16db63c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java @@ -172,7 +172,7 @@ protected void setupRequirements() steelBar = new ItemRequirement("Steel bar", ItemID.STEEL_BAR).showConditioned(notCannonBall); ammoMould = new ItemRequirement("Ammo mould", ItemID.AMMO_MOULD).showConditioned(notCannonBall).isNotConsumed(); ammoMould.addAlternates(ItemID.DOUBLE_AMMO_MOULD); - slayerGloves = new ItemRequirement("Slayer gloves", ItemID.SLAYERGUIDE_SLAYER_GLOVES).showConditioned(notFeverSpider).isNotConsumed(); + slayerGloves = new ItemRequirement("Slayer gloves", ItemID.DEAL_SLAYER_GLOVES).showConditioned(notFeverSpider).isNotConsumed(); ectophial = new ItemRequirement("Ectophial", ItemID.ECTOPHIAL).showConditioned(notEctophialTP).isNotConsumed(); restorePot = new ItemRequirement("Restore potion (4)", ItemID._4DOSESTATRESTORE).showConditioned(notGuthBalance); garlic = new ItemRequirement("Garlic", ItemID.GARLIC).showConditioned(notGuthBalance); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java index c7926e29559..fd66e8f4e94 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java @@ -48,7 +48,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java index b87bae14cd1..1dc7c98cb64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java @@ -55,6 +55,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; public class WesternMedium extends ComplexStateQuestHelper { @@ -136,8 +137,8 @@ public QuestStep loadStep() doMedium.addStep(notApeBass, apeBassTask); apeTeakTask = new ConditionalStep(this, moveToApeTeak); + apeTeakTask.addStep(and(inApeAtoll, teakLogs, choppedLogs), apeTeakBurn); apeTeakTask.addStep(inApeAtoll, apeTeakChop); - apeTeakTask.addStep(new Conditions(inApeAtoll, teakLogs, choppedLogs), apeTeakBurn); doMedium.addStep(notApeTeak, apeTeakTask); interPestTask = new ConditionalStep(this, moveToPest); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java index 13b83d76d8e..2a139a97e84 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java @@ -47,7 +47,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java index acdae9c6d68..7bac94818ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java @@ -36,7 +36,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; import net.runelite.api.Client; import net.runelite.api.coords.WorldPoint; - import java.util.Map; public class ChartingConditionalStep extends ReorderableConditionalStep diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java index 4677c3d31cb..d8f70bd858d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java @@ -24,22 +24,32 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; -import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.*; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingCaveTelescopeStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingCrateStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingCurrentStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingDivingStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingGenericObjectStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingPuzzleWrapStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingTaskStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingTelescopeStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingWeatherStep; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.TopLevelPanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.questinfo.HelperConfig; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.StepIsActiveRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.plugins.microbot.questhelper.questinfo.HelperConfig; import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.gameval.VarbitID; - -import java.util.*; - +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; public class ChartingHelper extends ComplexStateQuestHelper diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java index f8a3c231abf..914c86de2e0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java @@ -25,7 +25,6 @@ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; import lombok.Getter; - import java.util.List; @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java index f9d1a59a7c7..184d0d495c1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java @@ -24,10 +24,9 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import lombok.Getter; import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; - import java.util.ArrayList; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java index 5d6779ea15a..8797e96b5b5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java @@ -24,13 +24,12 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.VarbitID; +import java.util.List; import net.runelite.client.plugins.microbot.questhelper.requirements.sailing.BoatResistanceType; import net.runelite.client.plugins.microbot.questhelper.requirements.sailing.HasBoatResistanceRequirement; - -import java.util.List; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.coords.WorldPoint; // All data generated from the OSRS Wiki (https://oldschool.runescape.wiki/w/Sea_charting) public final class ChartingTasksData @@ -369,7 +368,7 @@ private ChartingTasksData() )), new ChartingSeaSection(27, "Mythic Sea", List.of( new ChartingTaskDefinition(ChartingType.CRATE, "Find a Sealed crate west of the Void Knights' Outpost and sample the contents.", new WorldPoint(2556, 2664, 0), "Shrouded Ocean", 12, VarbitID.SAILING_CHARTING_DRINK_CRATE_MYTHS_MIXER_COMPLETE, ItemID.SAILING_CHARTING_DRINK_CRATE_MYTHS_MIXER), - new ChartingTaskDefinition(ChartingType.GENERIC, "Find an abandoned camp on Anglers' Retreat. Watch out for Fetid waters!", new WorldPoint(2476, 2707, 0), "Shrouded Ocean", 1, VarbitID.SAILING_CHARTING_GENERIC_ABANDONED_CAMP_COMPLETE), + new ChartingTaskDefinition(ChartingType.GENERIC, "Find an abandoned camp on Anglers' Retreat. Watch out for Fetid waters!", new WorldPoint(2476, 2707, 0), "Shrouded Ocean", 51, VarbitID.SAILING_CHARTING_GENERIC_ABANDONED_CAMP_COMPLETE), new ChartingTaskDefinition(ChartingType.CURRENT, "Test the currents east of Anglers' Retreat. Watch out for Fetid waters!", new WorldPoint(2495, 2708, 0), new WorldPoint(2533, 2736, 0), "Shrouded Ocean", 40, VarbitID.SAILING_CHARTING_CURRENT_DUCK_MYTHIC_SEA_COMPLETE), new ChartingTaskDefinition(ChartingType.DIVING, "With help from a mermaid guide, document the water depth south of the Myths' Guild. Watch out for Fetid waters!", new WorldPoint(2446, 2784, 0), "Shrouded Ocean", 40, VarbitID.SAILING_CHARTING_MERMAID_GUIDE_MYTHIC_SEA_COMPLETE, "The answer is 'Cabbage', 'Onion', 'Tomato'.", List.of(ItemID.CABBAGE, ItemID.ONION, ItemID.TOMATO)) )), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java index 2f66459c73c..bed74d39369 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java @@ -33,12 +33,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import lombok.Getter; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ObjectID; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java index 2acbeaf1410..a5c4aad951b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java @@ -32,8 +32,9 @@ import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class ChartingCrateStep extends ChartingTaskObjectStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java index d5d56dda2b5..922868da909 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java @@ -28,13 +28,15 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class ChartingCurrentStep extends ChartingTaskObjectStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java index 1ba16f7b9ff..b545e6665d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java @@ -27,8 +27,11 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.ChartingTaskDefinition; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.api.GameObject; import net.runelite.api.TileObject; +import net.runelite.api.gameval.ItemID; +import java.util.List; // This is a lazy implementation where we fully trust the location of the object to only have one thing to work public class ChartingGenericObjectStep extends ChartingTaskObjectStep diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java index 98acdc3aa09..6cc8bde879c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java @@ -33,7 +33,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; public class ChartingPuzzleWrapStep extends PuzzleWrapperStep implements ChartingTaskInterface diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java index 0bf8cd55f71..947902f6993 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java @@ -33,9 +33,9 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import lombok.Getter; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; @Getter public class ChartingTaskNpcStep extends NpcStep implements ChartingTaskInterface diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java index 8af4bd4a3ac..33bbbd54770 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java @@ -33,7 +33,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import lombok.Getter; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java index 03e2b5bf212..ed442ca0340 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java @@ -33,7 +33,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import lombok.Getter; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java index c8e77aa44c8..7e977883af1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java @@ -33,6 +33,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import lombok.Getter; import net.runelite.api.Skill; import net.runelite.api.gameval.ItemID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java index 61100712b4c..cf2ee0242f2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java @@ -24,13 +24,11 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.alfredgrimhandsbarcrawl; - import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,59 +38,74 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarPlayerID; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - public class AlfredGrimhandsBarcrawl extends ComplexStateQuestHelper { - //Items Required - ItemRequirement coins208, coins50, coins10, coins70, coins8, coins7, coins15, coins18, coins12, barcrawlCard; - - //Items Recommended - ItemRequirement gamesNecklace, varrockTeleport, faladorTeleport, glory, ardougneTeleport, camelotTeleport, - duelingRing; - - Requirement notTalkedToGuard, notTalkedToBlueMoon, notTalkedToJollyBoar, notTalkedToRisingSun, - notTalkedToRustyAnchor, - notTalkedToZambo, notTalkedToDeadMansChest, notTalkedToFlyingHorseInn, notTalkedToForestersArms, notTalkedToBlurberry, - notTalkedToDragonInn, inGrandTreeF1; - - QuestStep talkToGuardToGetCard, talkToBlueMoon, talkToJollyBoar, talkToRisingSun, talkToRustyAnchor, talkToZambo, - talkToDeadMansChest, talkToFlyingHorseInn, talkToForestersArms, goUpToBlurberry, talkToBlurberry, - talkToDragonInn, talkToGuardAgain; - - //Zones + // Required items + ItemRequirement coins208; + + // Recommended items + ItemRequirement gamesNecklace; + ItemRequirement varrockTeleport; + ItemRequirement lumberyardTeleport; + ItemRequirement faladorTeleport; + ItemRequirement glory; + ItemRequirement ardougneTeleport; + ItemRequirement camelotTeleport; + ItemRequirement duelingRing; + + // Mid-quest item requirements + ItemRequirement coins50; + ItemRequirement coins10; + ItemRequirement coins70; + ItemRequirement coins8; + ItemRequirement coins7; + ItemRequirement coins15; + ItemRequirement coins18; + ItemRequirement coins12; + ItemRequirement barcrawlCard; + + // Zones Zone grandTreeF1; - @Override - public QuestStep loadStep() - { - initializeRequirements(); - setupZones(); - setupConditions(); - setupSteps(); + // Miscellaneous requirements + VarplayerRequirement notTalkedToGuard; + VarplayerRequirement notTalkedToBlueMoon; + VarplayerRequirement notTalkedToJollyBoar; + VarplayerRequirement notTalkedToRisingSun; + VarplayerRequirement notTalkedToRustyAnchor; + VarplayerRequirement notTalkedToZambo; + VarplayerRequirement notTalkedToDeadMansChest; + VarplayerRequirement notTalkedToFlyingHorseInn; + VarplayerRequirement notTalkedToForestersArms; + VarplayerRequirement notTalkedToBlurberry; + VarplayerRequirement notTalkedToDragonInn; + ZoneRequirement inGrandTreeF1; + + // Steps + NpcStep talkToGuardToGetCard; + NpcStep talkToBlueMoon; + NpcStep talkToJollyBoar; + NpcStep talkToRisingSun; + NpcStep talkToRustyAnchor; + NpcStep talkToZambo; + NpcStep talkToDeadMansChest; + NpcStep talkToFlyingHorseInn; + NpcStep talkToForestersArms; + ObjectStep goUpToBlurberry; + NpcStep talkToBlurberry; + NpcStep talkToDragonInn; + NpcStep talkToGuardAgain; - ConditionalStep barcrawl = new ConditionalStep(this, talkToGuardAgain); - barcrawl.addStep(notTalkedToGuard, talkToGuardToGetCard); - barcrawl.addStep(notTalkedToBlueMoon, talkToBlueMoon); - barcrawl.addStep(notTalkedToJollyBoar, talkToJollyBoar); - barcrawl.addStep(notTalkedToRisingSun, talkToRisingSun); - barcrawl.addStep(notTalkedToRustyAnchor, talkToRustyAnchor); - barcrawl.addStep(notTalkedToZambo, talkToZambo); - barcrawl.addStep(notTalkedToDeadMansChest, talkToDeadMansChest); - barcrawl.addStep(notTalkedToFlyingHorseInn, talkToFlyingHorseInn); - barcrawl.addStep(notTalkedToForestersArms, talkToForestersArms); - barcrawl.addStep(new Conditions(notTalkedToBlurberry, inGrandTreeF1), talkToBlurberry); - barcrawl.addStep(notTalkedToBlurberry, goUpToBlurberry); - barcrawl.addStep(notTalkedToDragonInn, talkToDragonInn); - - return barcrawl; + public void setupZones() + { + grandTreeF1 = new Zone(new WorldPoint(2437, 3474, 1), new WorldPoint(2493, 3511, 1)); } @Override @@ -110,6 +123,8 @@ protected void setupRequirements() gamesNecklace = new ItemRequirement("Games necklace", ItemCollections.GAMES_NECKLACES); varrockTeleport = new ItemRequirement("Varrock teleport", ItemID.POH_TABLET_VARROCKTELEPORT); + lumberyardTeleport = new ItemRequirement("Lumberyard teleport", ItemID.TELEPORTSCROLL_LUMBERYARD); + lumberyardTeleport.addAlternates(ItemID.RING_OF_ELEMENTS_CHARGED); faladorTeleport = new ItemRequirement("Falador teleport", ItemID.POH_TABLET_FALADORTELEPORT); glory = new ItemRequirement("Amulet of Glory", ItemCollections.AMULET_OF_GLORIES).isNotConsumed(); ardougneTeleport = new ItemRequirement("Ardougne teleport", ItemID.POH_TABLET_ARDOUGNETELEPORT); @@ -118,15 +133,6 @@ protected void setupRequirements() barcrawlCard = new ItemRequirement("Barcrawl card", ItemID.BARCRAWL_CARD); barcrawlCard.setTooltip("If you've lost it you can get another from the Barbarian Guard"); - } - - public void setupZones() - { - grandTreeF1 = new Zone(new WorldPoint(2437, 3474, 1), new WorldPoint(2493, 3511, 1)); - } - - public void setupConditions() - { inGrandTreeF1 = new ZoneRequirement(grandTreeF1); notTalkedToGuard = new VarplayerRequirement(VarPlayerID.BARCRAWL, false, 0); @@ -144,65 +150,89 @@ public void setupConditions() public void setupSteps() { - talkToGuardToGetCard = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), - "Talk to a barbarian guard outside the Barbarian Agility Course."); - talkToGuardToGetCard.addDialogSteps("I want to come through this gate.", - "Looks can be deceiving, I am in fact a barbarian."); - + talkToGuardToGetCard = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), "Talk to a barbarian guard outside the Barbarian Agility Course at the Barbarian Outpost to learn about Alfred Grimhand's Barcrawl."); + talkToGuardToGetCard.addDialogSteps("I want to come through this gate.", "Looks can be deceiving, I am in fact a barbarian."); - talkToBlueMoon = new NpcStep(this, NpcID.BLUEMOON_BARTENDER, new WorldPoint(3226, 3399, 0), - "Talk to the bartender in the Blue Moon Inn in Varrock.", coins50); + talkToBlueMoon = new NpcStep(this, NpcID.BLUEMOON_BARTENDER, new WorldPoint(3226, 3399, 0), "Talk to the bartender in the Blue Moon Inn in Varrock.", coins50); talkToBlueMoon.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToJollyBoar = new NpcStep(this, NpcID.JOLLYBOAR_BARTENDER, new WorldPoint(3279, 3488, 0), - "Talk to the bartender in the Jolly Boar Inn north east of Varrock.", coins10); + talkToJollyBoar = new NpcStep(this, NpcID.JOLLYBOAR_BARTENDER, new WorldPoint(3279, 3488, 0), "Talk to the bartender in the Jolly Boar Inn north east of Varrock.", coins10); + talkToJollyBoar.addTeleport(lumberyardTeleport); talkToJollyBoar.addDialogStep("I'm doing Alfred Grimhands Barcrawl."); - talkToRisingSun = new NpcStep(this, NpcID.RISINGSUN_BARMAID2, new WorldPoint(2956, 3370, 0), - "Talk to a bartender in the Rising Sun Inn in Falador.", true, coins70); + talkToRisingSun = new NpcStep(this, NpcID.RISINGSUN_BARMAID2, new WorldPoint(2956, 3370, 0), "Talk to a bartender in the Rising Sun Inn in Falador.", true, coins70); talkToRisingSun.addDialogStep("I'm doing Alfred Grimhand's barcrawl."); - ((NpcStep) talkToRisingSun).addAlternateNpcs(NpcID.RISINGSUN_BARMAID, NpcID.RISINGSUN_BARMAID3); + talkToRisingSun.addAlternateNpcs(NpcID.RISINGSUN_BARMAID, NpcID.RISINGSUN_BARMAID3); - talkToRustyAnchor = new NpcStep(this, NpcID.RUSTYANCHOR_BARTENDER, new WorldPoint(3046, 3257, 0), - "Talk to the bartender in the Rusty Anchor in Port Sarim.", coins8); + talkToRustyAnchor = new NpcStep(this, NpcID.RUSTYANCHOR_BARTENDER, new WorldPoint(3046, 3257, 0), "Talk to the bartender in the Rusty Anchor in Port Sarim.", coins8); talkToRustyAnchor.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToZambo = new NpcStep(this, NpcID.ZEMBO, new WorldPoint(2927, 3144, 0), - "Talk to Zembo in the Karamja Spirits Bar on Musa Point.", coins7); + + talkToZambo = new NpcStep(this, NpcID.ZEMBO, new WorldPoint(2927, 3144, 0), "Talk to Zembo in the Karamja Spirits Bar on Musa Point.", coins7); talkToZambo.addDialogStep("I'm doing Alfred Grimhand's barcrawl."); - talkToDeadMansChest = new NpcStep(this, NpcID.DEADMANS_BARTENDER, new WorldPoint(2796, 3156, 0), - "Talk to the bartender in the Dead Man's Chest in Brimhaven.", coins15); + + talkToDeadMansChest = new NpcStep(this, NpcID.DEADMANS_BARTENDER, new WorldPoint(2796, 3156, 0), "Talk to the bartender in the Dead Man's Chest in Brimhaven.", coins15); talkToDeadMansChest.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToFlyingHorseInn = new NpcStep(this, NpcID.FLYINGHORSE_BARTENDER, new WorldPoint(2574, 3323, 0), - "Talk to the bartender in the Flying Horse Inn in Ardougne.", coins8); + + talkToFlyingHorseInn = new NpcStep(this, NpcID.FLYINGHORSE_BARTENDER, new WorldPoint(2574, 3323, 0), "Talk to the bartender in the Flying Horse Inn in Ardougne.", coins8); talkToFlyingHorseInn.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToForestersArms = new NpcStep(this, NpcID.FORESTERS_BARTENDER, new WorldPoint(2690, 3494, 0), - "Talk to the bartender in the Forester's Arms in Seers' Village.", coins18); + + talkToForestersArms = new NpcStep(this, NpcID.FORESTERS_BARTENDER, new WorldPoint(2690, 3494, 0), "Talk to the bartender in the Forester's Arms in Seers' Village.", coins18); talkToForestersArms.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - goUpToBlurberry = new ObjectStep(this, QHObjectID.GRAND_TREE_F0_LADDER, new WorldPoint(2466, 3495, 0), - "Talk to Blurberry in the Grand Tree.", coins10); - talkToBlurberry = new NpcStep(this, NpcID.BLURBERRY, new WorldPoint(2482, 3491, 1), - "Talk to Blurberry in the Grand Tree.", coins10); + goUpToBlurberry = new ObjectStep(this, QHObjectID.GRAND_TREE_F0_LADDER, new WorldPoint(2466, 3495, 0), "Talk to Blurberry in the Grand Tree.", coins10); + talkToBlurberry = new NpcStep(this, NpcID.BLURBERRY, new WorldPoint(2482, 3491, 1), "Talk to Blurberry in the Grand Tree.", coins10); talkToBlurberry.addSubSteps(goUpToBlurberry); - talkToDragonInn = new NpcStep(this, NpcID.DRAGON_BARTENDER, new WorldPoint(2556, 3079, 0), - "Talk to the bartender in Dragon Inn in Yanille.", coins12); + + talkToDragonInn = new NpcStep(this, NpcID.DRAGON_BARTENDER, new WorldPoint(2556, 3079, 0), "Talk to the bartender in Dragon Inn in Yanille.", coins12); talkToDragonInn.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToGuardAgain = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), - "Return to the barbarian guards outside the Barbarian Agility Course."); + talkToGuardAgain = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), "Return to the barbarian guards outside the Barbarian Agility Course."); + } + + @Override + public QuestStep loadStep() + { + initializeRequirements(); + setupSteps(); + + var barcrawl = new ConditionalStep(this, talkToGuardAgain); + barcrawl.addStep(notTalkedToGuard, talkToGuardToGetCard); + barcrawl.addStep(notTalkedToBlueMoon, talkToBlueMoon); + barcrawl.addStep(notTalkedToJollyBoar, talkToJollyBoar); + barcrawl.addStep(notTalkedToRisingSun, talkToRisingSun); + barcrawl.addStep(notTalkedToRustyAnchor, talkToRustyAnchor); + barcrawl.addStep(notTalkedToZambo, talkToZambo); + barcrawl.addStep(notTalkedToDeadMansChest, talkToDeadMansChest); + barcrawl.addStep(notTalkedToFlyingHorseInn, talkToFlyingHorseInn); + barcrawl.addStep(notTalkedToForestersArms, talkToForestersArms); + barcrawl.addStep(and(notTalkedToBlurberry, inGrandTreeF1), talkToBlurberry); + barcrawl.addStep(notTalkedToBlurberry, goUpToBlurberry); + barcrawl.addStep(notTalkedToDragonInn, talkToDragonInn); + + return barcrawl; } @Override public List getItemRequirements() { - return List.of(coins208); + return List.of( + coins208 + ); } @Override public List getItemRecommended() { - return List.of(gamesNecklace, varrockTeleport, faladorTeleport, glory, ardougneTeleport, - camelotTeleport, duelingRing); + return List.of( + gamesNecklace, + varrockTeleport, + lumberyardTeleport, + faladorTeleport, + glory, + ardougneTeleport, + camelotTeleport, + duelingRing + ); } @Override @@ -217,14 +247,29 @@ public List getUnlockRewards() @Override public ArrayList getPanels() { - var allSteps = new ArrayList(); - - allSteps.add(new PanelDetails("Getting started", List.of(talkToGuardToGetCard))); - - allSteps.add(new PanelDetails("Drinking", Arrays.asList(talkToBlueMoon, talkToJollyBoar, talkToRisingSun, - talkToRustyAnchor, talkToZambo, talkToDeadMansChest, talkToFlyingHorseInn, talkToForestersArms, talkToBlurberry, - talkToDragonInn, talkToGuardAgain), barcrawlCard, coins208)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Getting started", List.of( + talkToGuardToGetCard + ))); + + sections.add(new PanelDetails("Drinking", List.of( + talkToBlueMoon, + talkToJollyBoar, + talkToRisingSun, + talkToRustyAnchor, + talkToZambo, + talkToDeadMansChest, + talkToFlyingHorseInn, + talkToForestersArms, + talkToBlurberry, + talkToDragonInn, + talkToGuardAgain + ), List.of( + barcrawlCard, + coins208 + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java index 0179424eb5e..e41e977228a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java @@ -26,33 +26,26 @@ import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.config.ConfigKeys; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import net.runelite.client.plugins.microbot.questhelper.requirements.ChatMessageRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.MesBoxRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.MultiChatMessageRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -61,49 +54,143 @@ public class BarbarianTraining extends BasicQuestHelper { // Items Required - ItemRequirement barbFishingRod, tinderbox, bow, knife, fish, combatGear, antifireShield, chewedBones, bronzeBar, logs, hammer, - roe, attackPotion, sapling, seed, spade, oakLogs, axe, feathers, barbarianAttackPotion; + ItemRequirement barbFishingRod; + ItemRequirement tinderbox; + ItemRequirement bow; + ItemRequirement knife; + ItemRequirement fish; + ItemRequirement combatGear; + ItemRequirement antifireShield; + ItemRequirement chewedBones; + ItemRequirement bronzeBar; + ItemRequirement logs; + ItemRequirement hammer; + ItemRequirement roe; + ItemRequirement attackPotion; + ItemRequirement sapling; + ItemRequirement seed; + ItemRequirement spade; + ItemRequirement oakLogs; + ItemRequirement axe; + ItemRequirement feathers; + ItemRequirement barbarianAttackPotion; // Items recommended - ItemRequirement gamesNecklace, catherbyTeleport; - - Requirement fishing48, agility15, strength15, fishing55, strength35, firemaking35, crafting11, farming15, smithing5; - - QuestRequirement druidicRitual, taiBwoWannaiTrio; - - Requirement taskedWithFishing, taskedWithHarpooning, taskedWithFarming, taskedWithBowFiremaking, taskedWithPyre, taskedWithPotSmashing, - taskedWithSpears, taskedWithHastae, taskedWithHerblore; + ItemRequirement gamesNecklace; + ItemRequirement catherbyTeleport; + + Requirement fishing48; + Requirement agility15; + Requirement strength15; + Requirement fishing55; + Requirement strength35; + Requirement firemaking35; + Requirement crafting11; + Requirement farming15; + Requirement smithing5; + + QuestRequirement druidicRitual; + QuestRequirement taiBwoWannaiTrio; Requirement chewedBonesNearby; - Requirement plantedSeed, smashedPot, litFireWithBow, sacrificedRemains, caughtBarbarianFish, - caughtFishWithoutHarpoon, madePotion, madeSpear, madeHasta; - - DetailedQuestStep talkToOttoAboutFishing, searchBed, catchFish, talkToOttoAfterFish; - - DetailedQuestStep talkToOttoAboutBarehanded, fishHarpoon, talkToOttoAfterHarpoon; - - DetailedQuestStep talkToOttoAboutBow, lightLogWithBow, talkToOttoAfterBow; - - DetailedQuestStep talkToOttoAboutPyre, enterWhirlpool, goDownToBrutalGreen, goUpToMithrilDragons, killMithrilDragons, - pickupChewedBones, useLogOnPyre, talkToOttoAfterPyre; - - DetailedQuestStep talkToOttoAboutFarming, plantSeed, talkToOttoAfterPlantingSeed; - - DetailedQuestStep talkToOttoAboutPots, plantSapling, talkToOttoAfterSmashingPot; - - DetailedQuestStep talkToOttoAboutSpears, makeBronzeSpear, talkToOttoAfterBronzeSpear, talkToOttoAboutHastae, makeBronzeHasta, talkToOttoAfterMakingHasta; - - DetailedQuestStep talkToOttoAboutHerblore, getBarbRodForHerblore, fishForHerblore, dissectFish, useRoeOnAttackPotion, talkToOttoAfterPotion; - - ConditionalStep fishingSteps, harpoonSteps, seedSteps, potSmashingSteps, firemakingSteps, pyreSteps, spearSteps, - spearAndHastaeSteps, herbloreSteps; - - Requirement finishedFishing, finishedHarpoon, finishedSeedPlanting, finishedPotSmashing, finishedFiremaking, finishedPyre, finishedSpear, finishedHasta, finishedHerblore; - - Zone ancientCavernF0, ancientCavernF1, ancientCavernArrivalRoom; - - ZoneRequirement inAncientCavernF0, inAncientCavernF1, inAncientCavernArrivalRoom; + DetailedQuestStep talkToOttoAboutFishing; + DetailedQuestStep searchBed; + DetailedQuestStep catchFish; + DetailedQuestStep talkToOttoAfterFish; + + DetailedQuestStep talkToOttoAboutBarehanded; + DetailedQuestStep fishHarpoon; + DetailedQuestStep talkToOttoAfterHarpoon; + + DetailedQuestStep talkToOttoAboutBow; + DetailedQuestStep lightLogWithBow; + DetailedQuestStep talkToOttoAfterBow; + + DetailedQuestStep talkToOttoAboutPyre; + DetailedQuestStep enterWhirlpool; + DetailedQuestStep goDownToBrutalGreen; + DetailedQuestStep goUpToMithrilDragons; + DetailedQuestStep killMithrilDragons; + DetailedQuestStep pickupChewedBones; + DetailedQuestStep useLogOnPyre; + DetailedQuestStep talkToOttoAfterPyre; + + DetailedQuestStep talkToOttoAboutFarming; + DetailedQuestStep plantSeed; + DetailedQuestStep talkToOttoAfterPlantingSeed; + + DetailedQuestStep talkToOttoAboutPots; + DetailedQuestStep plantSapling; + DetailedQuestStep talkToOttoAfterSmashingPot; + + DetailedQuestStep talkToOttoAboutSpears; + DetailedQuestStep makeBronzeSpear; + DetailedQuestStep talkToOttoAfterBronzeSpear; + DetailedQuestStep talkToOttoAboutHastae; + DetailedQuestStep makeBronzeHasta; + DetailedQuestStep talkToOttoAfterMakingHasta; + + DetailedQuestStep talkToOttoAboutHerblore; + DetailedQuestStep getBarbRodForHerblore; + DetailedQuestStep fishForHerblore; + DetailedQuestStep dissectFish; + DetailedQuestStep useRoeOnAttackPotion; + DetailedQuestStep talkToOttoAfterPotion; + + ConditionalStep fishingSteps; + ConditionalStep harpoonSteps; + ConditionalStep seedSteps; + ConditionalStep potSmashingSteps; + ConditionalStep firemakingSteps; + ConditionalStep pyreSteps; + ConditionalStep spearSteps; + ConditionalStep spearAndHastaeSteps; + ConditionalStep herbloreSteps; + + Zone ancientCavernF0; + Zone ancientCavernF1; + Zone ancientCavernArrivalRoom; + + ZoneRequirement inAncientCavernF0; + ZoneRequirement inAncientCavernF1; + ZoneRequirement inAncientCavernArrivalRoom; + + VarbitRequirement taskedWithFishing; + VarbitRequirement caughtBarbarianFish; + VarbitRequirement finishedFishing; + + VarbitRequirement taskedWithHerblore; + VarbitRequirement madePotion; + VarbitRequirement finishedHerblore; + + VarbitRequirement taskedWithHarpooning; + VarbitRequirement caughtFishWithoutHarpoon; + VarbitRequirement finishedHarpoon; + + VarbitRequirement taskedWithFarming; + VarbitRequirement plantedSeed; + VarbitRequirement finishedSeedPlanting; + + VarbitRequirement taskedWithPotSmashing; + VarbitRequirement smashedPot; + VarbitRequirement finishedPotSmashing; + + VarbitRequirement taskedWithBowFiremaking; + VarbitRequirement litFireWithBow; + VarbitRequirement finishedFiremaking; + + VarbitRequirement taskedWithSpears; + VarbitRequirement madeSpear; + VarbitRequirement finishedSpear; + + VarbitRequirement taskedWithHastae; + VarbitRequirement madeHasta; + VarbitRequirement finishedHasta; + + VarbitRequirement taskedWithPyre; + VarbitRequirement sacrificedRemains; + VarbitRequirement finishedPyre; @Override public Map loadSteps() @@ -189,13 +276,10 @@ public Map loadSteps() allSteps.addDialogSteps("Let's talk about my training.", "I seek more knowledge."); allSteps.setCheckAllChildStepsOnListenerCall(true); - - // Started, 9613 + // Controlled by VarbitID.BRUT_MINIQUEST, specifying the number of miniquests completed steps.put(0, allSteps); steps.put(1, allSteps); - // Increments after doing a task steps.put(2, allSteps); - // 9610, 0->1 at some point??? Probably for pot smashing, or for whirlpool? steps.put(3, allSteps); steps.put(4, allSteps); steps.put(5, allSteps); @@ -259,281 +343,64 @@ public void setupRequirements() crafting11 = new SkillRequirement(Skill.CRAFTING, 11); farming15 = new SkillRequirement(Skill.FARMING, 15, true); smithing5 = new SkillRequirement(Skill.SMITHING, 5, true); + + var barbFishing = new VarbitBuilder(VarbitID.BRUT_FISHING_R); + taskedWithFishing = barbFishing.eq(1); + caughtBarbarianFish = barbFishing.eq(2); + finishedFishing = barbFishing.eq(3); + finishedFishing.setDisplayText("Finished Barbarian Fishing"); + + var barbHerblore = new VarbitBuilder(VarbitID.BRUT_HERB_POTION); + taskedWithHerblore = barbHerblore.eq(1); + madePotion = barbHerblore.eq(2); + finishedHerblore = barbHerblore.eq(3); + finishedHerblore.setDisplayText("Finished Barbarian Herblore"); + + var barbHarpooning = new VarbitBuilder(VarbitID.BRUT_FISHING_S); + taskedWithHarpooning = barbHarpooning.eq(1); + caughtFishWithoutHarpoon = barbHarpooning.eq(2); + finishedHarpoon = barbHarpooning.eq(3); + finishedHarpoon.setDisplayText("Finished Barbarian Harpooning"); + + var barbPlanting = new VarbitBuilder(VarbitID.BRUT_FARMING_PLANTING); + taskedWithFarming = barbPlanting.eq(1); + plantedSeed = barbPlanting.eq(2); + finishedSeedPlanting = barbPlanting.eq(3); + finishedSeedPlanting.setDisplayText("Finished Barbarian Planting"); + + var barbPotSmashing = new VarbitBuilder(VarbitID.BRUT_FARMING_SMASHING); + taskedWithPotSmashing = barbPotSmashing.eq(1); + smashedPot = barbPotSmashing.eq(2); + finishedPotSmashing = barbPotSmashing.eq(3); + finishedPotSmashing.setDisplayText("Finished Barbarian Pot Smashing"); + + var barbFiremaking = new VarbitBuilder(VarbitID.BRUT_FIRE); + taskedWithBowFiremaking = barbFiremaking.eq(1); + litFireWithBow = barbFiremaking.eq(2); + finishedFiremaking = barbFiremaking.eq(3); + finishedFiremaking.setDisplayText("Finished Barbarian Firemaking"); + + var barbSpear = new VarbitBuilder(VarbitID.BRUT_SMITH_SPEAR); + taskedWithSpears = barbSpear.eq(1); + madeSpear = barbSpear.eq(2); + finishedSpear = barbSpear.eq(3); + finishedSpear.setDisplayText("Finished Barbarian Spear Smithing"); + + var barbHasta = new VarbitBuilder(VarbitID.BRUT_SMITH_HASTA); + taskedWithHastae = barbHasta.eq(1); + madeHasta = barbHasta.eq(2); + finishedHasta = barbHasta.eq(3); + finishedHasta.setDisplayText("Finished Barbarian Hastae Smithing"); + + var barbPyre = new VarbitBuilder(VarbitID.BRUT_CRAFT_SHIP); + taskedWithPyre = barbPyre.eq(1); + sacrificedRemains = barbPyre.eq(2); + finishedPyre = barbPyre.eq(3); + finishedPyre.setDisplayText("Finished Barbarian Pyremaking"); } public void setupConditions() { - // Started tasks - - taskedWithFishing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Certainly. Take the rod from under my bed and fish in the lake. When you have caught a few fish, I am sure you will be ready to talk more with me."), - new DialogRequirement("Alas, I do not sense that you have been successful in your fishing yet. The look in your eyes is not that of the osprey."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with a new") - ) - ); - - taskedWithHarpooning = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("... and I thought fishing was a safe way to pass the time."), - new DialogRequirement("I see you need encouragement in learning the ways of fishing without a harpoon."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with my") - ) - ); - - taskedWithFarming = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Remember to be calm, and good luck."), - new DialogRequirement("I see you have yet to be successful in planting a seed with your fists."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "plant a seed with") - ) - ); - - taskedWithPotSmashing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("May the spirits guide you into success."), - new DialogRequirement("You have not yet attempted to plant a tree. Why not?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smash pots after") - ) - ); - - taskedWithBowFiremaking = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The spirits will aid you. The power they supply will guide your hands. Go and benefit from their guidance upon oak logs."), - new DialogRequirement("By now you know my response."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "light a fire with") - ) - ); - - taskedWithPyre = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Dive into the whirlpool in the lake to the east. The spirits will use their abilities to ensure you arrive in the correct location. Be warned, their influence fades, so you must find y"), - new DialogRequirement("I will repeat myself fully, since this is quite complex. Listen well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to create pyre ships") - ) - ); - - taskedWithHerblore = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Have I become so predictable? But yes, I do indeed require a potion. It is of the highest importance that you bring me a lesser attack potion combined with fish roe."), - new DialogRequirement("Do you have my potion?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to make a new type") - ) - ); - - taskedWithSpears = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Note well that you will require wood for the spear shafts. The quality of wood must be similar to that of the metal involved."), - new DialogRequirement("You do not exude the presence of one who has poured his soul into manufacturing spears."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smith spears") - ) - ); - - taskedWithHastae = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Indeed. You may use our special anvil for this spear type too. The ways of black and dragon hastae are beyond our knowledge, however."), - new DialogRequirement("Take some wood and metal and make a spear upon the
nearby anvil, then you may return to me. As an
example, you may use bronze bars with normal logs or
iron bars with oak logs."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, " has tasked me with learning how to smith a hasta") - ) - ); - - // Finished tasks - finishedFishing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Patience young one. These are fish which are fat with eggs rather than fat of flesh. It is these eggs that are the thing to make use of."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to catch a fish with the new rod!") - ), - "Finished Barbarian Fishing" - ); - - finishedHarpoon = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I mean that when you eventually die and find peace, at least the spirits you encounter will be your friends. Alas for you adventurous sort, the natural ways of passing are close to imp"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to fish with my hands!") - ), - "Finished Barbarian Harpooning" - ); - - finishedSeedPlanting = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("No child, but we all have potential to improve our strength."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to plant a seed with my fists!") - ), - "Finished Barbarian Seed Planting" - ); - - finishedPotSmashing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("It will become more natural with practice."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smash a plant pot without littering!") - ), - "Finished Barbarian Pot Smashing" - ); - - finishedFiremaking = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Fine news indeed!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to light a fire with a bow!") - ), - "Finished Barbarian Firemaking" - ); - - finishedPyre = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("On this great day you have my eternal thanks. May you find riches while rescuing my spiritual ancestors in the caverns for many moons to come."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a pyre ship!") - ), - "Finished Barbarian Pyremaking" - ); - - finishedSpear = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The manufacture of spears is now yours as a speciality. Use your skill well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smith a spear!") - ), - "Finished Barbarian Spear Smithing" - ); - - finishedHasta = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("To live life to it's fullest of course - that you may be a peaceful spirit when your time ends."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a hasta!") - ), - "Finished Barbarian Hasta Smithing" - ); - - finishedHerblore = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I will take that off your hands now. I will say no more than that I am eternally grateful."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a new potion!") - ), - "Finished Barbarian Herblore" - ); - - // Mid-conditions - plantedSeed = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_PLANTED_SEED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to plant a seed with my fists!") - ) - ); - - smashedPot = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_SMASHED_POT.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement(" sapling"), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smash a pot without littering!") - ) - ); - - litFireWithBow = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_BOW_FIRE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The fire catches and the logs begin to burn."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to light a fire with a bow!") - ) - ); - - sacrificedRemains = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_PYRE_MADE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The ancient barbarian is laid to rest."), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to create a pyre ship! I should let") - ) - ); - - caughtBarbarianFish = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_BARBFISHED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a leaping trout.", "You catch a leaping salmon.", "You catch a leaping sturgeon."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to catch a fish with the new rod! I should let") - ) - ); - - caughtFishWithoutHarpoon = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_HARPOONED_FISH.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a raw tuna.", "You catch a swordfish.", "You catch a shark.", "You catch a shark!"), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to fish with my hands! I should let Otto know") - ) - ); - - madePotion = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_MADE_POTION.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You combine your potion with the fish eggs."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to make a new type of potion! I should let") - ) - ); - - madeSpear = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_MADE_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" spear."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a spear!") - ) - ); - - madeHasta = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_MADE_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" hasta."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a hasta!") - ) - ); - - // For harpooning, - // You catch a tuna. - ancientCavernArrivalRoom = new Zone(new WorldPoint(1762, 5364, 1), new WorldPoint(1769, 5359, 1)); ancientCavernF0 = new Zone(new WorldPoint(1734, 5318, 0), new WorldPoint(1800, 5400, 0)); ancientCavernF1 = new Zone(new WorldPoint(1734, 5318, 1), new WorldPoint(1800, 5400, 1)); @@ -593,9 +460,9 @@ public void setupSteps() pickupChewedBones = new ItemStep(this, "Pick up the chewed bones.", chewedBones); useLogOnPyre = new ObjectStep(this, ObjectID.BRUT_BURNED_GROUND, new WorldPoint(2506, 3518, 0), "Construct a pyre on the lake near Otto.", logs, chewedBones, tinderbox, axe); - useLogOnPyre.addDialogStep("I've created a pyre ship!"); talkToOttoAfterPyre = new NpcStep(this, NpcID.BRUT_OTTO, new WorldPoint(2500, 3488, 0), "Return to Otto and tell him about the succesful pyre-making."); + talkToOttoAfterPyre.addDialogStep("I've created a pyre ship!"); // Barbarian Farming talkToOttoAboutFarming = new NpcStep(this, NpcID.BRUT_OTTO, new WorldPoint(2500, 3488, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java index 8214a77b8af..e5f22510d67 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java @@ -29,6 +29,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -38,17 +40,17 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class DaddysHome extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java index fc8e5808d25..6e49d979822 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java @@ -70,7 +70,7 @@ public Map loadSteps() protected void setupRequirements() { spade = new ItemRequirement("Spade", ItemID.SPADE).isNotConsumed(); - key = new KeyringRequirement("Enchanted key", configManager, KeyringCollection.ENCHANTED_KEY); + key = new KeyringRequirement("Enchanted key", KeyringCollection.ENCHANTED_KEY); varrockTeleports = new ItemRequirement("Varrock teleports", ItemID.POH_TABLET_VARROCKTELEPORT); ardougneTeleports = new ItemRequirement("Ardougne teleports", ItemID.POH_TABLET_ARDOUGNETELEPORT); rellekkaTeleports = new ItemRequirement("Rellekka teleport", ItemID.NZONE_TELETAB_RELLEKKA); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java index 3e6bd6e3b8a..72b02d328f7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java @@ -42,7 +42,6 @@ import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -185,7 +184,7 @@ public boolean update(final String message) return false; } - final WorldPoint localWorld = Rs2Player.getWorldLocation(); + final WorldPoint localWorld = player.getWorldLocation(); if (localWorld == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java index d145cc52d61..98e3576b6bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java @@ -43,7 +43,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Prayer; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.Arrays; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java index fc1f5000a77..35303c6638d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.themagearenai; +import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; @@ -86,7 +87,7 @@ protected void setupRequirements() { runesForCasts = new ItemRequirement("Runes for fighting Kolodion", -1, -1); runesForCasts.setDisplayItemId(ItemID.DEATHRUNE); - knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemID.KNIFE).isNotConsumed(); + knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemCollections.SLASH_WEB_KNIFE).isNotConsumed(); godCape = new ItemRequirement("God cape", ItemID.ZAMORAK_CAPE).isNotConsumed(); godCape.addAlternates(ItemID.GUTHIX_CAPE, ItemID.SARADOMIN_CAPE); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java index 320158b1352..c9585dbe4f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.themagearenaii; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; @@ -38,7 +39,9 @@ import net.runelite.api.QuestState; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; +import net.runelite.client.ui.overlay.components.PanelComponent; +import java.awt.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -46,10 +49,10 @@ public class MA2Locator extends ComplexStateQuestHelper { - ItemRequirement zamorakStaff, guthixStaff, saradominStaff, runesForCasts, magicCombatGear, knife, brews, restores + ItemRequirement zamorakStaff, guthixStaff, saradominStaff, godStaff, runesForCasts, magicCombatGear, knife, brews, restores , food, recoils, enchantedSymbol, justicarsHand, demonsHeart, entRoots, godCape; - QuestStep locateFollowerSara; + QuestStep locateFollowers; Zone cavern; @@ -59,7 +62,7 @@ public QuestStep loadStep() initializeRequirements(); setupSteps(); - return locateFollowerSara; + return locateFollowers; } @Override @@ -71,6 +74,11 @@ protected void setupRequirements() guthixStaff.setTooltip("You can buy one from the Chamber Guardian in the Mage Arena Cavern for 80k"); saradominStaff = new ItemRequirement("Saradomin staff", ItemID.SARADOMIN_STAFF); saradominStaff.setTooltip("You can buy one from the Chamber Guardian in the Mage Arena Cavern for 80k"); + + godStaff = new ItemRequirement("God staff matching boss you're killing", ItemID.SARADOMIN_STAFF); + godStaff.addAlternates(ItemID.ZAMORAK_STAFF, ItemID.GUTHIX_STAFF); + godStaff.setTooltip("You can buy one from the Chamber Guardian in the Mage Arena Cavern for 80k"); + runesForCasts = new ItemRequirements("Runes for 50+ casts of god spells", new ItemRequirement("Blood runes", ItemID.BLOODRUNE, -1), new ItemRequirement("Air runes", ItemID.AIRRUNE, -1), @@ -102,7 +110,7 @@ protected void setupZones() public void setupSteps() { - locateFollowerSara = new MageArenaBossStep(this, saradominStaff, "desired", "", + locateFollowers = new MageArenaBossStep(this, godStaff, "", enchantedSymbol, food); } @@ -146,8 +154,21 @@ public List getGeneralRequirements() public List getPanels() { List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Upgrading the God Cape", Collections.singletonList(locateFollowerSara), + allSteps.add(new PanelDetails("Upgrading the God Cape", Collections.singletonList(locateFollowers), knife, saradominStaff, guthixStaff, zamorakStaff, runesForCasts)); return allSteps; } + + @Override + public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, PanelComponent panelComponent) + { + super.renderDebugOverlay(graphics, plugin, panelComponent); + + var currentStep = this.getCurrentStep(); + if (currentStep instanceof MageArenaBossStep) + { + var bossStep = (MageArenaBossStep) currentStep; + bossStep.renderDebugOverlay(graphics, plugin, panelComponent); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java index 076b82da09d..569947a4cb0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java @@ -31,18 +31,27 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; import lombok.NonNull; import net.runelite.api.ChatMessageType; +import net.runelite.api.KeyCode; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.VarbitID; +import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -52,8 +61,11 @@ import java.awt.image.BufferedImage; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; public class MageArenaBossStep extends DetailedQuestStep @@ -77,33 +89,79 @@ public class MageArenaBossStep extends DetailedQuestStep ItemRequirement[] baseRequirements; - @Nullable - private MageArenaSolver mageArenaSolver; + private God godToFind; + + private God lastGodClicked; + + /// Set to true after the user clicks "Activate" on the MA2 Enchanted Symbol. + /// This helps ensure we don't add key and mouse listeners to unrelated dialogs. + private boolean clickedActivateOnSymbol = false; + + private final Map mageArenaSolvers = new HashMap<>(); boolean foundLocation = false; int currentVar = 0; + boolean allowChangingBoss; + + // We need this as a player can press multiple keys in the options dialog, but only the first press counts + boolean keyPressedOnce; + + /// If set, will be used when "Activate" is clicked to figure out whether it's the last option available (only a thing during MA2) + private final @Nullable VarbitRequirement finishedSaradomin; + + /// If set, will be used when "Activate" is clicked to figure out whether it's the last option available (only a thing during MA2) + private final @Nullable VarbitRequirement finishedGuthix; + + /// If set, will be used when "Activate" is clicked to figure out whether it's the last option available (only a thing during MA2) + private final @Nullable VarbitRequirement finishedZamorak; + public MageArenaBossStep(QuestHelper questHelper, ItemRequirement staff, String bossName, - String abilityDetail, ItemRequirement... requirements) + String abilityDetail, + VarbitRequirement finishedSaradomin, + VarbitRequirement finishedGuthix, + VarbitRequirement finishedZamorak, + ItemRequirement... requirements) { super(questHelper, originalTextStart + bossName + originalTextEnd, requirements); this.bossName = bossName; this.abilityDetail = abilityDetail; this.staff = staff; this.baseRequirements = requirements; + this.godToFind = God.getByName(bossName); + + this.finishedSaradomin = finishedSaradomin; + this.finishedGuthix = finishedGuthix; + this.finishedZamorak = finishedZamorak; + } + + public MageArenaBossStep(QuestHelper questHelper, ItemRequirement staff, + String abilityDetail, ItemRequirement... requirements) + { + super(questHelper, originalTextStart + "desired" + originalTextEnd, requirements); + this.bossName = "desired"; + this.abilityDetail = abilityDetail; + this.staff = staff; + this.baseRequirements = requirements; + this.allowChangingBoss = true; + this.godToFind = God.SARADOMIN; + + this.finishedSaradomin = null; + this.finishedGuthix = null; + this.finishedZamorak = null; } @Override public void makeOverlayHint(PanelComponent panelComponent, QuestHelperPlugin plugin, @NonNull List additionalText, @NonNull List additionalRequirements) { super.makeOverlayHint(panelComponent, plugin, additionalText, additionalRequirements); - if (mageArenaSolver == null) + if (mageArenaSolvers == null) { return; } - final Collection digLocations = mageArenaSolver.getPossibleLocations(); + final Collection digLocations = mageArenaSolvers.get(godToFind).getPossibleLocations(); List locations = digLocations.stream() .map(MageArenaSpawnLocation::getArea) .distinct() @@ -169,16 +227,47 @@ public void resetState() setWorldPoint(DefinedPoint.of(null)); Set locations = Arrays.stream(MageArenaSpawnLocation.values()) - .collect(Collectors.toSet()); + .collect(Collectors.toSet()); + + if (mageArenaSolvers == null) return; + + mageArenaSolvers.forEach(((god, mageArenaSolver) -> + mageArenaSolver.resetSolver(locations) + )); - if (mageArenaSolver != null) + if (mageArenaSolvers.get(godToFind).getPossibleLocations().size() == 1) { - mageArenaSolver.resetSolver(locations); + this.setWorldPoint(mageArenaSolvers.get(godToFind).getPossibleLocations().iterator().next().getWorldPoint()); } - if (mageArenaSolver.getPossibleLocations().size() == 1) + } + + @Override + public void setWorldPoint(DefinedPoint definedPoint) + { + super.setWorldPoint(definedPoint); + + if (definedPoint == null || definedPoint.getWorldPoint() == null) { - this.setWorldPoint(mageArenaSolver.getPossibleLocations().iterator().next().getWorldPoint()); + setHighlightZone(java.util.Collections.emptyList()); + return; } + + final WorldPoint worldPoint = definedPoint.getWorldPoint(); + final int maxDistance = MageArenaTemperature.SHAKING.getMaxDistance(); + + final WorldPoint minPoint = new WorldPoint( + worldPoint.getX() - maxDistance, + worldPoint.getY() - maxDistance, + worldPoint.getPlane() + ); + + final WorldPoint maxPoint = new WorldPoint( + worldPoint.getX() + maxDistance, + worldPoint.getY() + maxDistance, + worldPoint.getPlane() + ); + + setHighlightZone(new Zone(minPoint, maxPoint)); } @Override @@ -201,9 +290,130 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) OverlayUtil.renderTileOverlay(client, graphics, localLocation, getSymbolLocation(), questHelper.getConfig().targetOverlayColor()); } + @Override + public void onWidgetLoaded(WidgetLoaded widgetLoaded) + { + super.onWidgetLoaded(widgetLoaded); + if (widgetLoaded.getGroupId() != InterfaceID.CHATMENU) return; + if (!clickedActivateOnSymbol) return; + + clickedActivateOnSymbol = false; + clientThread.invokeAtTickEnd(this::addListeners); + } + + public void addListeners() + { + final AtomicInteger SARADOMIN_KC = new AtomicInteger(-1); + final AtomicInteger GUTHIX_KC = new AtomicInteger(-1); + final AtomicInteger ZAMORAK_KC = new AtomicInteger(-1); + var chatMenu = client.getWidget(InterfaceID.Chatmenu.OPTIONS); + if (chatMenu == null || chatMenu.isHidden()) return; + if (chatMenu.getChildren() == null || chatMenu.getChildren().length < 4) return; + + for (var i = 1; i < 4; ++i) + { + var button = chatMenu.getChild(i); + if (button == null) + { + return; + } + var buttonText = button.getText(); + var buttonIndex = button.getIndex(); + if ("Saradomin".equals(buttonText)) + { + button.setOnClickListener((JavaScriptCallback) ev -> { handleBossButtonClick(God.SARADOMIN); }); + if (buttonIndex == 1) SARADOMIN_KC.set(KeyCode.KC_1); + else if (buttonIndex == 2) SARADOMIN_KC.set(KeyCode.KC_2); + else if (buttonIndex == 3) SARADOMIN_KC.set(KeyCode.KC_3); + } + else if ("Guthix".equals(buttonText)) + { + button.setOnClickListener((JavaScriptCallback) ev -> {handleBossButtonClick(God.GUTHIX);}); + if (buttonIndex == 1) GUTHIX_KC.set(KeyCode.KC_1); + else if (buttonIndex == 2) GUTHIX_KC.set(KeyCode.KC_2); + else if (buttonIndex == 3) GUTHIX_KC.set(KeyCode.KC_3); + } + else if ("Zamorak".equals(buttonText)) + { + button.setOnClickListener((JavaScriptCallback) ev -> { handleBossButtonClick(God.ZAMORAK); }); + if (buttonIndex == 1) ZAMORAK_KC.set(KeyCode.KC_1); + else if (buttonIndex == 2) ZAMORAK_KC.set(KeyCode.KC_2); + else if (buttonIndex == 3) ZAMORAK_KC.set(KeyCode.KC_3); + } + } + + keyPressedOnce = false; + + chatMenu.setHasListener(true); + chatMenu.setOnKeyListener((JavaScriptCallback) ev -> { + if (keyPressedOnce) return; + keyPressedOnce = true; + var saradominKc = SARADOMIN_KC.get(); + var guthixKc = GUTHIX_KC.get(); + var zamorakKc = ZAMORAK_KC.get(); + if (saradominKc != -1 && ev.getTypedKeyCode() == saradominKc) handleBossButtonClick(God.SARADOMIN); + if (guthixKc != -1 && ev.getTypedKeyCode() == guthixKc) handleBossButtonClick(God.GUTHIX); + if (zamorakKc != -1 && ev.getTypedKeyCode() == zamorakKc) handleBossButtonClick(God.ZAMORAK); + }); + chatMenu.revalidate(); + } + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked e) + { + if (e.getItemId() == ItemID.MA2_SYMBOL && "Activate".equals(e.getMenuOption())) + { + if (finishedSaradomin != null && finishedGuthix != null && finishedZamorak != null) { + var finishedSaradomin = this.finishedSaradomin.check(client); + var finishedGuthix = this.finishedGuthix.check(client); + var finishedZamorak = this.finishedZamorak.check(client); + + if (finishedSaradomin && finishedGuthix && !finishedZamorak) + { + // User only has Zamorak left + handleBossButtonClick(God.ZAMORAK); + return; + } + + if (finishedSaradomin && !finishedGuthix && finishedZamorak) + { + // User only has Guthix left + handleBossButtonClick(God.GUTHIX); + return; + } + + if (!finishedSaradomin && finishedGuthix && finishedZamorak) + { + // User only has Saradomin left + handleBossButtonClick(God.SARADOMIN); + return; + } + } + + clickedActivateOnSymbol = true; + } + } + + private void handleBossButtonClick(God godClicked) + { + if (allowChangingBoss && godToFind != godClicked) + { + // Technically this could be set to the last wp of the previous god tracking, but that + // Seemed to cause issues sometimes so something seems wrong with that assumption + mageArenaSolvers.get(godClicked).setLastWorldPoint(null); + godToFind = godClicked; + } + else + { + lastGodClicked = godClicked; + } + } + + @Override public void onChatMessage(ChatMessage chatMessage) { + super.onChatMessage(chatMessage); + if (chatMessage.getType() == ChatMessageType.GAMEMESSAGE) { update(chatMessage.getMessage()); @@ -212,7 +422,15 @@ public void onChatMessage(ChatMessage chatMessage) public void update(final String message) { - if (mageArenaSolver == null) + final MageArenaTemperatureChange temperatureChange = MageArenaTemperatureChange.of(message); + + if (mageArenaSolvers == null || mageArenaSolvers.get(godToFind) == null) + { + return; + } + + // If looking only for a specific boss, don't bother checking others + if (!allowChangingBoss && lastGodClicked != godToFind) { return; } @@ -235,13 +453,12 @@ public void update(final String message) return; } - final MageArenaTemperatureChange temperatureChange = MageArenaTemperatureChange.of(message); - - mageArenaSolver.signal(localWorld, temperature, temperatureChange); + final MageArenaSolver currentMageArenaSolver = mageArenaSolvers.get(godToFind); + currentMageArenaSolver.signal(localWorld, temperature, temperatureChange); - if (mageArenaSolver.getPossibleLocations().size() == 1) + if (currentMageArenaSolver.getPossibleLocations().size() == 1) { - this.setWorldPoint(mageArenaSolver.getPossibleLocations().iterator().next().getWorldPoint()); + this.setWorldPoint(currentMageArenaSolver.getPossibleLocations().iterator().next().getWorldPoint()); } else { @@ -255,14 +472,20 @@ public void startUp() { super.startUp(); currentVar = client.getVarbitValue(VarbitID.MA2_TIMER_REMAINING); - Set locations = - Arrays.stream(MageArenaSpawnLocation.values()) + + mageArenaSolvers.put(God.SARADOMIN, new MageArenaSolver(Arrays.stream(MageArenaSpawnLocation.values()).collect(Collectors.toSet()))); + mageArenaSolvers.put(God.GUTHIX, new MageArenaSolver(Arrays.stream(MageArenaSpawnLocation.values()).collect(Collectors.toSet()))); + mageArenaSolvers.put(God.ZAMORAK, new MageArenaSolver(Arrays.stream(MageArenaSpawnLocation.values()).collect(Collectors.toSet()))); + + var locations = Arrays.stream(MageArenaSpawnLocation.values()) .collect(Collectors.toSet()); - mageArenaSolver = new MageArenaSolver(locations); + if (locations.size() == 1) { this.setWorldPoint(locations.iterator().next().getWorldPoint()); } + + addListeners(); } @Override @@ -276,4 +499,55 @@ private BufferedImage getSymbolLocation() { return itemManager.getImage(ItemID.MA2_SYMBOL); } + + public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, PanelComponent panelComponent) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("God name") + .leftColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .right(this.bossName) + .rightColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .build() + ); + + panelComponent.getChildren().add(LineComponent.builder() + .left("God to find") + .leftColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .right(this.godToFind.name) + .rightColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .build() + ); + + panelComponent.getChildren().add(LineComponent.builder() + .left("Pending") + .leftColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .right(clickedActivateOnSymbol ? "y" : "n") + .rightColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .build() + ); + } + + enum God + { + SARADOMIN("Saradomin"), + GUTHIX("Guthix"), + ZAMORAK("Zamorak"); + + final String name; + + God(String name) + { + this.name = name; + } + + public static God getByName(String name) + { + for (God god : God.values()) + { + if (god.name.equals(name)) return god; + } + // Failure catch + return SARADOMIN; + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java index 87383dcbc0a..d46335f5ac8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java @@ -49,7 +49,9 @@ public class MageArenaSolver { @Setter private Set possibleLocations; + @Nullable + @Setter private WorldPoint lastWorldPoint; public MageArenaSolver(Set possibleLocations) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java index 39c8ca96a07..aa23732a44d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java @@ -48,13 +48,12 @@ public enum MageArenaSpawnLocation NORTH_EAST_LAVA_DRAGON_4(new WorldPoint(3247, 3862, 0), "North east of the Lava Dragon Isle."), WEST_LAVA_DRAGON(new WorldPoint(3146, 3895, 0), "West of the Lava Dragon Isle."), WEST_LAVA_DRAGON_2(new WorldPoint(3163, 3833, 0), "West of the Lava Dragon Isle."), - WEST_DEMONIC_RUINS(new WorldPoint(3314, 3876, 0), "West of the Demonic Ruins."), + EAST_DEMONIC_RUINS(new WorldPoint(3314, 3876, 0), "East of the Demonic Ruins."), EAST_LAVA_DRAGON_ISLE(new WorldPoint(3246, 3834, 0), "East of the Lava Dragon Isle."), EAST_LAVA_DRAGON_ISLE_2(new WorldPoint(3279, 3823, 0), "East of the Lava Dragon Isle."), SOUTH_EAST_LAVA_DRAGON_ISLE(new WorldPoint(3266, 3814, 0), "South east of the Lava Dragon Isle."), EAST_ROGUE(new WorldPoint(3306, 3936, 0), "East of the Rogues' Castle."), - // TODO: This one isn't a precise position - EAST_ROGUE_2(new WorldPoint(3343, 3911, 0), "East of the Rogues' Castle."), + EAST_ROGUE_2(new WorldPoint(3335, 3902, 0), "East of the Rogues' Castle."), WEST_ROGUE(new WorldPoint(3261, 3909, 0), "West of the Rogues' Castle."); private final WorldPoint worldPoint; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java index d3cd649cc13..1029c9420a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java @@ -35,7 +35,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; @@ -46,6 +48,7 @@ import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -55,7 +58,14 @@ public class TheMageArenaII extends BasicQuestHelper ItemRequirement zamorakStaff, guthixStaff, saradominStaff, runesForCasts, magicCombatGear, knife, brews, restores , food, recoils, enchantedSymbol, justicarsHand, demonsHeart, entRoots, godCape; - Requirement inCavern, givenHand, givenHeart, givenRoots; + Requirement inCavern; + VarbitRequirement givenHand; + VarbitRequirement givenHeart; + VarbitRequirement givenRoots; + + VarplayerRequirement unlockedSaradominStrike; + VarplayerRequirement unlockedClawsOfGuthix; + VarplayerRequirement unlockedFlamesOfZamorak; QuestStep enterCavern, talkToKolodion, locateFollowerSara, locateFollowerGuthix, locateFollowerZammy, enterCavernWithHand, enterCavernWithHeart, enterCavernWithRoots, giveKolodionHeart, giveKolodionHand, @@ -115,7 +125,7 @@ protected void setupRequirements() new ItemRequirement("Fire runes", ItemID.FIRERUNE, -1)); magicCombatGear = new ItemRequirement("Magic combat gear", -1, 1).isNotConsumed(); magicCombatGear.setDisplayItemId(BankSlotIcons.getMagicCombatGear()); - knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemID.KNIFE).isNotConsumed(); + knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemCollections.SLASH_WEB_KNIFE).isNotConsumed(); brews = new ItemRequirement("Saradomin brews", ItemCollections.SARADOMIN_BREWS, -1); restores = new ItemRequirement("Super restores", ItemCollections.SUPER_RESTORE_POTIONS, -1); food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); @@ -130,6 +140,13 @@ protected void setupRequirements() godCape = new ItemRequirement("God cape", ItemID.ZAMORAK_CAPE).isNotConsumed(); godCape.addAlternates(ItemID.GUTHIX_CAPE, ItemID.SARADOMIN_CAPE); godCape.setHighlightInInventory(true); + + unlockedSaradominStrike = new VarplayerRequirement(VarPlayerID.SARAMAGE, 100, Operation.GREATER_EQUAL, "Unlocked Saradomin Strike"); + unlockedSaradominStrike.setTooltip("Unlocked by casting the Saradomin Strike 100 times within the mage arena"); + unlockedClawsOfGuthix = new VarplayerRequirement(VarPlayerID.GUTHMAGE, 100, Operation.GREATER_EQUAL, "Unlocked Claws of Guthix"); + unlockedClawsOfGuthix.setTooltip("Unlocked by casting the Claws of Guthix 100 times within the mage arena"); + unlockedFlamesOfZamorak = new VarplayerRequirement(VarPlayerID.ZAMOMAGE, 100, Operation.GREATER_EQUAL, "Unlocked Flames of Zamorak"); + unlockedFlamesOfZamorak.setTooltip("Unlocked by casting the Flames of Zamorak 100 times within the mage arena"); } @Override @@ -161,14 +178,15 @@ public void setupSteps() locateFollowerSara = new MageArenaBossStep(this, saradominStaff, "Saradomin", "If he fires a blue wave at " + "you, move off your tile to avoid it. If you don't, he will pull you into melee distance.", - enchantedSymbol, food); + givenHand, givenRoots, givenHeart, enchantedSymbol, food); locateFollowerSara.addDialogStep("Saradomin"); locateFollowerGuthix = new MageArenaBossStep(this, guthixStaff, "Guthix", "If he spawns green orbs, destroy " + - "them to stop them healing him.", enchantedSymbol, food); + "them to stop them healing him.", + givenHand, givenRoots, givenHeart, enchantedSymbol, food); locateFollowerGuthix.addDialogStep("Guthix"); locateFollowerZammy = new MageArenaBossStep(this, zamorakStaff, "Zamorak", "If he fires an energy ball at " + "you, move away away from the boss to reduce the damage you take.", - enchantedSymbol, food); + givenHand, givenRoots, givenHeart, enchantedSymbol, food); locateFollowerZammy.addDialogStep("Zamorak"); enterCavernWithHand = new ObjectStep(this, ObjectID.MAGEARENA_LEVER_TO_CELLAR, new WorldPoint(3090, 3956, 0), "Return with" + @@ -237,7 +255,9 @@ public List getGeneralRequirements() ArrayList reqs = new ArrayList<>(); reqs.add(new SkillRequirement(Skill.MAGIC, 75)); reqs.add(new QuestRequirement(QuestHelperQuest.THE_MAGE_ARENA, QuestState.FINISHED)); - reqs.add(new ItemRequirement("Unlocked all 3 god spells", -1, -1)); + reqs.add(unlockedSaradominStrike); + reqs.add(unlockedClawsOfGuthix); + reqs.add(unlockedFlamesOfZamorak); return reqs; } @@ -252,7 +272,7 @@ public List getPanels() { List allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Upgrading the God Cape", Arrays.asList(enterCavern, - talkToKolodion, locateAndKillMinions), knife, saradominStaff, guthixStaff, zamorakStaff, runesForCasts)); + talkToKolodion, locateAndKillMinions, useGodCapeOnKolidion), knife, saradominStaff, guthixStaff, zamorakStaff, unlockedSaradominStrike, unlockedClawsOfGuthix, unlockedFlamesOfZamorak, runesForCasts)); return allSteps; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java index c716a0340ae..e9850368916 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java @@ -32,14 +32,21 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -48,14 +55,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - /** * The quest guide for the "Vale Totems" OSRS quest */ @@ -153,7 +152,7 @@ protected void setupRequirements() oneDecorativeItem.setTooltip("You can also use Willow, Maple, Yew, Magic, or Redwood decorative items, but it needs to match the logs you used to build the totem."); needToBuildTotem = new VarbitRequirement(VarbitID.ENT_TOTEMS_BROKEN_CHAT, 1); - isTotemBaseBuilt = new VarbitRequirement(VarbitID.ENT_TOTEMS_SITE_1_BASE, 1); + isTotemBaseBuilt = new VarbitRequirement(VarbitID.ENT_TOTEMS_SITE_1_BASE, 0, Operation.GREATER); isBuffaloNearby = or( new VarbitRequirement(VarbitID.ENT_TOTEMS_SITE_1_ANIMAL_1, 1), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java index 09ddde6c431..e580be9e8be 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java @@ -28,7 +28,6 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.config.ConfigManager; import net.runelite.client.events.ConfigChanged; - import java.util.function.Consumer; public class FarmingConfigChangeHandler diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java index 01c49e4e82b..36f7e1f3839 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java @@ -48,14 +48,28 @@ public class FarmingPatch private final PatchImplementation implementation; private int farmer = -1; private final int patchNumber; - @Getter + @Getter(AccessLevel.NONE) private final WorldPoint location; - @Getter private final Shape patchArea; + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation) + { + this(name, varbit, implementation, null, new Polygon(), -1, -1); + } + + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, int farmer) + { + this(name, varbit, implementation, null, new Polygon(), farmer, -1); + } + + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, int farmer, int patchNumber) + { + this(name, varbit, implementation, null, new Polygon(), farmer, patchNumber); + } + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, WorldPoint location) { - this(name, varbit, implementation, location, new Polygon(), -1); + this(name, varbit, implementation, location, new Polygon(), -1, -1); } FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, WorldPoint location, Shape patchArea) @@ -79,6 +93,19 @@ public class FarmingPatch this.patchArea = patchArea; } + public WorldPoint getLocation() + { + if (location != null) + { + return location; + } + if (region == null) + { + return null; + } + return WorldPoint.fromRegion(region.getRegionID(), 32, 32, 0); + } + String configKey() { return region.getRegionID() + "." + varbit; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java index 288f603babe..f0dbdcf5bce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java @@ -24,22 +24,16 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns; -import java.util.Collections; -import java.util.HashSet; import lombok.Getter; import net.runelite.api.coords.WorldPoint; -import java.util.Set; -import org.jetbrains.annotations.NotNull; - @Getter -public class FarmingRegion implements Comparable +public class FarmingRegion { private final String name; private final int regionID; private final boolean definite; private final FarmingPatch[] patches; - private final Set regionIDs; FarmingRegion(String name, int regionID, boolean definite, FarmingPatch... patches) { @@ -47,56 +41,20 @@ public class FarmingRegion implements Comparable this.regionID = regionID; this.definite = definite; this.patches = patches; - this.regionIDs = Set.of(regionID); - for (FarmingPatch p : patches) - { - p.setRegion(this); - } - } - - FarmingRegion(String name, int regionID, boolean definite, Set regionIDs, FarmingPatch... patches) - { - this.name = name; - this.regionID = regionID; - this.definite = definite; - this.patches = patches; - - Set allRegionIds = new HashSet<>(regionIDs); - allRegionIds.add(regionID); - this.regionIDs = Collections.unmodifiableSet(allRegionIds); - for (FarmingPatch p : patches) { p.setRegion(this); } } - /** - * Check if the given WorldPoint is within this farming region - * Checks if the point's regionID is in this region's regionIDs set - * - * @param loc The WorldPoint to check - * @return true if the point is within this farming region - */ public boolean isInBounds(WorldPoint loc) { - return regionIDs.contains(loc.getRegionID()); + return true; } @Override public String toString() { - String sb = "FarmingRegion{name='" + name + '\'' + - ", regionID=" + regionID + - ", definite=" + definite + - ", patches=" + patches.length + - '}'; - return sb; - } - - @Override - public int compareTo(@NotNull FarmingRegion o) - { - return Integer.compare(regionID, o.getRegionID()); + return name; } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java index 8280a86e6c6..e03879a7bc0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java @@ -27,6 +27,8 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.Client; import net.runelite.api.gameval.ItemID; import net.runelite.client.config.ConfigManager; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java index 6f2416d2011..52f4a864f1d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java @@ -30,15 +30,21 @@ import com.google.common.collect.Multimaps; import com.google.inject.Singleton; import java.awt.Polygon; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.stream.Collectors; import lombok.Getter; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarbitID; import net.runelite.client.plugins.timetracking.Tab; -import java.util.*; -import java.util.stream.Collectors; - @Singleton public class FarmingWorld { @@ -46,12 +52,13 @@ public class FarmingWorld private Multimap regions = HashMultimap.create(); @Getter + @SuppressWarnings("PMD.ImmutableField") private Map> tabs = new HashMap<>(); private final Comparator tabSorter = Comparator - .comparing(FarmingPatch::getImplementation) - .thenComparing((FarmingPatch p) -> p.getRegion().getName()) - .thenComparing(FarmingPatch::getName); + .comparing(FarmingPatch::getImplementation) + .thenComparing((FarmingPatch p) -> p.getRegion().getName()) + .thenComparing(FarmingPatch::getName); @Getter private final FarmingRegion farmingGuildRegion; @@ -60,120 +67,104 @@ public class FarmingWorld { // Some of these patches get updated in multiple regions. // It may be worth it to add a specialization for these patches - add(new FarmingRegion("Al Kharid", 13106, false, Set.of(13105, 13362), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CACTUS, new WorldPoint(3317, 3203, 0), - new Polygon( + add(new FarmingRegion("Al Kharid", 13106, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CACTUS, new WorldPoint(3317, 3203, 0), new Polygon( new int[]{3315, 3315, 3316, 3316}, new int[]{3202, 3203, 3203, 3202}, 4 - ), - NpcID.FARMING_GARDENER_CACTUS) - )); + ), NpcID.FARMING_GARDENER_CACTUS) + ), 13362, 13105); - add(new FarmingRegion("Aldarin", 5421, false, Set.of(5165, 5166, 5422, 5677, 5678), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(1366, 2941, 0), - new Polygon( + add(new FarmingRegion("Aldarin", 5421, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(1366, 2941, 0), new Polygon( new int[]{1363, 1363, 1366, 1366}, new int[]{2937, 2940, 2940, 2937}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_5) + ), NpcID.FARMING_GARDENER_HOPS_5) + ), 5165, 5166, 5422, 5677, 5678); + + add(new FarmingRegion("Anglers' Retreat", 9770, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, NpcID.FARMING_GARDENER_HARDWOOD_TREE_5) )); - add(new FarmingRegion("Ardougne", 10290, false, Set.of(10546), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2616, 3226, 0), - new Polygon( + add(new FarmingRegion("Ardougne", 10290, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2616, 3226, 0), new Polygon( new int[]{2617, 2617, 2618, 2618}, new int[]{3225, 3226, 3226, 3225}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_4) - )); + ), NpcID.FARMING_GARDENER_BUSH_4) + ), 10546); add(new FarmingRegion("Ardougne", 10548, false, - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3379, 0), - new Polygon( + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3379, 0), new Polygon( new int[]{2662, 2662, 2671, 2671, 2663, 2663}, new int[]{3377, 3379, 3379, 3378, 3378, 3377}, 6 - ), - NpcID.KRAGEN, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3371, 0), - new Polygon( + ), NpcID.KRAGEN, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3371, 0), new Polygon( new int[]{2662, 2662, 2663, 2663, 2671, 2671}, new int[]{3370, 3372, 3372, 3371, 3371, 3370}, 6 - ), - NpcID.KRAGEN, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2668, 3375, 0), - new Polygon( + ), NpcID.KRAGEN, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2668, 3375, 0), new Polygon( new int[]{2666, 2666, 2667, 2667}, new int[]{3374, 3375, 3375, 3374}, - 4) - ), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2672, 3375, 0), - new Polygon( + 4)), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2672, 3375, 0), new Polygon( new int[]{2670, 2670, 2671, 2671}, new int[]{3374, 3375, 3375, 3374}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(2662, 3375, 0)) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) )); - add(new FarmingRegion("Avium Savannah", 6702, true, Set.of(6446), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(1685, 2971, 0), - new Polygon( + add(new FarmingRegion("Auburnvale", 5427, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, NpcID.FARMING_GARDENER_TREE_7), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.BELLADONNA) + ), 5428, 5684); + + add(new FarmingRegion("Avium Savannah", 6702, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(1685, 2971, 0), new Polygon( new int[]{1686, 1686, 1688, 1688}, new int[]{2971, 2973, 2973, 2971}, 4 - ), - NpcID.FROG_QUEST_MARCELLUS) - )); + ), NpcID.FROG_QUEST_MARCELLUS) + ), 6446); - add(new FarmingRegion("Brimhaven", 11058, false, Set.of(11057), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2766, 3213, 0), - new Polygon( + add(new FarmingRegion("Brimhaven", 11058, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2766, 3213, 0), new Polygon( new int[]{2764, 2764, 2765, 2765}, new int[]{3212, 3213, 3213, 3212}, 4 - ), - NpcID.GARTH), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2800, 3202, 0), - new Polygon( + ), NpcID.GARTH), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2800, 3202, 0), new Polygon( new int[]{2801, 2801, 2803, 2803}, new int[]{3202, 3204, 3204, 3202}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_3) - )); + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_3) + ), 11057); - add(new FarmingRegion("Catherby", 11062, false, Set.of(11061, 11318, 11317), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2814, 3466, 0), - new Polygon( + add(new FarmingRegion("Catherby", 11062, false, + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2814, 3466, 0), new Polygon( new int[]{2805, 2805, 2814, 2814, 2806, 2806}, new int[]{3466, 3468, 3468, 3467, 3467, 3466}, 6 - ), - NpcID.DANTAERA, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2815, 3460, 0), - new Polygon( + ), NpcID.DANTAERA, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2815, 3460, 0), new Polygon( new int[]{2805, 2805, 2806, 2806, 2814, 2814}, new int[]{3459, 3461, 3461, 3460, 3460, 3459}, 6 - ), - NpcID.DANTAERA, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2810, 3465, 0), - new Polygon( + ), NpcID.DANTAERA, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2810, 3465, 0), new Polygon( new int[]{2809, 2809, 2810, 2810}, new int[]{3463, 3464, 3464, 3463}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2815, 3464, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2815, 3464, 0), new Polygon( new int[]{2813, 2813, 2814, 2814}, new int[]{3463, 3464, 3464, 3463}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(2805, 3464, 0)) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) ) { @Override @@ -186,15 +177,13 @@ public boolean isInBounds(WorldPoint loc) } return true; } - }); + }, 11061, 11318, 11317); add(new FarmingRegion("Catherby", 11317, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2860, 3432, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2860, 3432, 0), new Polygon( new int[]{2860, 2860, 2861, 2861}, new int[]{3433, 3434, 3434, 3433}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_4) + ), NpcID.FARMING_GARDENER_FRUIT_4) ) { //The fruit tree patch is always sent when upstairs in 11317 @@ -205,119 +194,92 @@ public boolean isInBounds(WorldPoint loc) } }); - add(new FarmingRegion("Civitas illa Fortis", 6192, false, Set.of(6447, 6448, 6449, 6191, 6193), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1586, 3102, 0), - new Polygon( + add(new FarmingRegion("Civitas illa Fortis", 6192, false, + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1586, 3102, 0), new Polygon( new int[]{1581, 1581, 1585, 1585, 1582, 1582}, new int[]{3098, 3103, 3103, 3102, 3102, 3098}, 6 - ), - NpcID.FORTIS_GARDENER, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1591, 3098, 0), - new Polygon( + ), NpcID.FORTIS_GARDENER, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1591, 3098, 0), new Polygon( new int[]{1585, 1585, 1589, 1589, 1590, 1590}, new int[]{3094, 3095, 3095, 3098, 3098, 3094}, 6 - ), - NpcID.FORTIS_GARDENER, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1587, 3099, 0), - new Polygon( + ), NpcID.FORTIS_GARDENER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1587, 3099, 0), new Polygon( new int[]{1585, 1585, 1586, 1586}, new int[]{3098, 3099, 3099, 3098}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1581, 3094, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1581, 3094, 0), new Polygon( new int[]{1581, 1581, 1582, 1582}, new int[]{3094, 3095, 3095, 3094}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(1587, 3103, 0)) - )); + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) + ), 6447, 6448, 6449, 6191, 6193); add(new FarmingRegion("Champions' Guild", 12596, true, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(3181, 3356, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(3181, 3356, 0), new Polygon( new int[]{3181, 3181, 3182, 3182}, new int[]{3357, 3358, 3358, 3357}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_1) + ), NpcID.FARMING_GARDENER_BUSH_1) )); add(new FarmingRegion("Draynor Manor", 12340, false, - new FarmingPatch("Belladonna", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BELLADONNA, new WorldPoint(3088, 3355, 0), - new Polygon( - new int[]{3086, 3086, 3087, 3087}, - new int[]{3354, 3355, 3355, 3354}, - 4 - )) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BELLADONNA) )); - add(new FarmingRegion("Entrana", 11060, false, Set.of(11316), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2812, 3334, 0), - new Polygon( + add(new FarmingRegion("Entrana", 11060, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2812, 3334, 0), new Polygon( new int[]{2809, 2809, 2812, 2812}, new int[]{3335, 3338, 3338, 3335}, 4 - ), - NpcID.FRANCIS) - )); + ), NpcID.FRANCIS) + ), 11316); add(new FarmingRegion("Etceteria", 10300, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2592, 3862, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2592, 3862, 0), new Polygon( new int[]{2591, 2591, 2592, 2592}, new int[]{3863, 3864, 3864, 3863}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_3), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2613, 3856, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_BUSH_3), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2613, 3856, 0), new Polygon( new int[]{2612, 2612, 2614, 2614}, new int[]{3857, 3859, 3859, 3857}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_2) + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_2) )); - add(new FarmingRegion("Falador", 11828, false, Set.of(12084), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3004, 3371, 0), - new Polygon( + add(new FarmingRegion("Falador", 11828, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3004, 3371, 0), new Polygon( new int[]{3003, 3003, 3005, 3005}, new int[]{3372, 3374, 3374, 3372}, 4 - ), - NpcID.FARMING_GARDENER_TREE_2) - )); + ), NpcID.FARMING_GARDENER_TREE_2) + ), 12084); add(new FarmingRegion("Falador", 12083, false, - new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3052, 3307, 0), - new Polygon( + new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3052, 3307, 0), new Polygon( new int[]{3050, 3050, 3054, 3054, 3051, 3051}, new int[]{3307, 3312, 3312, 3311, 3311, 3307}, 6 - ), - NpcID.ELSTAN, 0), - new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3055, 3305, 0), - new Polygon( + ), NpcID.ELSTAN, 0), + new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3055, 3305, 0), new Polygon( new int[]{3055, 3055, 3058, 3058, 3059, 3059}, new int[]{3303, 3304, 3304, 3308, 3308, 3303}, 6 - ), - NpcID.ELSTAN, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3053, 3307, 0), - new Polygon( + ), NpcID.ELSTAN, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3053, 3307, 0), new Polygon( new int[]{3054, 3054, 3055, 3055}, new int[]{3307, 3308, 3308, 3307}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3057, 3311, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3057, 3311, 0), new Polygon( new int[]{3058, 3058, 3059, 3059}, new int[]{3311, 3312, 3312, 3311}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(3056, 3311, 0)) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) ) { @Override @@ -328,28 +290,22 @@ public boolean isInBounds(WorldPoint loc) } }); - add(new FarmingRegion("Fossil Island", 14651, false, Set.of(14907, 14908, 15164, 14652, 14906, 14650, 15162, 15163), - new FarmingPatch("East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3713, 3835, 0), - new Polygon( + add(new FarmingRegion("Fossil Island", 14651, false, + new FarmingPatch("East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3713, 3835, 0), new Polygon( new int[]{3714, 3714, 3716, 3716}, new int[]{3834, 3836, 3836, 3834}, 4 - ), - NpcID.FOSSIL_SQUIRREL_GARDENER1), - new FarmingPatch("Middle", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3708, 3835, 0), - new Polygon( + ), NpcID.FOSSIL_SQUIRREL_GARDENER1), + new FarmingPatch("Middle", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3708, 3835, 0), new Polygon( new int[]{3707, 3707, 3709, 3709}, new int[]{3832, 3834, 3834, 3832}, 4 - ), - NpcID.FOSSIL_SQUIRREL_GARDENER2), - new FarmingPatch("West", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3701, 3836, 0), - new Polygon( + ), NpcID.FOSSIL_SQUIRREL_GARDENER2), + new FarmingPatch("West", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3701, 3836, 0), new Polygon( new int[]{3701, 3701, 3703, 3703}, new int[]{3836, 3838, 3838, 3836}, 4 - ), - NpcID.FOSSIL_SQUIRREL_GARDENER3) + ), NpcID.FOSSIL_SQUIRREL_GARDENER3) ) { @Override @@ -366,194 +322,168 @@ public boolean isInBounds(WorldPoint loc) //East and west ladders to rope bridge if ((loc.getX() == 3729 || loc.getX() == 3728 || loc.getX() == 3747 || loc.getX() == 3746) - && loc.getY() <= 3832 && loc.getY() >= 3830) + && loc.getY() <= 3832 && loc.getY() >= 3830) { return false; } return loc.getPlane() == 0; } - }); + }, 14907, 14908, 15164, 14652, 14906, 14650, 15162, 15163); add(new FarmingRegion("Seaweed", 15008, false, - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SEAWEED, new WorldPoint(3733, 10272, 1), - new Polygon( + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SEAWEED, new WorldPoint(3733, 10272, 1), new Polygon( new int[]{3733, 3733, 3734, 3734}, new int[]{10273, 10274, 10274, 10273}, 4 - ), - NpcID.FOSSIL_GARDENER_UNDERWATER, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SEAWEED, new WorldPoint(3733, 10269, 1), - new Polygon( + ), NpcID.FOSSIL_GARDENER_UNDERWATER, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SEAWEED, new WorldPoint(3733, 10269, 1), new Polygon( new int[]{3733, 3733, 3734, 3734}, new int[]{10267, 10268, 10268, 10267}, 4 - ), - NpcID.FOSSIL_GARDENER_UNDERWATER, 1) + ), NpcID.FOSSIL_GARDENER_UNDERWATER, 1) )); - add(new FarmingRegion("Gnome Stronghold", 9781, true, Set.of(9782, 9526, 9525), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2437, 3417, 0), - new Polygon( + add(new FarmingRegion("Gnome Stronghold", 9781, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2437, 3417, 0), new Polygon( new int[]{2437, 2437, 2435, 2435}, new int[]{3416, 3414, 3414, 3416}, 4 - ), - NpcID.FARMING_GARDENER_TREE_GNOME), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.FRUIT_TREE, new WorldPoint(2475, 3447, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_TREE_GNOME), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.FRUIT_TREE, new WorldPoint(2475, 3447, 0), new Polygon( new int[]{2475, 2475, 2476, 2476}, new int[]{3445, 3446, 3446, 3445}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_1) - )); + ), NpcID.FARMING_GARDENER_FRUIT_1) + ), 9782, 9526, 9525); + + add(new FarmingRegion("Great Conch", 12581, true, + new FarmingPatch("East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CORAL, NpcID.TORTUGAN_CORAL_FARMER, 0), + new FarmingPatch("West", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.CORAL, NpcID.TORTUGAN_CORAL_FARMER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.CALQUAT, NpcID.FARMING_GARDENER_CALQUAT_3) + ), 12325, 12326, 12327, 12580, 12581, 12582, 12583, 12836, 12837, 12838, 12839, 13092, 13093, 13194); add(new FarmingRegion("Harmony", 15148, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3795, 2838, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3795, 2838, 0), new Polygon( new int[]{3794, 3794}, new int[]{2833, 2838}, 2 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HERB, new WorldPoint(3790, 3839, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HERB, new WorldPoint(3790, 3839, 0), new Polygon( new int[]{3789, 3789, 3790, 3790}, new int[]{2837, 2838, 2838, 2837}, 4 )) )); - add(new FarmingRegion("Kourend", 6967, false, Set.of(6711), - new FarmingPatch("North East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1739, 3553, 0), - new Polygon( + add(new FarmingRegion("Kastori", 5423, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CALQUAT, NpcID.FARMING_GARDENER_CALQUAT_2), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.FRUIT_TREE, NpcID.FARMING_GARDENER_FRUIT_7), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER) + ), 5167, 5424); + + add(new FarmingRegion("Kourend", 6967, false, + new FarmingPatch("North East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1739, 3553, 0), new Polygon( new int[]{1733, 1733, 1739, 1739, 1738, 1738}, new int[]{3558, 3559, 3559, 3554, 3554, 3558}, 6 - ), - NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 0), - new FarmingPatch("South West", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1735, 3552, 0), - new Polygon( + ), NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 0), + new FarmingPatch("South West", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1735, 3552, 0), new Polygon( new int[]{1730, 1730, 1731, 1731, 1735, 1735}, new int[]{3550, 3555, 3555, 3551, 3551, 3550}, 6 - ), - NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1735, 3553, 0), - new Polygon( + ), NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1735, 3553, 0), new Polygon( new int[]{1734, 1734, 1735, 1734}, new int[]{3554, 3555, 3555, 1734}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1739, 3552, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1739, 3552, 0), new Polygon( new int[]{1738, 1738, 1739, 1739}, new int[]{3550, 3551, 3551, 3550}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(1730, 3557, 0)), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.SPIRIT_TREE, new WorldPoint(1695, 3543, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.SPIRIT_TREE, new WorldPoint(1695, 3543, 0), new Polygon( new int[]{1692, 1692, 1694, 1694}, new int[]{3541, 3543, 3543, 3541}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_4) - )); - - /* - Not implemented - */ + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_4) + ), 6711); add(new FarmingRegion("Kourend", 7223, false, - new FarmingPatch("East 1", VarbitID.FARMING_TRANSMIT_A1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 2", VarbitID.FARMING_TRANSMIT_A2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 3", VarbitID.FARMING_TRANSMIT_B1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 4", VarbitID.FARMING_TRANSMIT_B2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 5", VarbitID.FARMING_TRANSMIT_C1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 6", VarbitID.FARMING_TRANSMIT_C2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 1", VarbitID.FARMING_TRANSMIT_D1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 2", VarbitID.FARMING_TRANSMIT_D2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 3", VarbitID.FARMING_TRANSMIT_E1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 4", VarbitID.FARMING_TRANSMIT_E2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 5", VarbitID.FARMING_TRANSMIT_F1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 6", VarbitID.FARMING_TRANSMIT_F2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)) - )); - - add(new FarmingRegion("Lletya", 9265, false, Set.of(11103), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2345, 3162, 0), - new Polygon( + new FarmingPatch("East 1", VarbitID.FARMING_TRANSMIT_A1, PatchImplementation.GRAPES), + new FarmingPatch("East 2", VarbitID.FARMING_TRANSMIT_A2, PatchImplementation.GRAPES), + new FarmingPatch("East 3", VarbitID.FARMING_TRANSMIT_B1, PatchImplementation.GRAPES), + new FarmingPatch("East 4", VarbitID.FARMING_TRANSMIT_B2, PatchImplementation.GRAPES), + new FarmingPatch("East 5", VarbitID.FARMING_TRANSMIT_C1, PatchImplementation.GRAPES), + new FarmingPatch("East 6", VarbitID.FARMING_TRANSMIT_C2, PatchImplementation.GRAPES), + new FarmingPatch("West 1", VarbitID.FARMING_TRANSMIT_D1, PatchImplementation.GRAPES), + new FarmingPatch("West 2", VarbitID.FARMING_TRANSMIT_D2, PatchImplementation.GRAPES), + new FarmingPatch("West 3", VarbitID.FARMING_TRANSMIT_E1, PatchImplementation.GRAPES), + new FarmingPatch("West 4", VarbitID.FARMING_TRANSMIT_E2, PatchImplementation.GRAPES), + new FarmingPatch("West 5", VarbitID.FARMING_TRANSMIT_F1, PatchImplementation.GRAPES), + new FarmingPatch("West 6", VarbitID.FARMING_TRANSMIT_F2, PatchImplementation.GRAPES) + )); + + add(new FarmingRegion("Lletya", 9265, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2345, 3162, 0), new Polygon( new int[]{2346, 2346, 2347, 2347}, new int[]{3161, 3162, 3162, 3161}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_TREE_5) - )); + ), NpcID.FARMING_GARDENER_FRUIT_TREE_5) + ), 11103); add(new FarmingRegion("Lumbridge", 12851, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(3232, 3317, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(3232, 3317, 0), new Polygon( new int[]{3227, 3227, 3231, 3231}, new int[]{3313, 3317, 3317, 3313}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_3) + ), NpcID.FARMING_GARDENER_HOPS_3) )); - add(new FarmingRegion("Lumbridge", 12594, false, Set.of(12850), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3195, 3230, 0), - new Polygon( + add(new FarmingRegion("Lumbridge", 12594, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3195, 3230, 0), new Polygon( new int[]{3192, 3192, 3194, 3194}, new int[]{3230, 3232, 3232, 3230}, 4 - ), - NpcID.FARMING_GARDENER_TREE_4) - )); + ), NpcID.FARMING_GARDENER_TREE_4) + ), 12850); - add(new FarmingRegion("Morytania", 13622, false, Set.of(13878), - new FarmingPatch("Mushroom", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.MUSHROOM, new WorldPoint(3451, 3474, 0), - new Polygon( + add(new FarmingRegion("Morytania", 13622, false, + new FarmingPatch("Mushroom", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.MUSHROOM, new WorldPoint(3451, 3474, 0), new Polygon( new int[]{3451, 3451, 3452, 3452}, new int[]{3472, 3473, 3473, 3472}, 4 )) - )); - add(new FarmingRegion("Morytania", 14391, false, Set.of(14390), - new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3597, 3524, 0), - new Polygon( + ), 13878); + add(new FarmingRegion("Morytania", 14391, false, + new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3597, 3524, 0), new Polygon( new int[]{3597, 3597, 3601, 3601, 3598, 3598}, new int[]{3525, 3530, 3530, 3529, 3529, 3525}, 6 - ), - NpcID.LYRA, 0), - new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3601, 3522, 0), - new Polygon( + ), NpcID.LYRA, 0), + new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3601, 3522, 0), new Polygon( new int[]{3602, 3602, 3605, 3605, 3606, 3606}, new int[]{3521, 3522, 3522, 3526, 3526, 3521}, 6 - ), - NpcID.LYRA, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3601, 3524, 0), - new Polygon( + ), NpcID.LYRA, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3601, 3524, 0), new Polygon( new int[]{3601, 3601, 3602, 3602}, new int[]{3225, 3226, 3226, 3225}, 4 - ) - ), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3605, 3528, 0), - new Polygon( + )), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3605, 3528, 0), new Polygon( new int[]{3605, 3605, 3606, 3606}, new int[]{3529, 3530, 3530, 3529}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(3609, 3522, 0)) - )); + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) + ), 14390); - add(new FarmingRegion("Port Sarim", 12082, false, Set.of(12083), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(3059, 3257, 0), - new Polygon( + add(new FarmingRegion("Port Sarim", 12082, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(3059, 3257, 0), new Polygon( new int[]{3059, 3059, 3061, 3061}, new int[]{3257, 3259, 3259, 3257}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_1) + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_1) ) { @Override @@ -561,90 +491,74 @@ public boolean isInBounds(WorldPoint loc) { return loc.getY() < 3272; } - }); + }, 12083); - add(new FarmingRegion("Rimmington", 11570, false, Set.of(11826), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2940, 3223, 0), - new Polygon( + add(new FarmingRegion("Rimmington", 11570, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2940, 3223, 0), new Polygon( new int[]{2940, 2940, 2941, 2941}, new int[]{3221, 3222, 3222, 3221}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_2) - )); + ), NpcID.FARMING_GARDENER_BUSH_2) + ), 11826); - add(new FarmingRegion("Seers' Village", 10551, false, Set.of(10550), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2669, 3522, 0), - new Polygon( + add(new FarmingRegion("Seers' Village", 10551, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2669, 3522, 0), new Polygon( new int[]{2664, 2664, 2669, 2669}, new int[]{3523, 3528, 3528, 3523}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_4) - )); + ), NpcID.FARMING_GARDENER_HOPS_4) + ), 10550); add(new FarmingRegion("Tai Bwo Wannai", 11056, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CALQUAT, new WorldPoint(2796, 3103, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CALQUAT, new WorldPoint(2796, 3103, 0), new Polygon( new int[]{2795, 2795, 2797, 2797}, new int[]{3100, 3102, 3102, 3100}, 4 - ), - NpcID.FARMING_GARDENER_CALQUAT) + ), NpcID.FARMING_GARDENER_CALQUAT) )); - add(new FarmingRegion("Taverley", 11573, false, Set.of(11829), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2936, 3440, 0), - new Polygon( + add(new FarmingRegion("Taverley", 11573, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2936, 3440, 0), new Polygon( new int[]{2935, 2935, 2937, 2937}, new int[]{3437, 3439, 3439, 3437}, 4 - ), - NpcID.FARMING_GARDENER_TREE_1) - )); + ), NpcID.FARMING_GARDENER_TREE_1) + ), 11829); - add(new FarmingRegion("Tree Gnome Village", 9777, true, Set.of(10033), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2488, 3180, 0), - new Polygon( + add(new FarmingRegion("Tree Gnome Village", 9777, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2488, 3180, 0), new Polygon( new int[]{2489, 2489, 2490, 2490}, new int[]{3179, 3180, 3180, 3179}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_2) - )); + ), NpcID.FARMING_GARDENER_FRUIT_2) + ), 10033); add(new FarmingRegion("Troll Stronghold", 11321, true, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2827, 3693, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2827, 3693, 0), new Polygon( new int[]{2826, 2826, 2827, 2827}, new int[]{3694, 3695, 3695, 3694}, 4 )) )); - add(new FarmingRegion("Varrock", 12854, false, Set.of(12853), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3229, 3457, 0), - new Polygon( + add(new FarmingRegion("Varrock", 12854, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3229, 3457, 0), new Polygon( new int[]{3228, 3228, 3230, 3230}, new int[]{3458, 3460, 3460, 3458}, 4 - ), - NpcID.FARMING_GARDENER_TREE_3_02) - )); + ), NpcID.FARMING_GARDENER_TREE_3_02) + ), 12853); add(new FarmingRegion("Yanille", 10288, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2573, 3106, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2573, 3106, 0), new Polygon( new int[]{2574, 2574, 2577, 2577}, new int[]{3103, 3106, 3106, 3103}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_1) + ), NpcID.FARMING_GARDENER_HOPS_1) )); add(new FarmingRegion("Weiss", 11325, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2849, 3933, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2849, 3933, 0), new Polygon( new int[]{2848, 2848, 2849, 2849}, new int[]{3934, 3935, 3935, 3934}, 4 @@ -652,8 +566,7 @@ public boolean isInBounds(WorldPoint loc) )); add(new FarmingRegion("Farming Guild", 5021, true, - new FarmingPatch("Hespori", VarbitID.FARMING_TRANSMIT_J, PatchImplementation.HESPORI, new WorldPoint(1246, 10085, 0), - new Polygon( + new FarmingPatch("Hespori", VarbitID.FARMING_TRANSMIT_J, PatchImplementation.HESPORI, new WorldPoint(1246, 10085, 0), new Polygon( new int[]{1246, 1248, 1248, 1246}, new int[]{10086, 10088, 10088, 10086}, 4 @@ -661,121 +574,95 @@ public boolean isInBounds(WorldPoint loc) )); //Full 3x3 region area centered on farming guild - add(farmingGuildRegion = new FarmingRegion("Farming Guild", 4922, true, Set.of(5177, 5178, 5179, 4921, 4923, 4665, 4666, 4667), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_G, PatchImplementation.TREE, new WorldPoint(1233, 3734, 0), - new Polygon( + add(farmingGuildRegion = new FarmingRegion("Farming Guild", 4922, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_G, PatchImplementation.TREE, new WorldPoint(1233, 3734, 0), new Polygon( new int[]{1231, 1231, 1233, 1233}, new int[]{3735, 3737, 3737, 3735}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T2), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.HERB, new WorldPoint(1238, 3728, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T2), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.HERB, new WorldPoint(1238, 3728, 0), new Polygon( new int[]{1238, 1238, 1239, 1239}, new int[]{3726, 3727, 3727, 3726}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.BUSH, new WorldPoint(1261, 3732, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.BUSH, new WorldPoint(1261, 3732, 0), new Polygon( new int[]{1260, 1260, 1261, 1261}, new int[]{3733, 3734, 3734, 3733}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 3), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_H, PatchImplementation.FLOWER, new WorldPoint(1261, 3727, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 3), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_H, PatchImplementation.FLOWER, new WorldPoint(1261, 3727, 0), new Polygon( new int[]{1260, 1260, 1261, 1261}, new int[]{3725, 3726, 3726, 3725}, 4 )), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3732, 0), - new Polygon( + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3732, 0), new Polygon( new int[]{1267, 1267, 1268, 1268, 1272, 1272}, new int[]{3732, 3736, 3736, 3733, 3733, 3732}, 6 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 1), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3727, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 1), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3727, 0), new Polygon( new int[]{1267, 1267, 1272, 1272, 1268, 1268}, new int[]{3723, 3727, 3727, 3726, 3726, 3723}, 6 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 2), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_N, PatchImplementation.BIG_COMPOST, new WorldPoint(1271, 3729, 0)), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.CACTUS, new WorldPoint(1264, 3746, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 2), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_N, PatchImplementation.BIG_COMPOST), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.CACTUS, new WorldPoint(1264, 3746, 0), new Polygon( new int[]{1264, 1264, 1265, 1265}, new int[]{3747, 3748, 3748, 3747}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 0), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(1251, 3749, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 0), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(1251, 3749, 0), new Polygon( new int[]{1252, 1252, 1254, 1254}, new int[]{3749, 3751, 3751, 3749}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_5), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_K, PatchImplementation.FRUIT_TREE, new WorldPoint(1243, 3757, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_5), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_K, PatchImplementation.FRUIT_TREE, new WorldPoint(1243, 3757, 0), new Polygon( new int[]{1242, 1242, 1243, 1243}, new int[]{3758, 3759, 3758, 3758}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T3), - new FarmingPatch("Anima", VarbitID.FARMING_TRANSMIT_M, PatchImplementation.ANIMA, new WorldPoint(1233, 3725, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T3), + new FarmingPatch("Anima", VarbitID.FARMING_TRANSMIT_M, PatchImplementation.ANIMA, new WorldPoint(1233, 3725, 0), new Polygon( new int[]{1231, 1231, 1233, 1233}, new int[]{3722, 3724, 3724, 3722}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_L, PatchImplementation.CELASTRUS, new WorldPoint(1245, 3752, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_L, PatchImplementation.CELASTRUS, new WorldPoint(1245, 3752, 0), new Polygon( new int[]{1243, 1243, 1245, 1245}, new int[]{3749, 3751, 3751, 3749}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_CELASTRUS), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_I, PatchImplementation.REDWOOD, new WorldPoint(1233, 3752, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_CELASTRUS), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_I, PatchImplementation.REDWOOD, new WorldPoint(1233, 3752, 0), new Polygon( new int[]{1225, 1225, 1232, 1232}, new int[]{3751, 3758, 3758, 3751}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_REDWOOD) - )); + ), NpcID.FARMING_GARDENER_FARMGUILD_REDWOOD) + ), 5177, 5178, 5179, 4921, 4923, 4665, 4666, 4667); //All of Prifddinas, and all of Prifddinas Underground - add(new FarmingRegion("Prifddinas", 13151, false, Set.of(12895, 12894, 13150, 12994, 12993, 12737, 12738, 12126, 12127, 13250), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3293, 6105, 0), - new Polygon( + add(new FarmingRegion("Prifddinas", 13151, false, + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3293, 6105, 0), new Polygon( new int[]{3288, 3288, 3293, 3293, 3289, 3289}, new int[]{6101, 6104, 6104, 6103, 6103, 6101}, 6 - ), - NpcID.PRIF_GARDENER, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3294, 6096, 0), - new Polygon( + ), NpcID.PRIF_GARDENER, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3294, 6096, 0), new Polygon( new int[]{3288, 3288, 3289, 3289, 3293, 3293}, new int[]{6095, 6098, 6098, 6096, 6096, 6095}, 6 - ), - NpcID.PRIF_GARDENER, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3294, 6100, 0), - new Polygon( + ), NpcID.PRIF_GARDENER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3294, 6100, 0), new Polygon( new int[]{3292, 3292, 3293, 3293}, new int[]{6099, 6100, 6100, 6099}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.CRYSTAL_TREE, new WorldPoint(3291, 6117, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.CRYSTAL_TREE, new WorldPoint(3291, 6117, 0), new Polygon( new int[]{3291, 3291, 3292, 3292}, new int[]{6118, 6119, 6119, 6118}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.COMPOST, new WorldPoint(3288, 6100, 0)) - )); + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.COMPOST) + ), 12895, 12894, 13150, + /* Underground */ 12994, 12993, 12737, 12738, 12126, 12127, 13250); // Finalize this.regions = Multimaps.unmodifiableMultimap(this.regions); @@ -787,25 +674,25 @@ public boolean isInBounds(WorldPoint loc) this.tabs = Collections.unmodifiableMap(umtabs); } - private void add(FarmingRegion r) + private void add(FarmingRegion r, int... extraRegions) { regions.put(r.getRegionID(), r); - for (int er : r.getRegionIDs()) + for (int er : extraRegions) { regions.put(er, r); } for (FarmingPatch p : r.getPatches()) { tabs - .computeIfAbsent(p.getImplementation().getTab(), k -> new TreeSet<>(tabSorter)) - .add(p); + .computeIfAbsent(p.getImplementation().getTab(), k -> new TreeSet<>(tabSorter)) + .add(p); } } Collection getRegionsForLocation(WorldPoint location) { return this.regions.get(location.getRegionID()).stream() - .filter(region -> region.isInBounds(location)) - .collect(Collectors.toSet()); + .filter(region -> region.isInBounds(location)) + .collect(Collectors.toSet()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java index cf76611eed4..5351434349e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java @@ -26,7 +26,6 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.config.ConfigKeys; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.TopLevelPanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; @@ -40,6 +39,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.QuestState; @@ -77,6 +77,8 @@ public class HerbRun extends ComplexStateQuestHelper // Recommended items ItemRequirement compost; + ItemRequirement enoughCompost; + ItemRequirement bottomlessBucket; ItemRequirement ectophial; ItemRequirement magicSec; ItemRequirement explorerRing2; @@ -87,7 +89,6 @@ public class HerbRun extends ComplexStateQuestHelper ItemRequirement icyBasalt; ItemRequirement stonyBasalt; ItemRequirement farmingGuildTeleport; - ItemRequirement hosidiusHouseTeleport; ItemRequirement hunterWhistle; ItemRequirement harmonyTeleport; ItemRequirement gracefulHood; @@ -109,7 +110,8 @@ public class HerbRun extends ComplexStateQuestHelper QuestRequirement accessToTrollStronghold; SkillRequirement accessToFarmingGuildPatch; QuestRequirement accessToVarlamore; - RuneliteRequirement unlockedBarbarianPlanting; + QuestRequirement accessToMorytania; + VarbitRequirement unlockedBarbarianPlanting; ManualRequirement ardougneEmpty; ManualRequirement catherbyEmpty; @@ -220,8 +222,9 @@ protected void setupRequirements() accessToWeiss = new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED); accessToTrollStronghold = new QuestRequirement(QuestHelperQuest.MY_ARMS_BIG_ADVENTURE, QuestState.FINISHED); accessToVarlamore = new QuestRequirement(QuestHelperQuest.CHILDREN_OF_THE_SUN, QuestState.FINISHED); + accessToMorytania = new QuestRequirement(QuestHelperQuest.PRIEST_IN_PERIL, QuestState.FINISHED); - unlockedBarbarianPlanting = new RuneliteRequirement(configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_SEED_PLANTING.getKey()); + unlockedBarbarianPlanting = new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, Operation.EQUAL, 3, "Unlocked Barbarian Planting"); spade = new ItemRequirement("Spade", ItemID.SPADE); dibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).hideConditioned(unlockedBarbarianPlanting); @@ -247,6 +250,10 @@ protected void setupRequirements() } compost = new ItemRequirement("Compost", ItemCollections.COMPOST); compost.setDisplayMatchedItemName(true); + + bottomlessBucket = new ItemRequirement("Bottomless Compost Bucket", ItemID.BOTTOMLESS_COMPOST_BUCKET_FILLED); + enoughCompost = new ItemRequirements(LogicType.OR, "Compost or bottomless bucket", bottomlessBucket, compost); + ectophial = new ItemRequirement("Ectophial", ItemID.ECTOPHIAL).showConditioned(new QuestRequirement(QuestHelperQuest.GHOSTS_AHOY, QuestState.FINISHED)); ectophial.addAlternates(ItemID.ECTOPHIAL_EMPTY); magicSec = new ItemRequirement("Magic secateurs", ItemID.FAIRY_ENCHANTED_SECATEURS).showConditioned(new QuestRequirement(QuestHelperQuest.FAIRYTALE_I__GROWING_PAINS, QuestState.FINISHED)); @@ -256,20 +263,19 @@ protected void setupRequirements() ardyCloak2.addAlternates(ItemID.ARDY_CAPE_HARD, ItemID.ARDY_CAPE_ELITE); xericsTalisman = new ItemRequirement("Xeric's talisman", ItemID.XERIC_TALISMAN); - hosidiusHouseTeleport = new ItemRequirement("Teleport to Hosidius House", ItemID.NZONE_TELETAB_KOUREND); - hosidiusHouseTeleport.addAlternates(ItemID.XERIC_TALISMAN); + xericsTalisman.addAlternates(ItemID.NZONE_TELETAB_KOUREND); var catherbyRunes = new ItemRequirements("Catherby teleport runes", new ItemRequirement("Law rune", ItemID.LAWRUNE), new ItemRequirement("Air rune", ItemID.AIRRUNE, 5)); var catherbyTablet = new ItemRequirement("Catherby tablet", ItemID.LUNAR_TABLET_CATHERBY_TELEPORT); - catherbyTeleport = new ItemRequirements(LogicType.OR, "Catherby teleport", catherbyRunes, catherbyTablet); + catherbyTeleport = new ItemRequirements(LogicType.OR, "Catherby teleport", catherbyTablet, catherbyRunes); var trollheimRunes = new ItemRequirements("Trollheim teleport runes", new ItemRequirement("Law rune", ItemID.LAWRUNE, 2), new ItemRequirement("Fire rune", ItemID.FIRERUNE, 2)); var trollheimTablet = new ItemRequirement("Trollheim tablet", ItemID.NZONE_TELETAB_TROLLHEIM); - trollheimTeleport = new ItemRequirements(LogicType.OR, "Trollheim teleport", trollheimRunes, trollheimTablet) - .hideConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); + trollheimTeleport = new ItemRequirements(LogicType.OR, "Trollheim teleport", trollheimTablet, trollheimRunes) + .showConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); icyBasalt = new ItemRequirement("Icy basalt", ItemID.WEISS_TELEPORT_BASALT).showConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); stonyBasalt = new ItemRequirement("Stony basalt", ItemID.STRONGHOLD_TELEPORT_BASALT).showConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); @@ -279,7 +285,7 @@ protected void setupRequirements() farmingGuildTeleport.addAlternates(ItemCollections.SKILLS_NECKLACES); farmingGuildTeleport.addAlternates(ItemCollections.FAIRY_STAFF); - harmonyTeleport = new ItemRequirement("Harmony Teleport", ItemID.TELETAB_HARMONY); + harmonyTeleport = new ItemRequirement("Harmony Teleport", ItemID.TELETAB_HARMONY).showConditioned(accessToHarmony); hunterWhistle = new ItemRequirement("Quetzal whistle", ItemID.HG_QUETZALWHISTLE_PERFECTED).showConditioned(accessToVarlamore); hunterWhistle.addAlternates(ItemID.HG_QUETZALWHISTLE_BASIC); @@ -370,7 +376,7 @@ public void setupSteps() faladorPlant.addIcon(ItemID.RANARR_SEED); faladorPatch.addSubSteps(faladorPlant); - hosidiusPlant = new ObjectStep(this, ObjectID.FARMING_HERB_PATCH_6, new WorldPoint(1738, 3550, 0), "Plant your seeds into the Hosidius patch.", hosidiusHouseTeleport); + hosidiusPlant = new ObjectStep(this, ObjectID.FARMING_HERB_PATCH_6, new WorldPoint(1738, 3550, 0), "Plant your seeds into the Hosidius patch.", xericsTalisman); hosidiusPlant.addIcon(ItemID.RANARR_SEED); hosidiusPatch.addSubSteps(hosidiusPlant); @@ -385,6 +391,7 @@ public void setupSteps() harmonyPatch.addSubSteps(harmonyPlant); morytaniaPlant = new ObjectStep(this, ObjectID.FARMING_HERB_PATCH_4, new WorldPoint(3605, 3529, 0), "Plant your seeds into the Morytania patch.", ectophial); + morytaniaPlant.conditionToHideInSidebar(new Conditions(LogicType.NOR, accessToMorytania)); morytaniaPlant.addIcon(ItemID.RANARR_SEED); morytaniaPatch.addSubSteps(morytaniaPlant); @@ -423,8 +430,8 @@ public QuestStep loadStep() steps.addStep(catherbyReady, catherbyPatch); steps.addStep(catherbyEmpty, catherbyPlant); - steps.addStep(morytaniaReady, morytaniaPatch); - steps.addStep(morytaniaEmpty, morytaniaPlant); + steps.addStep(new Conditions(accessToMorytania, morytaniaReady), morytaniaPatch); + steps.addStep(new Conditions(accessToMorytania, morytaniaEmpty), morytaniaPlant); steps.addStep(hosidiusReady, hosidiusPatch); steps.addStep(hosidiusEmpty, hosidiusPlant); @@ -566,7 +573,7 @@ public List getItemRequirements() @Override public List getItemRecommended() { - return Arrays.asList(compost, ectophial, magicSec, explorerRing2, ardyCloak2, xericsTalisman, hosidiusHouseTeleport, catherbyTeleport, + return Arrays.asList(enoughCompost, ectophial, magicSec, explorerRing2, ardyCloak2, xericsTalisman, catherbyTeleport, trollheimTeleport, icyBasalt, stonyBasalt, farmingGuildTeleport, hunterWhistle, harmonyTeleport, gracefulOutfit, farmersOutfit); } @@ -588,11 +595,11 @@ private void prepopulateSidebarPanels() new PanelDetails("Falador", Collections.singletonList(faladorPatch)).withId(1), new PanelDetails("Ardougne", Collections.singletonList(ardougnePatch)).withId(2), new PanelDetails("Catherby", Collections.singletonList(catherbyPatch)).withId(3), - new PanelDetails("Morytania", Collections.singletonList(morytaniaPatch)).withId(4), + new PanelDetails("Morytania", Collections.singletonList(morytaniaPatch)).withId(4).withHideCondition(nor(accessToMorytania)), new PanelDetails("Hosidius", Collections.singletonList(hosidiusPatch)).withId(5), - new PanelDetails("Varlamore", Collections.singletonList(varlamorePatch)).withId(6), - new PanelDetails("Troll Stronghold", Collections.singletonList(trollStrongholdPatch)).withId(7), - new PanelDetails("Weiss", Collections.singletonList(weissPatch)).withId(8), + new PanelDetails("Varlamore", Collections.singletonList(varlamorePatch)).withId(6).withHideCondition(nor(accessToVarlamore)), + new PanelDetails("Troll Stronghold", Collections.singletonList(trollStrongholdPatch)).withId(7).withHideCondition(nor(accessToTrollStronghold)), + new PanelDetails("Weiss", Collections.singletonList(weissPatch)).withId(8).withHideCondition(nor(accessToWeiss)), new PanelDetails("Harmony Island", Collections.singletonList(harmonyPatch)).withId(9).withHideCondition(nor(accessToHarmony)) ); allSteps.add(farmRunSidebar); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java index f7a1c2e1fb8..226f95622fe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java @@ -24,13 +24,12 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns; +import javax.annotation.Nullable; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.runelite.client.plugins.timetracking.Tab; import net.runelite.client.plugins.timetracking.farming.Produce; -import javax.annotation.Nullable; - @RequiredArgsConstructor @Getter public enum PatchImplementation @@ -1261,7 +1260,7 @@ PatchState forVarbitValue(int value) if (value == 33) { // Apple tree stump[Clear,Inspect,Guide] 7961 - return new PatchState(Produce.APPLE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.APPLE, CropState.STUMP, 0); } if (value == 34) { @@ -1291,7 +1290,7 @@ PatchState forVarbitValue(int value) if (value == 60) { // Banana tree stump[Clear,Inspect,Guide] 8019 - return new PatchState(Produce.BANANA, CropState.HARVESTABLE, 0); + return new PatchState(Produce.BANANA, CropState.STUMP, 0); } if (value == 61) { @@ -1331,7 +1330,7 @@ PatchState forVarbitValue(int value) if (value == 97) { // Orange tree stump[Clear,Inspect,Guide] 8077 - return new PatchState(Produce.ORANGE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.ORANGE, CropState.STUMP, 0); } if (value == 98) { @@ -1361,7 +1360,7 @@ PatchState forVarbitValue(int value) if (value == 124) { // Curry tree stump[Clear,Inspect,Guide] 8046 - return new PatchState(Produce.CURRY, CropState.HARVESTABLE, 0); + return new PatchState(Produce.CURRY, CropState.STUMP, 0); } if (value == 125) { @@ -1396,7 +1395,7 @@ PatchState forVarbitValue(int value) if (value == 161) { // Pineapple plant stump[Clear,Inspect,Guide] 7992 - return new PatchState(Produce.PINEAPPLE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.PINEAPPLE, CropState.STUMP, 0); } if (value == 162) { @@ -1426,7 +1425,7 @@ PatchState forVarbitValue(int value) if (value == 188) { // Papaya tree stump[Clear,Inspect,Guide] 8131 - return new PatchState(Produce.PAPAYA, CropState.HARVESTABLE, 0); + return new PatchState(Produce.PAPAYA, CropState.STUMP, 0); } if (value == 189) { @@ -1461,7 +1460,7 @@ PatchState forVarbitValue(int value) if (value == 225) { // Palm tree stump[Clear,Inspect,Guide] 8104 - return new PatchState(Produce.PALM, CropState.HARVESTABLE, 0); + return new PatchState(Produce.PALM, CropState.STUMP, 0); } if (value == 226) { @@ -1491,7 +1490,7 @@ PatchState forVarbitValue(int value) if (value == 252) { // Dragonfruit tree stump[Clear,Inspect,Guide] 34034 - return new PatchState(Produce.DRAGONFRUIT, CropState.HARVESTABLE, 0); + return new PatchState(Produce.DRAGONFRUIT, CropState.STUMP, 0); } if (value == 253) { @@ -1867,7 +1866,7 @@ PatchState forVarbitValue(int value) if (value == 14) { // Oak tree stump[Clear,Inspect,Guide] 8468 - return new PatchState(Produce.OAK, CropState.HARVESTABLE, 0); + return new PatchState(Produce.OAK, CropState.STUMP, 0); } if (value >= 15 && value <= 20) { @@ -1887,7 +1886,7 @@ PatchState forVarbitValue(int value) if (value == 23) { // Willow tree stump[Clear,Inspect,Guide] 8489 - return new PatchState(Produce.WILLOW, CropState.HARVESTABLE, 0); + return new PatchState(Produce.WILLOW, CropState.STUMP, 0); } if (value >= 24 && value <= 31) { @@ -1907,7 +1906,7 @@ PatchState forVarbitValue(int value) if (value == 34) { // Tree stump[Clear,Inspect,Guide] 8445 - return new PatchState(Produce.MAPLE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.MAPLE, CropState.STUMP, 0); } if (value >= 35 && value <= 44) { @@ -1927,7 +1926,7 @@ PatchState forVarbitValue(int value) if (value == 47) { // Yew tree stump[Clear,Inspect,Guide] 8514 - return new PatchState(Produce.YEW, CropState.HARVESTABLE, 0); + return new PatchState(Produce.YEW, CropState.STUMP, 0); } if (value >= 48 && value <= 59) { @@ -1947,7 +1946,7 @@ PatchState forVarbitValue(int value) if (value == 62) { // Magic Tree Stump[Clear,Inspect,Guide] 8410 - return new PatchState(Produce.MAGIC, CropState.HARVESTABLE, 0); + return new PatchState(Produce.MAGIC, CropState.STUMP, 0); } if (value >= 63 && value <= 72) { @@ -2150,7 +2149,7 @@ PatchState forVarbitValue(int value) if (value == 17) { // Tree stump[Clear,Inspect,Guide] 30446 - return new PatchState(Produce.TEAK, CropState.HARVESTABLE, 0); + return new PatchState(Produce.TEAK, CropState.STUMP, 0); } if (value >= 18 && value <= 23) { @@ -2180,7 +2179,7 @@ PatchState forVarbitValue(int value) if (value == 40) { // Mahogany tree stump[Clear,Inspect,Guide] 30418 - return new PatchState(Produce.MAHOGANY, CropState.HARVESTABLE, 0); + return new PatchState(Produce.MAHOGANY, CropState.STUMP, 0); } if (value >= 41 && value <= 47) { @@ -2210,7 +2209,7 @@ PatchState forVarbitValue(int value) if (value == 65) { // Camphor tree stump[Clear,Inspect,Guide] 58724 - return new PatchState(Produce.CAMPHOR, CropState.HARVESTABLE, 0); + return new PatchState(Produce.CAMPHOR, CropState.STUMP, 0); } if (value >= 66 && value <= 72) { @@ -2240,7 +2239,7 @@ PatchState forVarbitValue(int value) if (value == 90) { // Ironwood tree stump[Clear,Inspect,Guide] 58755 - return new PatchState(Produce.IRONWOOD, CropState.HARVESTABLE, 0); + return new PatchState(Produce.IRONWOOD, CropState.STUMP, 0); } if (value >= 91 && value <= 97) { @@ -2270,7 +2269,7 @@ PatchState forVarbitValue(int value) if (value == 116) { // Rosewood tree stump[Clear,Inspect,Guide] 58786 - return new PatchState(Produce.ROSEWOOD, CropState.HARVESTABLE, 0); + return new PatchState(Produce.ROSEWOOD, CropState.STUMP, 0); } if (value >= 117 && value <= 124) { @@ -2751,7 +2750,7 @@ PatchState forVarbitValue(int value) if (value == 28) { // Celastrus tree stump[Clear,Inspect,Guide] 33721 - return new PatchState(Produce.CELASTRUS, CropState.HARVESTABLE, 0); + return new PatchState(Produce.CELASTRUS, CropState.STUMP, 0); } if (value >= 29 && value <= 255) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java index e60d07530c5..f3086e05699 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java @@ -24,15 +24,14 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns; +import javax.inject.Inject; +import javax.inject.Singleton; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.runelite.client.config.ConfigManager; import net.runelite.client.plugins.timetracking.TimeTrackingConfig; -import javax.inject.Inject; -import javax.inject.Singleton; - @Slf4j @RequiredArgsConstructor( access = AccessLevel.PRIVATE, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java index be0e8318a03..0fd0dcbaee1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java @@ -28,7 +28,13 @@ import com.google.inject.Inject; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.*; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.FruitTreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.GracefulOrFarming; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.HardwoodTreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.TreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.CalquatTreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.PayOrCut; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.PayOrCompost; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.TopLevelPanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; @@ -46,6 +52,8 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.client.plugins.microbot.questhelper.steps.widget.LunarSpells; import net.runelite.client.plugins.microbot.questhelper.steps.widget.NormalSpells; +import java.util.Set; + import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; import net.runelite.api.QuestState; import net.runelite.api.Skill; @@ -56,11 +64,9 @@ import net.runelite.client.events.ConfigChanged; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.timetracking.Tab; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Set; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; @@ -71,6 +77,8 @@ * */ public class TreeRun extends ComplexStateQuestHelper { + private static final String TREE_PROTECTION_DIALOG = "Would you look after my crops for me?"; + @Inject private FarmingWorld farmingWorld; @@ -88,6 +96,9 @@ public class TreeRun extends ComplexStateQuestHelper DetailedQuestStep farmingGuildTreePatchCheckHealth, lumbridgeTreePatchCheckHealth, faladorTreePatchCheckHealth, taverleyTreePatchCheckHealth, varrockTreePatchCheckHealth, gnomeStrongholdTreePatchCheckHealth, auburnvaleTreePatchCheckHealth; + DetailedQuestStep farmingGuildTreePatchCutDown, lumbridgeTreePatchCutDown, faladorTreePatchCutDown, + taverleyTreePatchCutDown, varrockTreePatchCutDown, gnomeStrongholdTreePatchCutDown, + auburnvaleTreePatchCutDown; DetailedQuestStep farmingGuildTreePatchPlant, lumbridgeTreePatchPlant, faladorTreePatchPlant, taverleyTreePatchPlant, varrockTreePatchPlant, gnomeStrongholdTreePatchPlant, auburnvaleTreePatchPlant; @@ -118,6 +129,10 @@ public class TreeRun extends ComplexStateQuestHelper DetailedQuestStep farmingGuildFruitTreePatchDig, gnomeStrongholdFruitTreePatchDig, gnomeVillageFruitTreePatchDig, brimhavenFruitTreePatchDig, lletyaFruitTreePatchDig, catherbyFruitTreePatchDig, taiBwoWannaiCalquatPatchDig, kastoriFruitTreePatchDig, kastoriCalquatPatchDig, greatConchCalquatPatchDig; + DetailedQuestStep farmingGuildFruitTreePatchCutDown, gnomeStrongholdFruitTreePatchCutDown, gnomeVillageFruitTreePatchCutDown, + brimhavenFruitTreePatchCutDown, lletyaFruitTreePatchCutDown, catherbyFruitTreePatchCutDown, + kastoriFruitTreePatchCutDown; + DetailedQuestStep taiBwoWannaiCalquatPatchRemove, kastoriCalquatPatchRemove, greatConchCalquatPatchRemove; DetailedQuestStep guildFruitProtect, strongholdFruitProtect, villageFruitProtect, brimhavenFruitProtect, lletyaFruitProtect, catherbyFruitProtect, taiBwoWannaiCalquatProtect, kastoriFruitProtect, @@ -133,6 +148,8 @@ public class TreeRun extends ComplexStateQuestHelper DetailedQuestStep eastHardwoodTreePatchClear, westHardwoodTreePatchClear, middleHardwoodTreePatchClear, savannahClear, anglersClear; + DetailedQuestStep eastHardwoodTreePatchCutDown, westHardwoodTreePatchCutDown, middleHardwoodTreePatchCutDown, + savannahCutDown, anglersCutDown; DetailedQuestStep eastHardwoodProtect, westHardwoodProtect, middleHardwoodProtect, savannahProtect, anglersProtect; @@ -165,15 +182,17 @@ public class TreeRun extends ComplexStateQuestHelper gnomeStrongholdTreeStates, auburnvaleStates; PatchStates gnomeStrongholdFruitStates, gnomeVillageStates, brimhavenStates, catherbyStates, lletyaStates, - farmingGuildFruitStates, taiBwoWannaiStates, kastoriStates, greatConchStates; + farmingGuildFruitStates, taiBwoWannaiStates, kastoriFruitStates, kastoriCalquatStates, greatConchStates; PatchStates eastHardwoodStates, middleHardwoodStates, westHardwoodStates, savannahStates, anglersRetreatStates; Requirement allGrowing; - ConditionalStep farmingGuildStep, lumbridgeStep, varrockStep, faladorStep, taverleyStep, strongholdStep, - villageStep, lletyaStep, catherbyStep, brimhavenStep, fossilIslandStep, savannahStep, auburnvaleStep, - kastoriStep, anglersRetreatStep, greatConchStep; + ReorderableConditionalStep farmingGuildStep, strongholdStep, karamjaStep, fossilIslandStep, kastoriStep; + ConditionalStep farmingGuildTreeStep, farmingGuildFruitStep, lumbridgeStep, varrockStep, faladorStep, taverleyStep, + strongholdTreeStep, strongholdFruitStep, villageStep, lletyaStep, catherbyStep, brimhavenStep, + taiBwoWannaiStep, fossilIslandEastStep, fossilIslandMiddleStep, fossilIslandWestStep, savannahStep, + auburnvaleStep, kastoriFruitStep, kastoriCalquatStep, anglersRetreatStep, greatConchStep; private final String PAY_OR_CUT = "payOrCutTree"; private final String PAY_OR_COMPOST = "payOrCompostTree"; @@ -193,194 +212,216 @@ public QuestStep loadStep() // Varrock -> Gnome Stronghold Fruit -> Gnome Stronghold Tree -> Gnome Village -> catherby // -> Brimhaven -> lletya -> east hardwood -> middle hardwood -> west hardwood. - farmingGuildStep = new ConditionalStep(this, farmingGuildTreePatchCheckHealth); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsUnchecked(), farmingGuildTreePatchCheckHealth); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsHarvestable(), farmingGuildTreePatchClear); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsStump(), farmingGuildTreePatchDig); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsEmpty(), farmingGuildTreePatchPlant); - farmingGuildStep.addStep(nor(farmingGuildTreeStates.getIsProtected(), usingCompostorNothing), farmingGuildTreePayForProtection); - - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsUnchecked()), farmingGuildFruitTreePatchCheckHealth); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsHarvestable()), farmingGuildFruitTreePatchClear); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsStump()), farmingGuildFruitTreePatchDig); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsEmpty()), farmingGuildFruitTreePatchPlant); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, nor(farmingGuildFruitStates.getIsProtected(), usingCompostorNothing)), guildFruitProtect); - - steps.addStep(and(accessToFarmingGuildTreePatch, nand(farmingGuildTreeStates.getIsGrowing(), - farmingGuildFruitStates.getIsGrowing())), farmingGuildStep.withId(0)); + farmingGuildTreeStep = (ConditionalStep) new ConditionalStep(this, farmingGuildTreePatchCheckHealth).withId(-1); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsUnchecked(), farmingGuildTreePatchCheckHealth); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsStump(), farmingGuildTreePatchDig); + farmingGuildTreeStep.addStep(and(farmingGuildTreeStates.getIsHarvestable(), not(payingForRemoval)), farmingGuildTreePatchCutDown); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsHarvestable(), farmingGuildTreePatchClear); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsEmpty(), farmingGuildTreePatchPlant); + farmingGuildTreeStep.addStep(nor(farmingGuildTreeStates.getIsProtected(), usingCompostorNothing), farmingGuildTreePayForProtection); + + // TODO: Ideally we should allow for null steps to be rejected and propagate up conditionalstep chains + farmingGuildStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + farmingGuildStep.addStep(not(farmingGuildTreeStates.getIsGrowing()), farmingGuildTreeStep); + + farmingGuildFruitStep = (ConditionalStep) new ConditionalStep(this, farmingGuildFruitTreePatchCheckHealth).withId(-2); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsUnchecked()), farmingGuildFruitTreePatchCheckHealth); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsHarvestable(), not(payingForRemoval)), farmingGuildFruitTreePatchCutDown); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsHarvestable()), farmingGuildFruitTreePatchClear); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsStump()), farmingGuildFruitTreePatchDig); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsEmpty()), farmingGuildFruitTreePatchPlant); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, nor(farmingGuildFruitStates.getIsProtected(), usingCompostorNothing)), guildFruitProtect); + farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, not(farmingGuildFruitStates.getIsGrowing())), farmingGuildFruitStep); + steps.addStep(or(and(accessToFarmingGuildTreePatch, not(farmingGuildTreeStates.getIsGrowing())), and(accessToFarmingGuildFruitTreePatch, not(farmingGuildFruitStates.getIsGrowing()))), farmingGuildStep.withId(0)); lumbridgeStep = new ConditionalStep(this, lumbridgeTreePatchCheckHealth); lumbridgeStep.addStep(lumbridgeStates.getIsUnchecked(), lumbridgeTreePatchCheckHealth); + lumbridgeStep.addStep(and(lumbridgeStates.getIsHarvestable(), not(payingForRemoval)), lumbridgeTreePatchCutDown); lumbridgeStep.addStep(lumbridgeStates.getIsEmpty(), lumbridgeTreePatchPlant); lumbridgeStep.addStep(lumbridgeStates.getIsHarvestable(), lumbridgeTreePatchClear); lumbridgeStep.addStep(lumbridgeStates.getIsStump(), lumbridgeTreePatchDig); lumbridgeStep.addStep(nor(usingCompostorNothing, lumbridgeStates.getIsProtected()), lumbridgeTreeProtect); - - steps.addStep(nor(lumbridgeStates.getIsGrowing()), lumbridgeStep.withId(1)); + steps.addStep(not(lumbridgeStates.getIsGrowing()), lumbridgeStep.withId(1)); faladorStep = new ConditionalStep(this, faladorTreePatchCheckHealth); faladorStep.addStep(faladorStates.getIsUnchecked(), faladorTreePatchCheckHealth); + faladorStep.addStep(and(faladorStates.getIsHarvestable(), not(payingForRemoval)), faladorTreePatchCutDown); faladorStep.addStep(faladorStates.getIsEmpty(), faladorTreePatchPlant); faladorStep.addStep(faladorStates.getIsHarvestable(), faladorTreePatchClear); faladorStep.addStep(faladorStates.getIsStump(), faladorTreePatchDig); faladorStep.addStep(nor(usingCompostorNothing, faladorStates.getIsProtected()), faladorTreeProtect); - - steps.addStep(nor(faladorStates.getIsGrowing()), faladorStep.withId(2)); + steps.addStep(not(faladorStates.getIsGrowing()), faladorStep.withId(2)); taverleyStep = new ConditionalStep(this, taverleyTreePatchCheckHealth); taverleyStep.addStep(taverleyStates.getIsUnchecked(), taverleyTreePatchCheckHealth); + taverleyStep.addStep(and(taverleyStates.getIsHarvestable(), not(payingForRemoval)), taverleyTreePatchCutDown); taverleyStep.addStep(taverleyStates.getIsEmpty(), taverleyTreePatchPlant); taverleyStep.addStep(taverleyStates.getIsHarvestable(), taverleyTreePatchClear); taverleyStep.addStep(taverleyStates.getIsStump(), taverleyTreePatchDig); taverleyStep.addStep(nor(usingCompostorNothing, taverleyStates.getIsProtected()), taverleyTreeProtect); - - steps.addStep(nor(taverleyStates.getIsGrowing()), taverleyStep.withId(3)); + steps.addStep(not(taverleyStates.getIsGrowing()), taverleyStep.withId(3)); varrockStep = new ConditionalStep(this, varrockTreePatchCheckHealth); varrockStep.addStep(varrockStates.getIsUnchecked(), varrockTreePatchCheckHealth); + varrockStep.addStep(and(varrockStates.getIsHarvestable(), not(payingForRemoval)), varrockTreePatchCutDown); varrockStep.addStep(varrockStates.getIsEmpty(), varrockTreePatchPlant); varrockStep.addStep(varrockStates.getIsHarvestable(), varrockTreePatchClear); varrockStep.addStep(varrockStates.getIsStump(), varrockTreePatchDig); varrockStep.addStep(nor(usingCompostorNothing, varrockStates.getIsProtected()), varrockTreeProtect); - - steps.addStep(nor(varrockStates.getIsGrowing()), varrockStep.withId(4)); - - strongholdStep = new ConditionalStep(this, gnomeStrongholdFruitTreePatchCheckHealth); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsUnchecked(), gnomeStrongholdFruitTreePatchCheckHealth); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsEmpty(), gnomeStrongholdFruitTreePatchPlant); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsHarvestable(), gnomeStrongholdFruitTreePatchClear); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsStump(), gnomeStrongholdFruitTreePatchDig); - strongholdStep.addStep(nor(usingCompostorNothing, gnomeStrongholdFruitStates.getIsProtected()), strongholdFruitProtect); - - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsUnchecked(), gnomeStrongholdTreePatchCheckHealth); - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsEmpty(), gnomeStrongholdTreePatchPlant); - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsHarvestable(), gnomeStrongholdTreePatchClear); - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsStump(), gnomeStrongholdTreePatchDig); - strongholdStep.addStep(nor(usingCompostorNothing, gnomeStrongholdTreeStates.getIsProtected()), strongholdTreeProtect); - - steps.addStep(nand(gnomeStrongholdTreeStates.getIsGrowing(), - gnomeStrongholdFruitStates.getIsGrowing()), strongholdStep.withId(5)); + steps.addStep(not(varrockStates.getIsGrowing()), varrockStep.withId(4)); + + strongholdFruitStep = (ConditionalStep) new ConditionalStep(this, gnomeStrongholdFruitTreePatchCheckHealth).withId(51); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsUnchecked(), gnomeStrongholdFruitTreePatchCheckHealth); + strongholdFruitStep.addStep(and(gnomeStrongholdFruitStates.getIsHarvestable(), not(payingForRemoval)), gnomeStrongholdFruitTreePatchCutDown); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsEmpty(), gnomeStrongholdFruitTreePatchPlant); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsHarvestable(), gnomeStrongholdFruitTreePatchClear); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsStump(), gnomeStrongholdFruitTreePatchDig); + strongholdFruitStep.addStep(nor(usingCompostorNothing, gnomeStrongholdFruitStates.getIsProtected()), strongholdFruitProtect); + strongholdStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + strongholdStep.addStep(not(gnomeStrongholdFruitStates.getIsGrowing()), strongholdFruitStep); + strongholdTreeStep = (ConditionalStep) new ConditionalStep(this, gnomeStrongholdTreePatchCheckHealth).withId(52); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsUnchecked(), gnomeStrongholdTreePatchCheckHealth); + strongholdTreeStep.addStep(and(gnomeStrongholdTreeStates.getIsHarvestable(), not(payingForRemoval)), gnomeStrongholdTreePatchCutDown); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsEmpty(), gnomeStrongholdTreePatchPlant); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsHarvestable(), gnomeStrongholdTreePatchClear); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsStump(), gnomeStrongholdTreePatchDig); + strongholdTreeStep.addStep(nor(usingCompostorNothing, gnomeStrongholdTreeStates.getIsProtected()), strongholdTreeProtect); + strongholdStep.addStep(not(gnomeStrongholdTreeStates.getIsGrowing()), strongholdTreeStep); + steps.addStep(nand(gnomeStrongholdFruitStates.getIsGrowing(), gnomeStrongholdTreeStates.getIsGrowing()), strongholdStep.withId(5)); villageStep = new ConditionalStep(this, gnomeVillageFruitTreePatchCheckHealth); villageStep.addStep(gnomeVillageStates.getIsUnchecked(), gnomeVillageFruitTreePatchCheckHealth); + villageStep.addStep(and(gnomeVillageStates.getIsHarvestable(), not(payingForRemoval)), gnomeVillageFruitTreePatchCutDown); villageStep.addStep(gnomeVillageStates.getIsEmpty(), gnomeVillageFruitTreePatchPlant); villageStep.addStep(gnomeVillageStates.getIsHarvestable(), gnomeVillageFruitTreePatchClear); villageStep.addStep(gnomeVillageStates.getIsStump(), gnomeVillageFruitTreePatchDig); villageStep.addStep(nor(usingCompostorNothing, gnomeVillageStates.getIsProtected()), villageFruitProtect); - - steps.addStep(nor(gnomeVillageStates.getIsGrowing()), villageStep.withId(6)); + steps.addStep(not(gnomeVillageStates.getIsGrowing()), villageStep.withId(6)); catherbyStep = new ConditionalStep(this, catherbyFruitTreePatchCheckHealth); catherbyStep.addStep(catherbyStates.getIsUnchecked(), catherbyFruitTreePatchCheckHealth); + catherbyStep.addStep(and(catherbyStates.getIsHarvestable(), not(payingForRemoval)), catherbyFruitTreePatchCutDown); catherbyStep.addStep(catherbyStates.getIsEmpty(), catherbyFruitTreePatchPlant); catherbyStep.addStep(catherbyStates.getIsHarvestable(), catherbyFruitTreePatchClear); catherbyStep.addStep(catherbyStates.getIsStump(), catherbyFruitTreePatchDig); catherbyStep.addStep(nor(usingCompostorNothing, catherbyStates.getIsProtected()), catherbyFruitProtect); + steps.addStep(not(catherbyStates.getIsGrowing()), catherbyStep.withId(7)); - steps.addStep(nor(catherbyStates.getIsGrowing()), catherbyStep.withId(7)); - - brimhavenStep = new ConditionalStep(this, brimhavenFruitTreePatchCheckHealth); + brimhavenStep = (ConditionalStep) new ConditionalStep(this, brimhavenFruitTreePatchCheckHealth).withId(81); brimhavenStep.addStep(brimhavenStates.getIsUnchecked(), brimhavenFruitTreePatchCheckHealth); + brimhavenStep.addStep(and(brimhavenStates.getIsHarvestable(), not(payingForRemoval)), brimhavenFruitTreePatchCutDown); brimhavenStep.addStep(brimhavenStates.getIsEmpty(), brimhavenFruitTreePatchPlant); brimhavenStep.addStep(brimhavenStates.getIsHarvestable(), brimhavenFruitTreePatchClear); brimhavenStep.addStep(brimhavenStates.getIsStump(), brimhavenFruitTreePatchDig); brimhavenStep.addStep(nor(usingCompostorNothing, brimhavenStates.getIsProtected()), brimhavenFruitProtect); - brimhavenStep.addStep(taiBwoWannaiStates.getIsUnchecked(), taiBwoWannaiCalquatPatchCheckHealth); - brimhavenStep.addStep(taiBwoWannaiStates.getIsEmpty(), taiBwoWannaiCalquatPatchPlant); - brimhavenStep.addStep(taiBwoWannaiStates.getIsHarvestable(), taiBwoWannaiCalquatPatchClear); - brimhavenStep.addStep(taiBwoWannaiStates.getIsStump(), taiBwoWannaiCalquatPatchDig); - brimhavenStep.addStep(nor(usingCompostorNothing, taiBwoWannaiStates.getIsProtected()), + karamjaStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + karamjaStep.addStep(not(brimhavenStates.getIsGrowing()), brimhavenStep); + + taiBwoWannaiStep = (ConditionalStep) new ConditionalStep(this, taiBwoWannaiCalquatPatchCheckHealth).withId(82); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsUnchecked(), taiBwoWannaiCalquatPatchCheckHealth); + taiBwoWannaiStep.addStep(and(taiBwoWannaiStates.getIsHarvestable(), not(payingForRemoval)), taiBwoWannaiCalquatPatchRemove); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsEmpty(), taiBwoWannaiCalquatPatchPlant); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsHarvestable(), taiBwoWannaiCalquatPatchClear); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsStump(), taiBwoWannaiCalquatPatchDig); + taiBwoWannaiStep.addStep(nor(usingCompostorNothing, taiBwoWannaiStates.getIsProtected()), taiBwoWannaiCalquatProtect); - - steps.addStep(nand(brimhavenStates.getIsGrowing(), taiBwoWannaiStates.getIsGrowing()), brimhavenStep.withId(8)); + karamjaStep.addStep(not(taiBwoWannaiStates.getIsGrowing()), taiBwoWannaiStep); + steps.addStep(nand(brimhavenStates.getIsGrowing(), taiBwoWannaiStates.getIsGrowing()), karamjaStep.withId(8)); lletyaStep = new ConditionalStep(this, lletyaFruitTreePatchCheckHealth); lletyaStep.addStep(lletyaStates.getIsUnchecked(), lletyaFruitTreePatchCheckHealth); + lletyaStep.addStep(and(lletyaStates.getIsHarvestable(), not(payingForRemoval)), lletyaFruitTreePatchCutDown); lletyaStep.addStep(lletyaStates.getIsEmpty(), lletyaFruitTreePatchPlant); lletyaStep.addStep(lletyaStates.getIsHarvestable(), lletyaFruitTreePatchClear); lletyaStep.addStep(lletyaStates.getIsStump(), lletyaFruitTreePatchDig); lletyaStep.addStep(nor(usingCompostorNothing, lletyaStates.getIsProtected()), lletyaFruitProtect); - - steps.addStep(and(accessToLletya, nor(lletyaStates.getIsGrowing())), lletyaStep.withId(9)); - - fossilIslandStep = new ConditionalStep(this, eastHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(eastHardwoodStates.getIsUnchecked(), eastHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(eastHardwoodStates.getIsEmpty(), eastHardwoodTreePatchPlant); - fossilIslandStep.addStep(eastHardwoodStates.getIsHarvestable(), eastHardwoodTreePatchClear); - fossilIslandStep.addStep(eastHardwoodStates.getIsStump(), eastHardwoodTreePatchDig); - fossilIslandStep.addStep(nor(usingCompostorNothing, eastHardwoodStates.getIsProtected()), eastHardwoodProtect); - - fossilIslandStep.addStep(middleHardwoodStates.getIsUnchecked(), middleHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(middleHardwoodStates.getIsEmpty(), middleHardwoodTreePatchPlant); - fossilIslandStep.addStep(middleHardwoodStates.getIsHarvestable(), middleHardwoodTreePatchClear); - fossilIslandStep.addStep(middleHardwoodStates.getIsStump(), middleHardwoodTreePatchDig); - fossilIslandStep.addStep(nor(usingCompostorNothing, middleHardwoodStates.getIsProtected()), middleHardwoodProtect); - - fossilIslandStep.addStep(westHardwoodStates.getIsUnchecked(), westHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(westHardwoodStates.getIsEmpty(), westHardwoodTreePatchPlant); - fossilIslandStep.addStep(westHardwoodStates.getIsHarvestable(), westHardwoodTreePatchClear); - fossilIslandStep.addStep(westHardwoodStates.getIsStump(), westHardwoodTreePatchDig); - fossilIslandStep.addStep(nor(usingCompostorNothing, westHardwoodStates.getIsProtected()), westHardwoodProtect); - - steps.addStep(and(accessToFossilIsland, - nand(eastHardwoodStates.getIsGrowing(), westHardwoodStates.getIsGrowing(), middleHardwoodStates.getIsGrowing())), - fossilIslandStep.withId(10)); + steps.addStep(and(accessToLletya, not(lletyaStates.getIsGrowing())), lletyaStep.withId(9)); + + fossilIslandEastStep = (ConditionalStep) new ConditionalStep(this, eastHardwoodTreePatchCheckHealth).withId(101); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsUnchecked(), eastHardwoodTreePatchCheckHealth); + fossilIslandEastStep.addStep(and(eastHardwoodStates.getIsHarvestable(), not(payingForRemoval)), eastHardwoodTreePatchCutDown); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsEmpty(), eastHardwoodTreePatchPlant); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsHarvestable(), eastHardwoodTreePatchClear); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsStump(), eastHardwoodTreePatchDig); + fossilIslandEastStep.addStep(nor(usingCompostorNothing, eastHardwoodStates.getIsProtected()), eastHardwoodProtect); + fossilIslandStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + fossilIslandStep.addStep(not(eastHardwoodStates.getIsGrowing()), fossilIslandEastStep); + fossilIslandMiddleStep = (ConditionalStep) new ConditionalStep(this, middleHardwoodTreePatchCheckHealth).withId(102); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsUnchecked(), middleHardwoodTreePatchCheckHealth); + fossilIslandMiddleStep.addStep(and(middleHardwoodStates.getIsHarvestable(), not(payingForRemoval)), middleHardwoodTreePatchCutDown); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsEmpty(), middleHardwoodTreePatchPlant); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsHarvestable(), middleHardwoodTreePatchClear); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsStump(), middleHardwoodTreePatchDig); + fossilIslandMiddleStep.addStep(nor(usingCompostorNothing, middleHardwoodStates.getIsProtected()), middleHardwoodProtect); + fossilIslandStep.addStep(not(middleHardwoodStates.getIsGrowing()), fossilIslandMiddleStep); + + fossilIslandWestStep = (ConditionalStep) new ConditionalStep(this, westHardwoodTreePatchCheckHealth).withId(103); + fossilIslandWestStep.addStep(westHardwoodStates.getIsUnchecked(), westHardwoodTreePatchCheckHealth); + fossilIslandWestStep.addStep(and(westHardwoodStates.getIsHarvestable(), not(payingForRemoval)), westHardwoodTreePatchCutDown); + fossilIslandWestStep.addStep(westHardwoodStates.getIsEmpty(), westHardwoodTreePatchPlant); + fossilIslandWestStep.addStep(westHardwoodStates.getIsHarvestable(), westHardwoodTreePatchClear); + fossilIslandWestStep.addStep(westHardwoodStates.getIsStump(), westHardwoodTreePatchDig); + fossilIslandWestStep.addStep(nor(usingCompostorNothing, westHardwoodStates.getIsProtected()), westHardwoodProtect); + fossilIslandStep.addStep(not(westHardwoodStates.getIsGrowing()), fossilIslandWestStep); + steps.addStep(and(accessToFossilIsland, nand(eastHardwoodStates.getIsGrowing(), middleHardwoodStates.getIsGrowing(), westHardwoodStates.getIsGrowing())), fossilIslandStep.withId(10)); savannahStep = new ConditionalStep(this, savannahCheckHealth); savannahStep.addStep(savannahStates.getIsUnchecked(), savannahCheckHealth); + savannahStep.addStep(and(savannahStates.getIsHarvestable(), not(payingForRemoval)), savannahCutDown); savannahStep.addStep(savannahStates.getIsEmpty(), savannahPlant); savannahStep.addStep(savannahStates.getIsHarvestable(), savannahClear); savannahStep.addStep(savannahStates.getIsStump(), savannahDig); savannahStep.addStep(nor(usingCompostorNothing, savannahStates.getIsProtected()), savannahProtect); - - steps.addStep(and(accessToSavannah, nor(savannahStates.getIsGrowing())), savannahStep.withId(11)); + steps.addStep(and(accessToSavannah, not(savannahStates.getIsGrowing())), savannahStep.withId(11)); auburnvaleStep = new ConditionalStep(this, auburnvaleTreePatchCheckHealth); auburnvaleStep.addStep(auburnvaleStates.getIsUnchecked(), auburnvaleTreePatchCheckHealth); + auburnvaleStep.addStep(and(auburnvaleStates.getIsHarvestable(), not(payingForRemoval)), auburnvaleTreePatchCutDown); auburnvaleStep.addStep(auburnvaleStates.getIsEmpty(), auburnvaleTreePatchPlant); auburnvaleStep.addStep(auburnvaleStates.getIsHarvestable(), auburnvaleTreePatchClear); auburnvaleStep.addStep(auburnvaleStates.getIsStump(), auburnvaleTreePatchDig); auburnvaleStep.addStep(nor(usingCompostorNothing, auburnvaleStates.getIsProtected()), auburnvaleTreeProtect); - - steps.addStep(and(accessToVarlamore, nor(auburnvaleStates.getIsGrowing())), auburnvaleStep.withId(12)); - - - //kastoriStep, anglersRetreatStep, greatConchStep; - - kastoriStep = new ConditionalStep(this, kastoriFruitTreePatchCheckHealth); - kastoriStep.addStep(kastoriStates.getIsUnchecked(), kastoriFruitTreePatchCheckHealth); - kastoriStep.addStep(kastoriStates.getIsEmpty(), kastoriFruitTreePatchPlant); - kastoriStep.addStep(kastoriStates.getIsHarvestable(), kastoriFruitTreePatchClear); - kastoriStep.addStep(kastoriStates.getIsStump(), kastoriFruitTreePatchDig); - kastoriStep.addStep(nor(usingCompostorNothing, kastoriStates.getIsProtected()), kastoriFruitProtect); - - kastoriStep.addStep(kastoriStates.getIsUnchecked(), kastoriCalquatPatchCheckHealth); - kastoriStep.addStep(kastoriStates.getIsEmpty(), kastoriCalquatPatchPlant); - kastoriStep.addStep(kastoriStates.getIsHarvestable(), kastoriCalquatPatchClear); - kastoriStep.addStep(kastoriStates.getIsStump(), kastoriCalquatPatchDig); - kastoriStep.addStep(nor(usingCompostorNothing, kastoriStates.getIsProtected()), kastoriCalquatProtect); - - steps.addStep(and(accessToVarlamore, nand(kastoriStates.getIsGrowing(), kastoriStates.getIsGrowing())), kastoriStep.withId(13)); + steps.addStep(and(accessToVarlamore, not(auburnvaleStates.getIsGrowing())), auburnvaleStep.withId(12)); + + kastoriFruitStep = (ConditionalStep) new ConditionalStep(this, kastoriFruitTreePatchCheckHealth).withId(131); + kastoriFruitStep.addStep(kastoriFruitStates.getIsUnchecked(), kastoriFruitTreePatchCheckHealth); + kastoriFruitStep.addStep(and(kastoriFruitStates.getIsHarvestable(), not(payingForRemoval)), kastoriFruitTreePatchCutDown); + kastoriFruitStep.addStep(kastoriFruitStates.getIsEmpty(), kastoriFruitTreePatchPlant); + kastoriFruitStep.addStep(kastoriFruitStates.getIsHarvestable(), kastoriFruitTreePatchClear); + kastoriFruitStep.addStep(kastoriFruitStates.getIsStump(), kastoriFruitTreePatchDig); + kastoriFruitStep.addStep(nor(usingCompostorNothing, kastoriFruitStates.getIsProtected()), kastoriFruitProtect); + + kastoriCalquatStep = (ConditionalStep) new ConditionalStep(this, kastoriCalquatPatchCheckHealth).withId(132); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsUnchecked(), kastoriCalquatPatchCheckHealth); + kastoriCalquatStep.addStep(and(kastoriCalquatStates.getIsHarvestable(), not(payingForRemoval)), kastoriCalquatPatchRemove); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsEmpty(), kastoriCalquatPatchPlant); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsHarvestable(), kastoriCalquatPatchClear); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsStump(), kastoriCalquatPatchDig); + kastoriCalquatStep.addStep(nor(usingCompostorNothing, kastoriCalquatStates.getIsProtected()), kastoriCalquatProtect); + + + kastoriStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + kastoriStep.addStep(not(kastoriFruitStates.getIsGrowing()), kastoriFruitStep); + kastoriStep.addStep(not(kastoriCalquatStates.getIsGrowing()), kastoriCalquatStep); + steps.addStep(and(accessToVarlamore, nand(kastoriFruitStates.getIsGrowing(), kastoriCalquatStates.getIsGrowing())), kastoriStep.withId(13)); anglersRetreatStep = new ConditionalStep(this, anglersCheckHealth); anglersRetreatStep.addStep(anglersRetreatStates.getIsUnchecked(), anglersCheckHealth); + anglersRetreatStep.addStep(and(anglersRetreatStates.getIsHarvestable(), not(payingForRemoval)), anglersCutDown); anglersRetreatStep.addStep(anglersRetreatStates.getIsEmpty(), anglersPlant); anglersRetreatStep.addStep(anglersRetreatStates.getIsHarvestable(), anglersClear); anglersRetreatStep.addStep(anglersRetreatStates.getIsStump(), anglersDig); anglersRetreatStep.addStep(nor(usingCompostorNothing, anglersRetreatStates.getIsProtected()), anglersProtect); - - steps.addStep(and(accessToAnglersRetreat, nor(anglersRetreatStates.getIsGrowing())), - anglersRetreatStep.withId(14)); + steps.addStep(and(accessToAnglersRetreat, not(anglersRetreatStates.getIsGrowing())), anglersRetreatStep.withId(14)); greatConchStep = new ConditionalStep(this, greatConchCalquatPatchCheckHealth); greatConchStep.addStep(greatConchStates.getIsUnchecked(), greatConchCalquatPatchCheckHealth); + greatConchStep.addStep(and(greatConchStates.getIsHarvestable(), not(payingForRemoval)), greatConchCalquatPatchRemove); greatConchStep.addStep(greatConchStates.getIsEmpty(), greatConchCalquatPatchPlant); greatConchStep.addStep(greatConchStates.getIsHarvestable(), greatConchCalquatPatchClear); greatConchStep.addStep(greatConchStates.getIsStump(), greatConchCalquatPatchDig); greatConchStep.addStep(nor(usingCompostorNothing, greatConchStates.getIsProtected()), greatConchCalquatProtect); - - steps.addStep(and(accessToGreatConch, nor(greatConchStates.getIsGrowing())), - greatConchStep.withId(15)); + steps.addStep(and(accessToGreatConch, not(greatConchStates.getIsGrowing())), greatConchStep.withId(15)); return steps; } @@ -425,7 +466,8 @@ private void setupConditions() gnomeStrongholdFruitStates = new PatchStates("Gnome Stronghold"); lletyaStates = new PatchStates("Lletya", accessToLletya); farmingGuildFruitStates = new PatchStates("Farming Guild", accessToFarmingGuildFruitTreePatch); - kastoriStates = new PatchStates("Kastori", accessToVarlamore); + kastoriFruitStates = new PatchStates("Kastori", accessToVarlamore); + kastoriCalquatStates = new PatchStates("Kastori", accessToVarlamore); greatConchStates = new PatchStates("Great Conch", accessToGreatConch); westHardwoodStates = new PatchStates("Fossil Island", "West"); @@ -440,7 +482,8 @@ private void setupConditions() gnomeStrongholdFruitStates.getIsGrowing(), or(not(accessToLletya), lletyaStates.getIsGrowing()), or(not(accessToVarlamore), auburnvaleStates.getIsGrowing()), - or(not(accessToVarlamore), kastoriStates.getIsGrowing()), + or(not(accessToVarlamore), kastoriFruitStates.getIsGrowing()), + or(not(accessToVarlamore), kastoriCalquatStates.getIsGrowing()), or(not(accessToFarmingGuildTreePatch), farmingGuildTreeStates.getIsGrowing()), or(not(accessToFarmingGuildFruitTreePatch), farmingGuildFruitStates.getIsGrowing()), or(not(accessToFossilIsland), and(westHardwoodStates.getIsGrowing(), middleHardwoodStates.getIsGrowing(), eastHardwoodStates.getIsGrowing())), @@ -465,7 +508,7 @@ public void setupRequirements() .hideConditioned(new VarbitRequirement(VarbitID.FARMING_BLOCKWEEDS, 2)); coins = new ItemRequirement("Coins to quickly remove trees.", ItemID.COINS) .showConditioned(payingForRemoval); - axe = new ItemRequirement("Any axe you can use", ItemCollections.AXES); + axe = new ItemRequirement("Any axe", ItemCollections.AXES).isNotConsumed().showConditioned(not(payingForRemoval)); TreeSapling treeSaplingEnum = (TreeSapling) FarmingUtils.getEnumFromConfig(configManager, TreeSapling.MAGIC); treeSapling = treeSaplingEnum.getPlantableItemRequirement(itemManager); @@ -578,59 +621,73 @@ private void setupSteps() lumbridgeTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_4, new WorldPoint(3193, 3231, 0), "Speak to Fayeth to clear the patch."); + lumbridgeTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); lumbridgeTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); faladorTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_2, new WorldPoint(3004, 3373, 0), "Speak to Heskel to clear the patch."); + faladorTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); faladorTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); taverleyTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_1, new WorldPoint(2936, 3438, 0), "Speak to Alain to clear the patch."); + taverleyTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); taverleyTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); varrockTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_3_02, new WorldPoint(3229, 3459, 0), "Speak to Treznor to clear the patch."); + varrockTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); varrockTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); gnomeStrongholdTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_GNOME, new WorldPoint(2436, 3415, 0), "Speak to Prissy Scilla to clear the patch."); + gnomeStrongholdTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); gnomeStrongholdTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); farmingGuildTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T2, new WorldPoint(1232, 3736, 0), "Speak to Rosie to clear the patch."); + farmingGuildTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); farmingGuildTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); auburnvaleTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_7, new WorldPoint(1367, 3322, 0), "Speak to Aub to clear the patch."); + auburnvaleTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); auburnvaleTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); lumbridgeTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_4, new WorldPoint(3193, 3231, 0), "Speak to Fayeth to protect the patch."); - lumbridgeTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + lumbridgeTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + lumbridgeTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); faladorTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_2, new WorldPoint(3004, 3373, 0), "Speak to Heskel to protect the patch."); - faladorTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + faladorTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + faladorTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); taverleyTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_1, new WorldPoint(2936, 3438, 0), "Speak to Alain to protect the patch."); - taverleyTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + taverleyTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + taverleyTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); varrockTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_3_02, new WorldPoint(3229, 3459, 0), "Speak to Treznor to protect the patch."); - varrockTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + varrockTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + varrockTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); strongholdTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_GNOME, new WorldPoint(2436, 3415, 0), "Speak to Prissy Scilla to protect the patch."); - strongholdTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + strongholdTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + strongholdTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); farmingGuildTreePayForProtection = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T2, new WorldPoint(1232, 3736, 0), "Speak to Rosie to protect the patch."); - farmingGuildTreePayForProtection.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + farmingGuildTreePayForProtection.conditionToHideInSidebar(not(payingForProtection)); + farmingGuildTreePayForProtection.addDialogSteps(TREE_PROTECTION_DIALOG); auburnvaleTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_7, new WorldPoint(1367, 3322, 0), "Speak to Aub to protect the patch."); - auburnvaleTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + auburnvaleTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + auburnvaleTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); // Tree Patch Steps lumbridgeTreePatchCheckHealth = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), @@ -660,6 +717,44 @@ private void setupSteps() auburnvaleTreePatchCheckHealth.conditionToHideInSidebar(new Conditions(LogicType.NOR, accessToVarlamore)); auburnvaleTreePatchCheckHealth.addTeleport(auburnvaleTeleport); + // Tree Cut Down Steps + farmingGuildTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_6, new WorldPoint(1232, 3736, 0), + "Cut down the tree planted in the Farming Guild.", axe); + farmingGuildTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToFarmingGuildTreePatch), payingForRemoval)); + farmingGuildTreePatchCutDown.addTeleport(farmingGuildTeleport); + + lumbridgeTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), + "Cut down the tree planted in Lumbridge.", axe); + lumbridgeTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + lumbridgeTreePatchCutDown.addTeleport(lumbridgeTeleport); + lumbridgeTreePatchCutDown.addSpellHighlight(NormalSpells.LUMBRIDGE_TELEPORT); + lumbridgeTreePatchCutDown.addSpellHighlight(NormalSpells.LUMBRIDGE_HOME_TELEPORT); + + faladorTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_2, new WorldPoint(3004, 3373, 0), + "Cut down the tree planted in Falador.", axe); + faladorTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + faladorTreePatchCutDown.addTeleport(faladorTeleport); + faladorTreePatchCutDown.addSpellHighlight(NormalSpells.FALADOR_TELEPORT); + + taverleyTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_1, new WorldPoint(2936, 3438, 0), + "Cut down the tree planted in Taverley.", axe); + taverleyTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + varrockTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_3, new WorldPoint(3229, 3459, 0), + "Cut down the tree planted in Varrock.", axe); + varrockTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + varrockTreePatchCutDown.addTeleport(varrockTeleport); + varrockTreePatchCutDown.addSpellHighlight(NormalSpells.VARROCK_TELEPORT); + + gnomeStrongholdTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_5, new WorldPoint(2436, 3415, 0), + "Cut down the tree planted in the Tree Gnome Stronghold.", axe); + gnomeStrongholdTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + auburnvaleTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_7, new WorldPoint(1367, 3322, 0), + "Cut down the tree planted at Auburnvale.", axe); + auburnvaleTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToVarlamore), payingForRemoval)); + auburnvaleTreePatchCutDown.addTeleport(auburnvaleTeleport); + // Tree Plant Steps lumbridgeTreePatchPlant = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), "Plant your sapling in the Lumbridge patch.", treeSapling); @@ -701,26 +796,33 @@ private void setupSteps() // Dig lumbridgeTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), "Dig up the tree stump in Lumbridge."); + lumbridgeTreePatchDig.conditionToHideInSidebar(payingForRemoval); faladorTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_2, new WorldPoint(3004, 3373, 0), "Dig up the tree stump in Falador."); + faladorTreePatchDig.conditionToHideInSidebar(payingForRemoval); taverleyTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_1, new WorldPoint(2936, 3438, 0), "Dig up the tree stump in Taverley."); + taverleyTreePatchDig.conditionToHideInSidebar(payingForRemoval); varrockTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_3, new WorldPoint(3229, 3459, 0), "Dig up the tree stump in Varrock."); + varrockTreePatchDig.conditionToHideInSidebar(payingForRemoval); gnomeStrongholdTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_5, new WorldPoint(2436, 3415, 0), "Dig up the tree stump in the Tree Gnome Stronghold."); + gnomeStrongholdTreePatchDig.conditionToHideInSidebar(payingForRemoval); farmingGuildTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_6, new WorldPoint(1232, 3736, 0), "Dig up the tree stump in the Farming Guild tree patch."); + farmingGuildTreePatchDig.conditionToHideInSidebar(payingForRemoval); auburnvaleTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_7, new WorldPoint(1367, 3322, 0), "Dig up the tree stump in the Auburnvale tree patch."); + auburnvaleTreePatchDig.conditionToHideInSidebar(payingForRemoval); - faladorTreePatchClear.addSubSteps(faladorTreePatchDig, faladorTreeProtect); - taverleyTreePatchClear.addSubSteps(taverleyTreePatchDig, taverleyTreeProtect); - varrockTreePatchClear.addSubSteps(varrockTreePatchDig, varrockTreeProtect); - gnomeStrongholdTreePatchClear.addSubSteps(gnomeStrongholdTreePatchDig, strongholdTreeProtect); - lumbridgeTreePatchClear.addSubSteps(lumbridgeTreePatchDig, lumbridgeTreeProtect); - farmingGuildTreePatchClear.addSubSteps(farmingGuildTreePatchDig, farmingGuildTreePayForProtection); - auburnvaleTreePatchClear.addSubSteps(auburnvaleTreePatchDig, auburnvaleTreeProtect); + faladorTreePatchClear.addSubSteps(faladorTreePatchDig); + taverleyTreePatchClear.addSubSteps(taverleyTreePatchDig); + varrockTreePatchClear.addSubSteps(varrockTreePatchDig); + gnomeStrongholdTreePatchClear.addSubSteps(gnomeStrongholdTreePatchDig); + lumbridgeTreePatchClear.addSubSteps(lumbridgeTreePatchDig); + farmingGuildTreePatchClear.addSubSteps(farmingGuildTreePatchDig); + auburnvaleTreePatchClear.addSubSteps(auburnvaleTreePatchDig); // Fruit Tree Steps @@ -833,106 +935,192 @@ private void setupSteps() greatConchCalquatPatchCheckHealth.addWidgetHighlightWithTextRequirement(187, 3, "Great Conch", true); greatConchCalquatPatchCheckHealth.addSubSteps(greatConchCalquatPatchPlant); + // Fruit Tree Cut Down Steps + gnomeStrongholdFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_1, new WorldPoint(2476, 3446, 0), + "Cut down the fruit tree planted in the Tree Gnome Stronghold.", axe); + gnomeStrongholdFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + gnomeStrongholdFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Gnome Stronghold", true); + + gnomeVillageFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_2, new WorldPoint(2490, 3180, 0), + "Cut down the fruit tree planted outside the Tree Gnome Village.", axe); + gnomeVillageFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + gnomeVillageFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Tree Gnome Village", true); + + brimhavenFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_3, new WorldPoint(2765, 3213, 0), + "Cut down the fruit tree planted in Brimhaven.", axe); + brimhavenFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + brimhavenFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(InterfaceID.MENU, InterfaceID.Menu.LJ_LAYER1 & 0xFFFF, "Brimhaven", true); + brimhavenFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(InterfaceID.CHARTERING_MENU_SIDE, InterfaceID.CharteringMenuSide.LIST_CONTENT & 0xFFFF, "Brimhaven", true); + brimhavenFruitTreePatchCutDown.addWidgetHighlight(new WidgetHighlight(InterfaceID.SAILING_MENU, InterfaceID.SailingMenu.CONTENT & 0xFFFF, 2)); + + catherbyFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_4, new WorldPoint(2860, 3433, 0), + "Cut down the fruit tree planted in Catherby.", axe); + catherbyFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + catherbyFruitTreePatchCutDown.addTeleport(catherbyTeleport); + catherbyFruitTreePatchCutDown.addSpellHighlight(NormalSpells.CAMELOT_TELEPORT); + catherbyFruitTreePatchCutDown.addSpellHighlight(LunarSpells.CATHERBY_TELEPORT); + + lletyaFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_5, new WorldPoint(2347, 3162, 0), + "Cut down the fruit tree planted in Lletya.", axe); + lletyaFruitTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToLletya), payingForRemoval)); + lletyaFruitTreePatchCutDown.addTeleport(crystalTeleport); + + farmingGuildFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_6, new WorldPoint(1242, 3758, 0), + "Cut down the fruit tree planted in the Farming Guild.", axe); + farmingGuildFruitTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToFarmingGuildFruitTreePatch), payingForRemoval)); + farmingGuildFruitTreePatchCutDown.addTeleport(farmingGuildTeleport); + farmingGuildFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Farming Guild", true); + + kastoriFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_7, new WorldPoint(1350, 3057, 0), + "Cut down the fruit tree planted in Kastori.", axe); + kastoriFruitTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToVarlamore), payingForRemoval)); + kastoriFruitTreePatchCutDown.addTeleport(kastoriTeleport); + kastoriFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Kastori", true); + + taiBwoWannaiCalquatPatchRemove = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH, new WorldPoint(2795, 3102, 0), + "Pick the fruit off the calquat and clear the patch in Tai Bwo Wannai."); + taiBwoWannaiCalquatPatchRemove.conditionToHideInSidebar(payingForRemoval); + taiBwoWannaiCalquatPatchRemove.addWidgetHighlightWithTextRequirement(187, 3, "Tai Bwo Wannai", true); + + kastoriCalquatPatchRemove = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_2, new WorldPoint(1366, 3033, 0), + "Pick the fruit off the calquat and clear the patch in Kastori."); + kastoriCalquatPatchRemove.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToVarlamore), payingForRemoval)); + kastoriCalquatPatchRemove.addTeleport(kastoriTeleport); + kastoriCalquatPatchRemove.addWidgetHighlightWithTextRequirement(187, 3, "Kastori", true); + + greatConchCalquatPatchRemove = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_3, new WorldPoint(3129, 2406, 0), + "Pick the fruit off the calquat and clear the patch in Great Conch."); + greatConchCalquatPatchRemove.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToGreatConch), payingForRemoval)); + greatConchCalquatPatchRemove.addWidgetHighlightWithTextRequirement(187, 3, "Great Conch", true); + // Clear gnomeStrongholdFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_1, new WorldPoint(2476, 3446, 0), "Pay Bolongo 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + gnomeStrongholdFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); gnomeStrongholdFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); gnomeVillageFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_2, new WorldPoint(2490, 3180, 0), "Pay Gileth 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + gnomeVillageFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); gnomeVillageFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); brimhavenFruitTreePatchClear = new NpcStep(this, NpcID.GARTH, new WorldPoint(2765, 3213, 0), "Pay Garth 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + brimhavenFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); brimhavenFruitTreePatchClear.addWidgetHighlightWithTextRequirement(InterfaceID.MENU, InterfaceID.Menu.LJ_LAYER1 & 0xFFFF, "Brimhaven", true); brimhavenFruitTreePatchClear.addWidgetHighlightWithTextRequirement(InterfaceID.CHARTERING_MENU_SIDE, InterfaceID.CharteringMenuSide.LIST_CONTENT & 0xFFFF, "Brimhaven", true); brimhavenFruitTreePatchClear.addWidgetHighlight(new WidgetHighlight(InterfaceID.SAILING_MENU, InterfaceID.SailingMenu.CONTENT & 0xFFFF, 2)); brimhavenFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); catherbyFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_4, new WorldPoint(2860, 3433, 0), "Pay Ellena 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + catherbyFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); catherbyFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); lletyaFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_TREE_5, new WorldPoint(2347, 3162, 0), "Pay Liliwen 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + lletyaFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); lletyaFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); farmingGuildFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T3, new WorldPoint(1243, 3760, 0), "Pay Nikkie 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + farmingGuildFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); farmingGuildFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); kastoriFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_7, new WorldPoint(1350, 3057, 0), "Pay Ehecatl 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + kastoriFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); kastoriFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); taiBwoWannaiCalquatPatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT, new WorldPoint(2795, 3102, 0), "Pay Imiago 200 coins to clear the calquat tree, or pick all the fruit and cut it down."); + taiBwoWannaiCalquatPatchClear.conditionToHideInSidebar(not(payingForRemoval)); taiBwoWannaiCalquatPatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); kastoriCalquatPatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_2, new WorldPoint(1366, 3033, 0), "Pay Tziuhtla 200 coins to clear the calquat tree, or pick all the fruit and cut it down."); + kastoriCalquatPatchClear.conditionToHideInSidebar(not(payingForRemoval)); kastoriCalquatPatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); greatConchCalquatPatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_3, new WorldPoint(3129, 2406, 0), "Pay Guppa 200 coins to clear the calquat tree, or pick all the fruit and cut it down."); + greatConchCalquatPatchClear.conditionToHideInSidebar(not(payingForRemoval)); greatConchCalquatPatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); strongholdFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_1, new WorldPoint(2476, 3446, 0), "Pay Bolongo to protect the patch."); - strongholdFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + strongholdFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + strongholdFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); villageFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_2, new WorldPoint(2490, 3180, 0), "Pay Gileth to protect the patch."); - villageFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + villageFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + villageFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); brimhavenFruitProtect = new NpcStep(this, NpcID.GARTH, new WorldPoint(2765, 3213, 0), "Pay Garth to protect the patch."); - brimhavenFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + brimhavenFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + brimhavenFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); catherbyFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_4, new WorldPoint(2860, 3433, 0), "Pay Ellena to protect the patch."); - catherbyFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + catherbyFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + catherbyFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); lletyaFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_TREE_5, new WorldPoint(2347, 3162, 0), "Pay Liliwen to protect the patch."); - lletyaFruitProtect.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - " + - "chop my tree down please.", "Yes."); + lletyaFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + lletyaFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); guildFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T3, new WorldPoint(1243, 3760, 0), "Pay Nikkie to protect the patch."); - guildFruitProtect.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - " + - "chop my tree down please.", "Yes."); + guildFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + guildFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); kastoriFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_7, new WorldPoint(1350, 3057, 0), "Pay Ehecatl to protect the patch."); - kastoriFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + kastoriFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + kastoriFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); taiBwoWannaiCalquatProtect = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT, new WorldPoint(2795, 3102, 0), "Pay Imiago to protect the patch."); - taiBwoWannaiCalquatProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + taiBwoWannaiCalquatProtect.conditionToHideInSidebar(not(payingForProtection)); + taiBwoWannaiCalquatProtect.addDialogSteps(TREE_PROTECTION_DIALOG); kastoriCalquatProtect = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_2, new WorldPoint(1366, 3033, 0), "Pay Tziuhtla to protect the patch."); - kastoriCalquatProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + kastoriCalquatProtect.conditionToHideInSidebar(not(payingForProtection)); + kastoriCalquatProtect.addDialogSteps(TREE_PROTECTION_DIALOG); greatConchCalquatProtect = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_3, new WorldPoint(3129, 2406, 0), "Pay Guppa to protect the patch."); - greatConchCalquatProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + greatConchCalquatProtect.conditionToHideInSidebar(not(payingForProtection)); + greatConchCalquatProtect.addDialogSteps(TREE_PROTECTION_DIALOG); // Dig Fruit Tree Steps gnomeStrongholdFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_1, new WorldPoint(2476, 3446, 0), "Dig up the fruit tree's stump in the Tree Gnome Stronghold."); + gnomeStrongholdFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); gnomeVillageFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_2, new WorldPoint(2490, 3180, 0), "Dig up the fruit tree's stump outside the Tree Gnome Village."); + gnomeVillageFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); brimhavenFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_3, new WorldPoint(2765, 3213, 0), "Dig up the fruit tree's stump in Brimhaven."); + brimhavenFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); catherbyFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_4, new WorldPoint(2860, 3433, 0), "Check the health of the fruit tree planted in Catherby"); + catherbyFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); lletyaFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_5, new WorldPoint(2347, 3162, 0), "Dig up the fruit tree's stump in Lletya."); + lletyaFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); farmingGuildFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_6, new WorldPoint(1242, 3758, 0), "Dig up the fruit tree's stump in the Farming Guild."); + farmingGuildFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); kastoriFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_7, new WorldPoint(1350, 3057, 0), "Dig up the fruit tree's stump in Kastori."); + kastoriFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); taiBwoWannaiCalquatPatchDig = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH, new WorldPoint(2795, 3102, 0), "Dig up the calquat tree's stump in Tai Bwo Wannai."); + taiBwoWannaiCalquatPatchDig.conditionToHideInSidebar(payingForRemoval); kastoriCalquatPatchDig = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_2, new WorldPoint(1366, 3033, 0), "Dig up the calquat tree's stump in Kastori."); + kastoriCalquatPatchDig.conditionToHideInSidebar(payingForRemoval); greatConchCalquatPatchDig = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_3, new WorldPoint(3129, 2406, 0), "Dig up the calquat tree's stump in Great Conch."); - - gnomeStrongholdFruitTreePatchClear.addSubSteps(gnomeStrongholdFruitTreePatchDig, strongholdFruitProtect); - gnomeVillageFruitTreePatchClear.addSubSteps(gnomeVillageFruitTreePatchDig, villageFruitProtect); - brimhavenFruitTreePatchClear.addSubSteps(brimhavenFruitTreePatchDig, brimhavenFruitProtect); - catherbyFruitTreePatchClear.addSubSteps(catherbyFruitTreePatchDig, catherbyFruitProtect); - lletyaFruitTreePatchClear.addSubSteps(lletyaFruitTreePatchDig, lletyaFruitProtect); - farmingGuildFruitTreePatchClear.addSubSteps(farmingGuildFruitTreePatchDig, guildFruitProtect); - kastoriFruitTreePatchClear.addSubSteps(kastoriFruitTreePatchDig, kastoriFruitProtect); - taiBwoWannaiCalquatPatchClear.addSubSteps(taiBwoWannaiCalquatPatchDig, taiBwoWannaiCalquatProtect); - kastoriCalquatPatchClear.addSubSteps(kastoriCalquatPatchDig, kastoriCalquatProtect); - greatConchCalquatPatchClear.addSubSteps(greatConchCalquatPatchDig, greatConchCalquatProtect); + greatConchCalquatPatchDig.conditionToHideInSidebar(payingForRemoval); + + gnomeStrongholdFruitTreePatchClear.addSubSteps(gnomeStrongholdFruitTreePatchDig); + gnomeVillageFruitTreePatchClear.addSubSteps(gnomeVillageFruitTreePatchDig); + brimhavenFruitTreePatchClear.addSubSteps(brimhavenFruitTreePatchDig); + catherbyFruitTreePatchClear.addSubSteps(catherbyFruitTreePatchDig); + lletyaFruitTreePatchClear.addSubSteps(lletyaFruitTreePatchDig); + farmingGuildFruitTreePatchClear.addSubSteps(farmingGuildFruitTreePatchDig); + kastoriFruitTreePatchClear.addSubSteps(kastoriFruitTreePatchDig); + taiBwoWannaiCalquatPatchClear.addSubSteps(taiBwoWannaiCalquatPatchDig); + kastoriCalquatPatchClear.addSubSteps(kastoriCalquatPatchDig); + greatConchCalquatPatchClear.addSubSteps(greatConchCalquatPatchDig); // Hardwood Tree Steps westHardwoodTreePatchCheckHealth = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_3, new WorldPoint(3702, 3837, 0), @@ -968,56 +1156,97 @@ private void setupSteps() anglersPlant = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_5, new WorldPoint(2470, 2704, 0), "Plant your sapling on the hardwood tree patch on Anglers' Retreat.", hardwoodSapling); + // Hardwood Tree Cut Down Steps + eastHardwoodTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_1, new WorldPoint(3715, 3835, 0), + "Cut down the hardwood tree planted on the eastern hardwood tree patch on Fossil Island.", axe); + eastHardwoodTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + middleHardwoodTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_2, new WorldPoint(3708, 3833, 0), + "Cut down the hardwood tree planted on the centre hardwood tree patch on Fossil Island.", axe); + middleHardwoodTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + westHardwoodTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_3, new WorldPoint(3702, 3837, 0), + "Cut down the hardwood tree planted on the western hardwood tree patch on Fossil Island.", axe); + westHardwoodTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + savannahCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_4, new WorldPoint(1687, 2972, 0), + "Cut down the hardwood tree planted in the Avium Savannah.", axe); + savannahCutDown.conditionToHideInSidebar(payingForRemoval); + + anglersCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_5, new WorldPoint(2470, 2704, 0), + "Cut down the hardwood tree planted in the Anglers' Retreat.", axe); + anglersCutDown.conditionToHideInSidebar(payingForRemoval); + westHardwoodTreePatchClear = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER3, new WorldPoint(3702, 3837, 0), "Pay the brown squirrel to remove the west tree."); + westHardwoodTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); westHardwoodTreePatchClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); middleHardwoodTreePatchClear = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER2, new WorldPoint(3702, 3837, 0), "Pay the black squirrel to remove the middle tree."); + middleHardwoodTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); middleHardwoodTreePatchClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); eastHardwoodTreePatchClear = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER1, new WorldPoint(3702, 3837, 0), "Pay the grey squirrel to remove the east tree."); + eastHardwoodTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); eastHardwoodTreePatchClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); savannahClear = new NpcStep(this, NpcID.FROG_QUEST_MARCELLUS_FARMER, new WorldPoint(1687, 2972, 0), "Pay Marcellus to clear the tree."); + savannahClear.conditionToHideInSidebar(not(payingForRemoval)); savannahClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); anglersClear = new NpcStep(this, NpcID.FARMING_GARDENER_HARDWOOD_TREE_5, new WorldPoint(2470, 2704, 0), "Pay Argo to clear the tree."); + anglersClear.conditionToHideInSidebar(not(payingForRemoval)); anglersClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); westHardwoodTreePatchDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_3, new WorldPoint(3702, 3837, 0), "Dig up the western hardwood tree's stump on Fossil Island."); + westHardwoodTreePatchDig.conditionToHideInSidebar(payingForRemoval); middleHardwoodTreePatchDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_2, new WorldPoint(3708, 3833, 0), "Dig up the centre hardwood tree's stump on Fossil Island."); + middleHardwoodTreePatchDig.conditionToHideInSidebar(payingForRemoval); eastHardwoodTreePatchDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_1, new WorldPoint(3715, 3835, 0), "Dig up the eastern hardwood tree's stump on Fossil Island."); + eastHardwoodTreePatchDig.conditionToHideInSidebar(payingForRemoval); savannahDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_4, new WorldPoint(1687, 2972, 0), "Dig up the Savannah hardwood tree's stump."); + savannahDig.conditionToHideInSidebar(payingForRemoval); anglersDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_5, new WorldPoint(2470,2704, 0), "Dig up the Anglers' Retreat hardwood tree's stump."); + anglersDig.conditionToHideInSidebar(payingForRemoval); westHardwoodProtect = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER3, new WorldPoint(3702, 3837, 0), "Pay the brown squirrel to protect the west tree."); + westHardwoodProtect.conditionToHideInSidebar(not(payingForProtection)); + westHardwoodProtect.addDialogSteps(TREE_PROTECTION_DIALOG); middleHardwoodProtect = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER2, new WorldPoint(3702, 3837, 0), "Pay the black squirrel to protect the middle tree."); + middleHardwoodProtect.conditionToHideInSidebar(not(payingForProtection)); + middleHardwoodProtect.addDialogSteps(TREE_PROTECTION_DIALOG); eastHardwoodProtect = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER1, new WorldPoint(3702, 3837, 0), "Pay the grey squirrel to protect the east tree."); + eastHardwoodProtect.conditionToHideInSidebar(not(payingForProtection)); + eastHardwoodProtect.addDialogSteps(TREE_PROTECTION_DIALOG); savannahProtect = new NpcStep(this, NpcID.FROG_QUEST_MARCELLUS_FARMER, new WorldPoint(1687, 2972, 0), "Pay Marcellus to protect the hardwood tree."); + savannahProtect.conditionToHideInSidebar(not(payingForProtection)); + savannahProtect.addDialogSteps(TREE_PROTECTION_DIALOG); anglersProtect = new NpcStep(this, NpcID.FARMING_GARDENER_HARDWOOD_TREE_5, new WorldPoint(2470, 2704, 0), "Pay Argo to protect the hardwood tree."); - - westHardwoodTreePatchClear.addSubSteps(westHardwoodTreePatchDig, westHardwoodProtect); - middleHardwoodTreePatchClear.addSubSteps(middleHardwoodTreePatchDig, middleHardwoodProtect); - eastHardwoodTreePatchClear.addSubSteps(eastHardwoodTreePatchDig, eastHardwoodProtect); - savannahClear.addSubSteps(savannahDig, savannahProtect); - anglersClear.addSubSteps(anglersDig, anglersProtect); + anglersProtect.conditionToHideInSidebar(not(payingForProtection)); + anglersProtect.addDialogSteps(TREE_PROTECTION_DIALOG); + + westHardwoodTreePatchClear.addSubSteps(westHardwoodTreePatchDig); + middleHardwoodTreePatchClear.addSubSteps(middleHardwoodTreePatchDig); + eastHardwoodTreePatchClear.addSubSteps(eastHardwoodTreePatchDig); + savannahClear.addSubSteps(savannahDig); + anglersClear.addSubSteps(anglersDig); } @Subscribe @@ -1033,10 +1262,10 @@ public void onGameTick(GameTick event) farmingWorld.getTabs().get(Tab.TREE), allTreeSaplings, allProtectionItemTree); handleTreePatches(PatchImplementation.FRUIT_TREE, List.of(farmingGuildFruitStates, brimhavenStates, catherbyStates, gnomeStrongholdFruitStates, gnomeVillageStates, lletyaStates, - kastoriStates), + kastoriFruitStates), farmingWorld.getTabs().get(Tab.FRUIT_TREE), allFruitSaplings, allProtectionItemFruitTree); handleTreePatches(PatchImplementation.CALQUAT, - List.of(taiBwoWannaiStates, kastoriStates, greatConchStates), + List.of(taiBwoWannaiStates, kastoriCalquatStates, greatConchStates), farmingWorld.getTabs().get(Tab.FRUIT_TREE), allCalquatSaplings, allProtectionItemCalquat); handleTreePatches(PatchImplementation.HARDWOOD_TREE, List.of(westHardwoodStates, middleHardwoodStates, eastHardwoodStates, savannahStates, anglersRetreatStates), @@ -1058,8 +1287,9 @@ public void handleTreePatches(PatchImplementation implementation, List getConfigs() @Override public List getItemRequirements() { - return Arrays.asList(spade, rake, compost, coins, allTreeSaplings, allFruitSaplings, allHardwoodSaplings, allCalquatSaplings, allProtectionItemTree, allProtectionItemFruitTree, allProtectionItemHardwood, allProtectionItemCalquat); + return Arrays.asList(spade, rake, compost, coins, axe, allTreeSaplings, allFruitSaplings, allHardwoodSaplings, allCalquatSaplings, allProtectionItemTree, allProtectionItemFruitTree, allProtectionItemHardwood, allProtectionItemCalquat); } @Override @@ -1151,70 +1381,97 @@ public List getPanels() // IDEA: Can add ID to each step. onLoad and onConfigChanged it checks id ordering. List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Wait for Herbs", waitForTree).withHideCondition(nor(allGrowing))); + allSteps.add(new PanelDetails("Wait for Trees", waitForTree).withHideCondition(nor(allGrowing))); - PanelDetails farmingGuildPanel = new PanelDetails("Farming Guild", Arrays.asList(farmingGuildTreePatchCheckHealth, farmingGuildTreePatchClear, - farmingGuildTreePatchPlant, farmingGuildFruitTreePatchCheckHealth, farmingGuildFruitTreePatchClear, - farmingGuildTreePatchPlant)).withId(0); + PanelDetails farmingGuildTreePanel = new PanelDetails("Tree Patch", + Arrays.asList(farmingGuildTreePatchCheckHealth, farmingGuildTreePatchCutDown, farmingGuildTreePatchDig, farmingGuildTreePatchClear, farmingGuildTreePatchPlant, farmingGuildTreePayForProtection)).withId(-1); + farmingGuildTreePanel.setLockingStep(farmingGuildTreeStep); + PanelDetails farmingGuildFruitPanel = new PanelDetails("Fruit Tree Patch", + Arrays.asList(farmingGuildFruitTreePatchCheckHealth, farmingGuildFruitTreePatchCutDown, farmingGuildFruitTreePatchDig, farmingGuildFruitTreePatchClear, farmingGuildFruitTreePatchPlant, guildFruitProtect)).withId(-2); + farmingGuildFruitPanel.setLockingStep((farmingGuildFruitStep)); + var farmingGuildPanel = new TopLevelPanelDetails("Farming Guild", + farmingGuildTreePanel, farmingGuildFruitPanel).withId(0); farmingGuildPanel.setLockingStep(farmingGuildStep); - PanelDetails lumbridgePanel = new PanelDetails("Lumbridge", Arrays.asList(lumbridgeTreePatchCheckHealth, lumbridgeTreePatchClear, lumbridgeTreePatchPlant)).withId(1); + PanelDetails lumbridgePanel = new PanelDetails("Lumbridge", Arrays.asList(lumbridgeTreePatchCheckHealth, lumbridgeTreePatchCutDown, lumbridgeTreePatchDig, lumbridgeTreePatchClear, lumbridgeTreePatchPlant, lumbridgeTreeProtect)).withId(1); lumbridgePanel.setLockingStep(lumbridgeStep); - PanelDetails faladorPanel = new PanelDetails("Falador", Arrays.asList(faladorTreePatchCheckHealth, faladorTreePatchClear, faladorTreePatchPlant)).withId(2); + PanelDetails faladorPanel = new PanelDetails("Falador", Arrays.asList(faladorTreePatchCheckHealth, faladorTreePatchCutDown, faladorTreePatchDig, faladorTreePatchClear, faladorTreePatchPlant, faladorTreeProtect)).withId(2); faladorPanel.setLockingStep(faladorStep); - PanelDetails taverleyPanel = new PanelDetails("Taverley", Arrays.asList(taverleyTreePatchCheckHealth, taverleyTreePatchClear, taverleyTreePatchPlant)).withId(3); + PanelDetails taverleyPanel = new PanelDetails("Taverley", Arrays.asList(taverleyTreePatchCheckHealth, taverleyTreePatchCutDown, taverleyTreePatchDig, taverleyTreePatchClear, taverleyTreePatchPlant, taverleyTreeProtect)).withId(3); taverleyPanel.setLockingStep(taverleyStep); - PanelDetails varrockPanel = new PanelDetails("Varrock", Arrays.asList(varrockTreePatchCheckHealth, varrockTreePatchClear, varrockTreePatchPlant)).withId(4); + PanelDetails varrockPanel = new PanelDetails("Varrock", Arrays.asList(varrockTreePatchCheckHealth, varrockTreePatchCutDown, varrockTreePatchDig, varrockTreePatchClear, varrockTreePatchPlant, varrockTreeProtect)).withId(4); varrockPanel.setLockingStep(varrockStep); - PanelDetails gnomeStrongholdPanel = new PanelDetails("Gnome Stronghold", Arrays.asList(gnomeStrongholdFruitTreePatchCheckHealth, gnomeStrongholdFruitTreePatchClear, gnomeStrongholdFruitTreePatchPlant, - gnomeStrongholdTreePatchCheckHealth, gnomeStrongholdTreePatchClear, gnomeStrongholdFruitTreePatchPlant)).withId(5); + PanelDetails gnomeStrongholdFruitPanel = new PanelDetails("Fruit Tree Patch", + Arrays.asList(gnomeStrongholdFruitTreePatchCheckHealth, gnomeStrongholdFruitTreePatchCutDown, gnomeStrongholdFruitTreePatchDig, gnomeStrongholdFruitTreePatchClear, gnomeStrongholdFruitTreePatchPlant, strongholdFruitProtect)).withId(51); + gnomeStrongholdFruitPanel.setLockingStep(strongholdFruitStep); + PanelDetails gnomeStrongholdTreePanel = new PanelDetails("Tree Patch", + Arrays.asList(gnomeStrongholdTreePatchCheckHealth, gnomeStrongholdTreePatchCutDown, gnomeStrongholdTreePatchDig, gnomeStrongholdTreePatchClear, gnomeStrongholdTreePatchPlant, strongholdTreeProtect)).withId(52); + gnomeStrongholdTreePanel.setLockingStep(strongholdTreeStep); + var gnomeStrongholdPanel = new TopLevelPanelDetails("Gnome Stronghold", + gnomeStrongholdFruitPanel, gnomeStrongholdTreePanel).withId(5); gnomeStrongholdPanel.setLockingStep(strongholdStep); PanelDetails villagePanel = new PanelDetails("Tree Gnome Village", Arrays.asList(gnomeVillageFruitTreePatchCheckHealth, - gnomeVillageFruitTreePatchClear, gnomeVillageFruitTreePatchPlant)).withId(6); + gnomeVillageFruitTreePatchCutDown, gnomeVillageFruitTreePatchDig, gnomeVillageFruitTreePatchClear, gnomeVillageFruitTreePatchPlant, villageFruitProtect)).withId(6); villagePanel.setLockingStep(villageStep); - PanelDetails catherbyPanel = new PanelDetails("Catherby", Arrays.asList(catherbyFruitTreePatchCheckHealth, catherbyFruitTreePatchClear, catherbyFruitTreePatchPlant)).withId(7); + PanelDetails catherbyPanel = new PanelDetails("Catherby", Arrays.asList(catherbyFruitTreePatchCheckHealth, catherbyFruitTreePatchCutDown, catherbyFruitTreePatchDig, catherbyFruitTreePatchClear, catherbyFruitTreePatchPlant, catherbyFruitProtect)).withId(7); catherbyPanel.setLockingStep(catherbyStep); - PanelDetails brimhavenPanel = new PanelDetails("Brimhaven", Arrays.asList(brimhavenFruitTreePatchCheckHealth, brimhavenFruitTreePatchClear, brimhavenFruitTreePatchPlant, - taiBwoWannaiCalquatPatchCheckHealth, taiBwoWannaiCalquatPatchClear, taiBwoWannaiCalquatPatchPlant)).withId(8); + PanelDetails brimhavenPanel = new PanelDetails("Brimhaven", Arrays.asList(brimhavenFruitTreePatchCheckHealth, brimhavenFruitTreePatchCutDown, brimhavenFruitTreePatchDig, brimhavenFruitTreePatchClear, brimhavenFruitTreePatchPlant, brimhavenFruitProtect)).withId(81); brimhavenPanel.setLockingStep(brimhavenStep); + PanelDetails taiBwoWannaiPanel = new PanelDetails("Tai Bwo Wannai", Arrays.asList(taiBwoWannaiCalquatPatchCheckHealth, taiBwoWannaiCalquatPatchRemove, taiBwoWannaiCalquatPatchDig, taiBwoWannaiCalquatPatchClear, taiBwoWannaiCalquatPatchPlant, taiBwoWannaiCalquatProtect)).withId(82); + taiBwoWannaiPanel.setLockingStep(taiBwoWannaiStep); + var karamjaPanel = new TopLevelPanelDetails("Karamja", brimhavenPanel, taiBwoWannaiPanel).withId(8); + karamjaPanel.setLockingStep(karamjaStep); - PanelDetails lletyaPanel = new PanelDetails("Lletya", Arrays.asList(lletyaFruitTreePatchCheckHealth, lletyaFruitTreePatchClear, lletyaFruitTreePatchPlant)).withId(9); + PanelDetails lletyaPanel = new PanelDetails("Lletya", Arrays.asList(lletyaFruitTreePatchCheckHealth, lletyaFruitTreePatchCutDown, lletyaFruitTreePatchDig, lletyaFruitTreePatchClear, lletyaFruitTreePatchPlant, lletyaFruitProtect)).withId(9); lletyaPanel.setLockingStep(lletyaStep); - PanelDetails fossilIslandPanel = new PanelDetails("Fossil Island", Arrays.asList(eastHardwoodTreePatchCheckHealth, eastHardwoodTreePatchClear, eastHardwoodTreePatchPlant, - middleHardwoodTreePatchCheckHealth, middleHardwoodTreePatchClear, middleHardwoodTreePatchPlant, - westHardwoodTreePatchCheckHealth, westHardwoodTreePatchClear, westHardwoodTreePatchPlant)).withId(10); + PanelDetails fossilIslandEastPanel = new PanelDetails("East Hardwood Patch", + Arrays.asList(eastHardwoodTreePatchCheckHealth, eastHardwoodTreePatchCutDown, eastHardwoodTreePatchDig, eastHardwoodTreePatchClear, eastHardwoodTreePatchPlant, eastHardwoodProtect) + ).withId(101); + fossilIslandEastPanel.setLockingStep(fossilIslandEastStep); + PanelDetails fossilIslandMiddlePanel = new PanelDetails("Middle Hardwood Patch", + Arrays.asList(middleHardwoodTreePatchCheckHealth, middleHardwoodTreePatchCutDown, middleHardwoodTreePatchDig, middleHardwoodTreePatchClear, middleHardwoodTreePatchPlant, middleHardwoodProtect) + ).withId(102); + fossilIslandMiddlePanel.setLockingStep(fossilIslandMiddleStep); + PanelDetails fossilIslandWestPanel = new PanelDetails("West Hardwood Patch", + Arrays.asList(westHardwoodTreePatchCheckHealth, westHardwoodTreePatchCutDown, westHardwoodTreePatchDig, westHardwoodTreePatchClear, westHardwoodTreePatchPlant, westHardwoodProtect) + ).withId(103); + fossilIslandWestPanel.setLockingStep(fossilIslandWestStep); + var fossilIslandPanel = new TopLevelPanelDetails("Fossil Island", + fossilIslandEastPanel, fossilIslandMiddlePanel, fossilIslandWestPanel).withId(10); fossilIslandPanel.setLockingStep(fossilIslandStep); - PanelDetails savannahPanel = new PanelDetails("Avium Savannah", Arrays.asList(savannahCheckHealth, savannahClear, savannahPlant)).withId(11); + PanelDetails savannahPanel = new PanelDetails("Avium Savannah", Arrays.asList(savannahCheckHealth, savannahCutDown, savannahDig, savannahClear, savannahPlant, savannahProtect)).withId(11); savannahPanel.setLockingStep(savannahStep); - PanelDetails auburnvalePanel = new PanelDetails("Auburnvale", Arrays.asList(auburnvaleTreePatchCheckHealth, auburnvaleTreePatchClear, auburnvaleTreePatchPlant)).withId(12); + PanelDetails auburnvalePanel = new PanelDetails("Auburnvale", Arrays.asList(auburnvaleTreePatchCheckHealth, auburnvaleTreePatchCutDown, auburnvaleTreePatchDig, auburnvaleTreePatchClear, auburnvaleTreePatchPlant, auburnvaleTreeProtect)).withId(12); auburnvalePanel.setLockingStep(auburnvaleStep); - PanelDetails kastoriPanel = new PanelDetails("Kastori", Arrays.asList(kastoriFruitTreePatchCheckHealth, - kastoriFruitTreePatchClear, kastoriFruitTreePatchPlant, kastoriCalquatPatchCheckHealth, - kastoriCalquatPatchClear, kastoriCalquatPatchPlant)).withId(13); + PanelDetails kastoriFruitPanel = new PanelDetails("Fruit Tree Patch", Arrays.asList(kastoriFruitTreePatchCheckHealth, kastoriFruitTreePatchCutDown, kastoriFruitTreePatchDig, kastoriFruitTreePatchClear, kastoriFruitTreePatchPlant, kastoriFruitProtect)).withId(131); + kastoriFruitPanel.setLockingStep(kastoriFruitStep); + PanelDetails kastoriCalquatPanel = new PanelDetails("Calquat Patch", Arrays.asList(kastoriCalquatPatchCheckHealth, kastoriCalquatPatchRemove, kastoriCalquatPatchDig, kastoriCalquatPatchClear, kastoriCalquatPatchPlant, kastoriCalquatProtect)).withId(132); + kastoriCalquatPanel.setLockingStep(kastoriCalquatStep); + var kastoriPanel = new TopLevelPanelDetails("Kastori", kastoriFruitPanel, kastoriCalquatPanel).withId(13); kastoriPanel.setLockingStep(kastoriStep); PanelDetails anglersPanel = new PanelDetails("Anglers' Retreat", Arrays.asList(anglersCheckHealth, - anglersClear, anglersPlant)).withId(14); + anglersCutDown, anglersDig, anglersClear, anglersPlant, anglersProtect)).withId(14); anglersPanel.setLockingStep(anglersRetreatStep); PanelDetails greatConchPanel = new PanelDetails("Great Conch", - Arrays.asList(greatConchCalquatPatchCheckHealth, greatConchCalquatPatchClear, - greatConchCalquatPatchPlant)).withId(15); + Arrays.asList(greatConchCalquatPatchCheckHealth, greatConchCalquatPatchRemove, greatConchCalquatPatchDig, greatConchCalquatPatchClear, + greatConchCalquatPatchPlant, greatConchCalquatProtect)).withId(15); greatConchPanel.setLockingStep(greatConchStep); - TopLevelPanelDetails farmRunSidebar = new TopLevelPanelDetails("Tree Run", farmingGuildPanel, lumbridgePanel, faladorPanel, taverleyPanel, - varrockPanel, gnomeStrongholdPanel, villagePanel, catherbyPanel, brimhavenPanel, lletyaPanel, fossilIslandPanel, savannahPanel, auburnvalePanel, + var farmRunSidebar = new TopLevelPanelDetails("Tree Run", farmingGuildPanel, lumbridgePanel, faladorPanel, taverleyPanel, + varrockPanel, gnomeStrongholdPanel, villagePanel, catherbyPanel, karamjaPanel, lletyaPanel, fossilIslandPanel, savannahPanel, auburnvalePanel, kastoriPanel, anglersPanel, greatConchPanel); allSteps.add(farmRunSidebar); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java index 9f44d8b9a67..6ab3754e78b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java @@ -44,7 +44,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java index 08eec560ee3..c32c524cda8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java @@ -31,26 +31,28 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.CombatLevelRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class StrongholdOfSecurity extends BasicQuestHelper { static final String[] CORRECT_ANSWERS = { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java index 9deed8869ec..fd151c9d68c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java @@ -36,62 +36,60 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class APorcineOfInterest extends BasicQuestHelper { - //Items Required - ItemRequirement rope, slashItem, reinforcedGoggles, combatGear, hoof; - - //Items Recommended - ItemRequirement draynorTeleport, faladorFarmTeleport; + // Required items + ItemRequirement rope; + ItemRequirement slashItem; + ItemRequirement combatGear; - Requirement inCave; + // Recommended items + ItemRequirement draynorTeleport; + ItemRequirement faladorFarmTeleport; - DetailedQuestStep readNotice, talkToSarah, useRopeOnHole, enterHole, investigateSkeleton, talkToSpria, enterHoleAgain, killSourhog, - enterHoleForFoot, cutOffFoot, returnToSarah, returnToSpria; + // Mid-quest item requirements + ItemRequirement reinforcedGoggles; + ItemRequirement hoof; - //Zones + // Zones Zone cave; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, readNotice); - steps.put(5, talkToSarah); - steps.put(10, useRopeOnHole); - - ConditionalStep investigateCave = new ConditionalStep(this, enterHole); - investigateCave.addStep(inCave, investigateSkeleton); - - steps.put(15, investigateCave); - - steps.put(20, talkToSpria); + // Miscellaneous requirements + Requirement inCave; - ConditionalStep goKillSourhog = new ConditionalStep(this, enterHoleAgain); - goKillSourhog.addStep(inCave, killSourhog); + // Steps + ObjectStep readNotice; + NpcStep talkToSarah; + ObjectStep useRopeOnHole; + ObjectStep enterHole; + ObjectStep investigateSkeleton; + NpcStep talkToSpria; + ObjectStep enterHoleAgain; + NpcStep killSourhog; + ObjectStep enterHoleForFoot; + ObjectStep cutOffFoot; + NpcStep returnToSarah; + NpcStep returnToSpria; - steps.put(25, goKillSourhog); - ConditionalStep getFootSteps = new ConditionalStep(this, enterHoleForFoot); - getFootSteps.addStep(hoof, returnToSarah); - getFootSteps.addStep(inCave, cutOffFoot); - - steps.put(30, getFootSteps); - steps.put(35, returnToSpria); - return steps; + @Override + protected void setupZones() + { + cave = new Zone(new WorldPoint(3152, 9669, 0), new WorldPoint(3181, 9720, 0)); } @Override @@ -102,6 +100,10 @@ protected void setupRequirements() slashItem = new ItemRequirement("A knife or slash weapon", ItemID.KNIFE).isNotConsumed(); slashItem.setTooltip("Except abyssal whip, abyssal tentacle, noxious halberd, or dragon claws."); + // This is not intended to be a full list, but rather just a reasonable list of slash weapons a user might bring. + // This does not fit super well into an item collection since it's not reusable. + slashItem.addAlternates(ItemID.DRAGON_SCIMITAR, ItemID.RUNE_SCIMITAR, ItemID.ADAMANT_SCIMITAR, ItemID.MITHRIL_SCIMITAR, ItemID.STEEL_SCIMITAR, ItemID.IRON_SCIMITAR, ItemID.BRONZE_SCIMITAR); + slashItem.addAlternates(ItemID.DRAGON_LONGSWORD, ItemID.RUNE_LONGSWORD, ItemID.ADAMANT_LONGSWORD, ItemID.MITHRIL_LONGSWORD, ItemID.STEEL_LONGSWORD, ItemID.IRON_LONGSWORD, ItemID.BRONZE_LONGSWORD); reinforcedGoggles = new ItemRequirement("Reinforced goggles", ItemID.SLAYER_REINFORCED_GOGGLES, 1, true).isNotConsumed(); reinforcedGoggles.setTooltip("You can get another pair from Spria"); @@ -110,22 +112,12 @@ protected void setupRequirements() combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); hoof = new ItemRequirement("Sourhog foot", ItemID.PORCINE_SOURHOG_TROPHY); - hoof.setTooltip("You can get another from Sourhog's corpse in his cave"); // Recommended draynorTeleport = new ItemRequirement("Teleport to north Draynor", ItemID.TELETAB_DRAYNOR); draynorTeleport.addAlternates(ItemCollections.AMULET_OF_GLORIES); faladorFarmTeleport = new ItemRequirement("Teleport to Falador Farm", ItemCollections.EXPLORERS_RINGS); - } - @Override - protected void setupZones() - { - cave = new Zone(new WorldPoint(3152, 9669, 0), new WorldPoint(3181, 9720, 0)); - } - - public void setupConditions() - { inCave = new ZoneRequirement(cave); } @@ -153,7 +145,7 @@ public void setupSteps() enterHoleForFoot = new ObjectStep(this, ObjectID.PORCINE_HOLE, new WorldPoint(3151, 3348, 0), "Climb down into the Strange Hole east of Draynor Manor.", slashItem); cutOffFoot = new ObjectStep(this, ObjectID.PORCINE_DEAD_SOURHOG, "Cut off Sourhog's foot.", slashItem); - ((ObjectStep) cutOffFoot).addAlternateObjects(ObjectID.PORCINE_DEAD_SOURHOG_9); + cutOffFoot.addAlternateObjects(ObjectID.PORCINE_DEAD_SOURHOG_9); cutOffFoot.addSubSteps(enterHoleForFoot); returnToSarah = new NpcStep(this, NpcID.FARMING_SHOPKEEPER_1, new WorldPoint(3033, 3293, 0), "Return to Sarah in the South Falador Farm.", hoof); @@ -162,22 +154,65 @@ public void setupSteps() returnToSpria = new NpcStep(this, NpcID.PORCINE_SPRIA, new WorldPoint(3092, 3267, 0), "Return to Spria in Draynor Village."); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, readNotice); + steps.put(5, talkToSarah); + steps.put(10, useRopeOnHole); + + var investigateCave = new ConditionalStep(this, enterHole); + investigateCave.addStep(inCave, investigateSkeleton); + + steps.put(15, investigateCave); + + steps.put(20, talkToSpria); + + var goKillSourhog = new ConditionalStep(this, enterHoleAgain); + goKillSourhog.addStep(inCave, killSourhog); + + steps.put(25, goKillSourhog); + + var getFootSteps = new ConditionalStep(this, enterHoleForFoot); + getFootSteps.addStep(hoof.alsoCheckBank(), returnToSarah); + getFootSteps.addStep(inCave, cutOffFoot); + + steps.put(30, getFootSteps); + steps.put(35, returnToSpria); + + return steps; + } + @Override public List getItemRequirements() { - return Arrays.asList(rope, slashItem, combatGear); + return List.of( + rope, + slashItem, + combatGear + ); } @Override public List getItemRecommended() { - return Arrays.asList(draynorTeleport, faladorFarmTeleport); + return List.of( + draynorTeleport, + faladorFarmTeleport + ); } @Override public List getCombatRequirements() { - return Collections.singletonList("Sourhog (level 37)"); + return List.of( + "Sourhog (level 37)" + ); } @Override @@ -189,28 +224,52 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.SLAYER, 1000)); + return List.of( + new ExperienceReward(Skill.SLAYER, 1000) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Coins", ItemID.COINS, 5000)); + return List.of( + new ItemReward("Coins", ItemID.COINS, 5000) + ); } @Override public List getUnlockRewards() { - return Arrays.asList(new UnlockReward("30 Slayer Points"), new UnlockReward("Access to Sourhog Cave"), new UnlockReward("Sourhogs can be assigned as a slayer task by Spria")); + return List.of( + new UnlockReward("30 Slayer Points"), + new UnlockReward("Access to Sourhog Cave"), + new UnlockReward("Sourhogs can be assigned as a slayer task by Spria") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(readNotice, talkToSarah, useRopeOnHole, - enterHole, investigateSkeleton, talkToSpria, enterHoleAgain, killSourhog, cutOffFoot, returnToSarah, - returnToSpria), rope, slashItem, combatGear)); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Helping Sarah", List.of( + readNotice, + talkToSarah, + useRopeOnHole, + enterHole, + investigateSkeleton, + talkToSpria, + enterHoleAgain, + killSourhog, + cutOffFoot, + returnToSarah, + returnToSpria + ), List.of( + rope, + slashItem, + combatGear + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java index 78415423df9..3311a96adf1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java @@ -79,7 +79,7 @@ protected void setupRequirements() { dustyKeyOr70AgilOrKeyMasterTeleport = new KeyringRequirement("Dusty key, or another way to get into the deep Taverley Dungeon", - configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + KeyringCollection.DUSTY_KEY).isNotConsumed(); spade = new ItemRequirement("Spade", ItemID.SPADE).isNotConsumed(); damagedSoulBearer = new ItemRequirement("Damaged soul bearer", ItemID.ARCEUUS_SOULBEARER_DAMAGED); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java index 47de8ce5781..e3846db5da8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java @@ -34,27 +34,30 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestPointRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcEmoteStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.emote.QuestEmote; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class BelowIceMountain extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java index 83dd2522d65..5253b48f53f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java @@ -227,7 +227,7 @@ public Map loadSteps() steps.put(78, returnToZahur); steps.put(80, talkToZahur); - ConditionalStep chemistryPuzzle = new ConditionalStep(this, warmUpChemistryEquipment); + ConditionalStep chemistryPuzzle = new ConditionalStep(this, warmUpChemistryEquipment, "Warm up Zahur's Chemistry Equipment."); chemistryPuzzle.addStep(new Conditions(inChemistryPuzzle, chemistryValveLeftStepZero, new Conditions(LogicType.NAND, chemistryValveMiddleAtMaximum)), chemistryValveIncreaseMiddle); chemistryPuzzle.addStep(new Conditions(inChemistryPuzzle, chemistryValveLeftStepZero, chemistryValveMiddleAtMaximum, new Conditions(LogicType.NAND, chemistryValveRightAtMaximum)), chemistryValveIncreaseRight); chemistryPuzzle.addStep(new Conditions(inChemistryPuzzle, chemistryValveLeftStepZero, chemistryValveMiddleAtMaximum, chemistryValveRightAtMaximum), chemistryValveDecreaseRight); @@ -273,8 +273,7 @@ protected void setupRequirements() waterskins.addAlternates(ItemID.WATER_SKIN3, ItemID.WATER_SKIN2, ItemID.WATER_SKIN1); waterskins.setTooltip("Used for protection against the desert heat"); antipoison = new ItemRequirement("Antipoison", ItemCollections.ANTIPOISONS); - accessToFairyRings = new ItemRequirement("Access to Fairy Rings", ItemID.DRAMEN_STAFF).isNotConsumed(); - accessToFairyRings.addAlternates(ItemID.LUNAR_MOONCLAN_LIMINAL_STAFF); + accessToFairyRings = new ItemRequirement("Access to Fairy Rings", ItemCollections.FAIRY_STAFF).isNotConsumed(); pharaohsSceptre = new ItemRequirement("Pharaoh's sceptre", ItemCollections.PHAROAH_SCEPTRE).isNotConsumed(); pharaohsSceptre.setTooltip("When visiting Necropolis during the quest, you can unlock the direct teleport by using 'Commune' on the Obelisk."); food = new ItemRequirement("Food", -1, -1); @@ -600,7 +599,7 @@ public List getPanels() Collections.singletonList(meleeCombatGear), Arrays.asList(waterskins, food))); allSteps.add(new PanelDetails("The Ruins of Ullek", Arrays.asList(talkToMaisaExploreCliffs, goFromCampsiteToRuinsOfUllek, inspectFurnace, useCoalOnFurnace, useTinderboxOnFurnace, searchWell, readStoneTablet, digForChest, openChest, craftEmblem, useEmblemOnPillar, confirmScarabRotation, enterDungeonToFightScarabMages, fightScarabMages, climbDownStairsAgain, pullLever, pullSecondLever, enterRiddleDoor), Arrays.asList(meleeCombatGear, coal, tinderbox, spade, ironBar), Arrays.asList(food, antipoison, waterskins))); allSteps.add(new PanelDetails("Riddle of the Tomb", Arrays.asList(solveTombRiddle, enterTombDoor, talkToSpirit, takeRustyKey))); - allSteps.add(new PanelDetails("The Champion of Scabaras", Arrays.asList(unlockBossDoor, fightChampionOfScabaras, talkToScabarasHighPriest), Arrays.asList(rangedCombatGear, food, rustyKey))); + allSteps.add(new PanelDetails("The Champion of Scabaras", Arrays.asList(unlockBossDoor, fightChampionOfScabaras, talkToScabarasHighPriest), Arrays.asList(rangedCombatGear, food, rustyKey), Collections.singletonList(antipoison))); allSteps.add(new PanelDetails("Cure for the Pox", Arrays.asList(talkToMaisaInNardah, purchaseBeef, attemptSteppingStones, pickLilyOfElid, takeLilyToZahur, talkToZahur, chemistryPuzzleWrapped, bringCureToPriest), Arrays.asList(meat, waterskins))); allSteps.add(new PanelDetails("Fight with the Menaphite Akh", Arrays.asList(prepareFightMenaphiteAkh, defeatMenaphiteAkh, finishQuest), Arrays.asList(meleeCombatGear, waterskins))); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java index ce4261b5425..599a40d6947 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java @@ -34,14 +34,27 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -50,10 +63,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class Biohazard extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java index 519d968d126..83034fa5123 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java @@ -7,26 +7,28 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestPointRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class BlackKnightFortress extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java index ecd69d4c0bd..8b1e3003ad0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java @@ -28,21 +28,29 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.MultiNpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class ChildrenOfTheSun extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java index 4c082429a5c..b235536b897 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java @@ -31,6 +31,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; @@ -39,19 +40,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class ClientOfKourend extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java index 46acb955f27..2ff138277c3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java @@ -34,6 +34,10 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -41,20 +45,22 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class ClockTower extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java index 4ad5754e8c3..f04f5f32524 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java @@ -29,6 +29,9 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -36,8 +39,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -45,13 +56,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class CooksAssistant extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java index 4fdea31910f..547898726d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java @@ -151,7 +151,9 @@ protected void setupRequirements() silverBar = new ItemRequirement("Silver bar", ItemID.SILVER_BAR); bronzeWire = new ItemRequirement("Bronze wire", ItemID.BRONZECRAFTWIRE, 3); needle = new ItemRequirement("Needle", ItemID.NEEDLE).isNotConsumed(); + needle.setTooltip("Costume needle cannot be used as a substitute"); thread = new ItemRequirement("Thread", ItemID.THREAD, 5); + thread.setTooltip("Costume needle cannot be used as a substitute"); spade = new ItemRequirement("Spade", ItemID.SPADE).isNotConsumed(); coins = new ItemRequirement("Coins at least", ItemCollections.COINS, 100); pickledBrain = new ItemRequirement("Pickled Brain", ItemID.FENK_BRAIN); @@ -268,7 +270,7 @@ public void setupSteps() marbleAmulet.highlighted(), obsidianAmulet.highlighted()); - goDownstairsForStar = new ObjectStep(this, ObjectID.FENK_STAIRS_LV1_TOP, new WorldPoint(3573, 3553, 1), + goDownstairsForStar = new ObjectStep(this, ObjectID.FENK_STAIRS_LV1_TOP, new WorldPoint(3537, 3553, 1), "Go back to the ground floor."); talkToGardenerForHead = new NpcStep(this, NpcID.FENK_GARDENER, new WorldPoint(3548, 3562, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java index 97ce8a564dc..2a4a10435c1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java @@ -34,13 +34,25 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.BoardShipStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.SailStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -49,14 +61,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; - public class CurrentAffairs extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java index 8388fcbd67c..08816c59f40 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java @@ -37,6 +37,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -45,7 +47,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -54,14 +64,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; - /** * The quest guide for the "Death on the Isle" OSRS quest *

@@ -499,6 +501,7 @@ public void setupSteps() accuseAdala.addDialogStep("Accuse Adala."); fightAdala = new NpcStep(this, NpcID.DOTI_ADALA_MASK_INSIDE, new WorldPoint(1446, 2933, 2), "Fight Adala. You cannot lose this fight."); + fightAdala.addAlternateNpcs(NpcID.DOTI_ADALA_BOSS); accuseAdala.addSubSteps(fightAdala); speakToSuspects = new ConditionalStep(this, accuseAdala); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java index 793be31c670..894d00748cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java @@ -48,7 +48,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java index bed24ba5eb2..c9f5b58de0c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java @@ -30,26 +30,28 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class DemonSlayer extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java index 92ddb2cc211..d377e5721ba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java @@ -27,13 +27,12 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.HashMap; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.Widget; -import java.util.HashMap; - public class IncantationStep extends ConditionalStep { private final HashMap words = new HashMap<>() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java index d3b33518193..d2e1f0448ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java @@ -49,6 +49,7 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.api.NullItemID; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -58,7 +59,6 @@ import net.runelite.api.gameval.VarbitID; import java.util.*; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class DesertTreasure extends BasicQuestHelper @@ -428,7 +428,7 @@ public void setupSteps() talkToArchaeologistAgainAfterTranslation = new NpcStep(this, NpcID.FOURDIAMONDS_INDIANA_VIS, new WorldPoint(3177, 3043, 0), "Talk to the Archaeologist again."); talkToArchaeologistAgainAfterTranslation.addDialogStep("Help him"); talkToArchaeologistAgainAfterTranslation.addTeleport(bedabinTeleport); - buyDrink = new NpcStep(this, NpcID.FOURDIAMONDS_BARTENDER, new WorldPoint(3159, 2978, 0), "Buy a drink from the pub in the Bandit Camp, then talk to the Bartender again.", coins650); + buyDrink = new NpcStep(this, NpcID.FOURDIAMONDS_BARTENDER, new WorldPoint(3159, 2978, 0), "Unequip any god-related items you have on, or else you'll be attacked by bandits. Go buy a drink from the pub in the Bandit Camp, then talk to the Bartender again.", coins650); buyDrink.addDialogStep("Buy a drink"); buyDrink.addDialogStep("Buy a beer"); talkToBartender = new NpcStep(this, NpcID.FOURDIAMONDS_BARTENDER, new WorldPoint(3159, 2978, 0), "Talk to the bartender in the Bandit Camp again."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java index b37cd432956..1c2a8b1d31e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java @@ -64,7 +64,9 @@ import java.util.*; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class DesertTreasureII extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java index b53c01c74e9..709bf37e78e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java @@ -47,7 +47,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Prayer; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.Arrays; import java.util.List; @@ -451,9 +455,7 @@ protected void setupConditions() natureAxonPresent = new NpcRequirement(NpcID.DT2_SCAR_MAZE_3_PATHING_NPC, "Abyssal Axon (Nature)"); completedAxonRoom = new VarbitRequirement(VarbitID.DT2_SCAR_MAZE_CHALLENGE_1_DONE, 1); - nothingInHands = and(new NoItemRequirement("Weapon", ItemSlots.WEAPON), - new NoItemRequirement("Shield", ItemSlots.SHIELD)); - ((Conditions) nothingInHands).setText("Nothing equipped in your hands"); + nothingInHands = new NoItemRequirement("Nothing equipped in your hands.", ItemSlots.EMPTY_HANDS); inNorthOfAbyssRoom2 = new ZoneRequirement(northAbyssRoom2P1, northAbyssRoom2P2, northAbyssRoom2P3, northAbyssRoom2P4, northAbyssRoom2P5); inNerveRoom = new ZoneRequirement(nerveRoom1, nerveRoom2, nerveRoom3); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java index 19ddc89833a..de5cb1dfd0b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java @@ -1371,7 +1371,7 @@ protected void setupSteps() fightWhispererSidebar.addText("Corrupted seeds: Activate the blackstone fragment in your inventory. Avoid the dark green seeds, and step on the light green ones."); fightWhispererSidebar.addText("Screech: Pillars appear, which you must hide behind to avoid damage."); fightWhispererSidebar.addText("After each special attack, the Whisperer fire out a binding spell if you are within 10 tiles of her, dealing Melee damage."); - fightWhispererSidebar.addText("When she hits 0 health, she will heal back to 100, and start attacking rapidly with random ranged and magic attacks. Finish her off."); + fightWhispererSidebar.addText("When she hits 0 health, she will heal back to 100, and start attacking rapidly, starting with ranged, and alternating every two attacks until the fight ends. Finish her off."); fightWhispererSidebar.addSubSteps(enterTheCathedral, enterRuinsOfCamdozaalFight, descendDownRopeFight); searchEntrails = new ObjectStep(getQuestHelper(), ObjectID.WHISPERER_MEDALLION_LOC, new WorldPoint(2656, 6370, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java index 54925d6b55c..0e586106b2c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java @@ -170,10 +170,9 @@ public void setupSteps() talkToMonk2 = new NpcStep(this, NpcID.DEVIOUS_MONK_HOODED_VISABLE, new WorldPoint(3406, 3494, 0), "Return to the monk near the Paterdomus temple with the bow-sword.", bowSword); talkToMonk2.addDialogStep("Yep, got it right here for you."); - makeIllumPouch = new DetailedQuestStep(this, "Use the Orb on the Large/Colossal Pouch.", orb, largePouch); - + makeIllumPouch = new DetailedQuestStep(this, "Use the Orb on the Large/Colossal Pouch. You will also be going to Entrana via the Abyss, so you must bank all combat gear.", orb, largePouch); teleToAbyss = new NpcStep(this, NpcID.RCU_ZAMMY_MAGE1B, new WorldPoint(3106, 3556, 0), - "Teleport with the Mage of Zamorak IN THE WILDERNESS to the Abyss. You will be attacked by " + + "Teleport with the Mage of Zamorak IN THE WILDERNESS (other players can attack you here) to the Abyss. You will be attacked by " + "monsters upon entering, and your prayer drained to 0!", illumPouch, noEquipment); enterLawRift = new ObjectStep(this, ObjectID.ABYSS_EXIT_TO_LAW, new WorldPoint(3049, 4839, 0), "Enter the central area through a gap/passage/eyes. Enter the Law Rift.", illumPouch, noEquipment); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java index 4172c26e46e..5dc9bbf948e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java @@ -35,33 +35,24 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; -import java.util.*; - public class DoricsQuest extends BasicQuestHelper { - //Items Required - ItemRequirement clay, copper, iron; - - //NPC Steps - QuestStep talkToDoric; - - @Override - public Map loadSteps() - { - initializeRequirements(); - setupSteps(); - Map steps = new HashMap<>(); + // Required items + ItemRequirement clay; + ItemRequirement copper; + ItemRequirement iron; - steps.put(0, talkToDoric); - steps.put(10, talkToDoric); - - return steps; - } + // Steps + NpcStep talkToDoric; @Override protected void setupRequirements() @@ -75,25 +66,41 @@ public void setupSteps() { talkToDoric = new NpcStep(this, NpcID.DORIC, new WorldPoint(2951, 3451, 0), "Bring Doric north of Falador all the required items. You can mine them all in the Dwarven Mines, or buy them from the Grand Exchange.", clay, copper, iron); talkToDoric.addDialogStep("I wanted to use your anvils."); + talkToDoric.addDialogStep("Yes."); talkToDoric.addDialogStep("Yes, I will get you the materials."); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToDoric); + steps.put(10, talkToDoric); + + return steps; + } + + @Override public List getGeneralRecommended() { - ArrayList req = new ArrayList<>(); - req.add(new SkillRequirement(Skill.MINING, 15, true, "15 Mining to get ores yourself")); - return req; + return List.of( + new SkillRequirement(Skill.MINING, 15, true, "15 Mining to get ores yourself") + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(clay); - reqs.add(copper); - reqs.add(iron); - return reqs; + return List.of( + clay, + copper, + iron + ); } @Override @@ -105,27 +112,40 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.MINING, 1300)); + return List.of( + new ExperienceReward(Skill.MINING, 1300) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Coins", ItemID.COINS, 180)); + return List.of( + new ItemReward("Coins", ItemID.COINS, 180) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Use of Doric's Anvil")); + return List.of( + new UnlockReward("Use of Doric's Anvil") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); + var sections = new ArrayList(); + + sections.add(new PanelDetails("Help Doric", List.of( + talkToDoric + ), List.of( + clay, + copper, + iron + ))); - allSteps.add(new PanelDetails("Help Doric", Collections.singletonList(talkToDoric), clay, copper, iron)); - return allSteps; + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java index 2fceb71686c..d5e7af0effb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java @@ -45,7 +45,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java index 80cc332f196..1f8b5c50378 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -36,19 +37,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - /** * The quest guide for the "Druidic Ritual" OSRS quest *

diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java index 7e6ee12102a..8c2869f0d92 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java @@ -30,6 +30,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetPresenceRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -37,18 +39,23 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.WidgetStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class DwarfCannon extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java index 8f0b2679b20..8975eb83aa0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java @@ -49,7 +49,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; @@ -150,7 +154,7 @@ protected void setupRequirements() slashedBook = new ItemRequirement("Slashed book", ItemID.ELEMENTAL_WORKSHOP_SHIELD_BOOK_SLASHED); slashedBook.setTooltip("If you've lost it you can get another by searching the bookcase in the building south of " + "the odd wall"); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY); + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY); batteredKey.setTooltip("If you've lost it you can get another by searching the bookcase in the building south of " + "the odd wall"); elementalOre = new ItemRequirement("Elemental ore", ItemID.ELEMENTAL_WORKSHOP_ORE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java index fb8073b2e44..321ba648f9e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java @@ -67,7 +67,7 @@ public class ElementalWorkshopII extends BasicQuestHelper ItemRequirement camelotTeleport, digsiteTeleport; ItemRequirement elementalOre, elementalBar, mindBar, primedBar, beatenBook, scroll, key, craneSchematic, claw, - smallCog, mediumCog, largeCog, pipe; + smallCog, mediumCog, largeCog, pipe, slashedBook; Requirement magic20; @@ -256,7 +256,7 @@ protected void setupRequirements() pickaxe = new ItemRequirement("Any pickaxe", ItemCollections.PICKAXES).isNotConsumed(); hammer = new ItemRequirement("Hammer", ItemCollections.HAMMER).isNotConsumed(); coal = new ItemRequirement("Coal", ItemID.COAL, 8); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY); + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY); batteredKey.setTooltip("You can get another by searching the bookcase in the house south of the elemental " + "workshop's entrance"); @@ -266,9 +266,9 @@ protected void setupRequirements() elementalOre = new ItemRequirement("Elemental ore", ItemID.ELEMENTAL_WORKSHOP_ORE); elementalOre.addAlternates(ItemID.ELEMENTAL_WORKSHOP_BAR); - elementalBar = new ItemRequirement("Elemental metal", ItemID.ELEMENTAL_WORKSHOP_BAR); + elementalBar = new ItemRequirement("Elemental metal. Bring an additional elemental metal if you want to smith a mind shield after this quest", ItemID.ELEMENTAL_WORKSHOP_BAR); mindBar = new ItemRequirement("Primed mind bar", ItemID.ELEM_MIND_BAR); - primedBar = new ItemRequirement("Primed bar", ItemID.ELEM_PRIMED_BAR); + primedBar = new ItemRequirement("Primed bar. Bring an additional primed bar if you want to smith a mind shield after this quest", ItemID.ELEM_PRIMED_BAR); beatenBook = new ItemRequirement("Beaten book", ItemID.ELEMENTAL_WORKSHOP_HELM_BOOK); beatenBook.setTooltip("You can get another from a bookcase in the Exam Center"); @@ -287,6 +287,10 @@ protected void setupRequirements() pipe = new ItemRequirement("Pipe", ItemID.ELEM2_SPARE_PIPE); magic20 = new SkillRequirement(Skill.MAGIC, 20, true); + + slashedBook = new ItemRequirement("Slashed book if you want to smith a mind shield after this quest", ItemID.ELEMENTAL_WORKSHOP_SHIELD_BOOK_SLASHED); + slashedBook.setTooltip("If you've lost it you can get another by searching the bookcase in the building south of " + + "the odd wall"); } @Override @@ -424,7 +428,7 @@ public void setupSteps() readScroll = new DetailedQuestStep(this, "Read the scroll.", scroll.highlighted()); enterWorkshop = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_SPIRALSTAIRSTOP, new WorldPoint(2711, 3498, 0), - "Enter the elemental workshop.", batteredKey, beatenBook); + "Enter the elemental workshop.", Arrays.asList(batteredKey, beatenBook), Collections.singletonList(slashedBook)); searchMachinery = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_2_BOILER_MULTI, new WorldPoint(2715, 9903, 0), ""); @@ -444,6 +448,7 @@ public void setupSteps() mineRock = new NpcStep(this, NpcID.ELEM1_QIP_EARTH_ELEMENTAL_ROCK_VERSION_ROCK, new WorldPoint(2703, 9894, 0), "You need 2 elemental bars. Mine one of the elemental rocks in the west room, ready to fight a level 35.", true, pickaxe); + mineRock.addText("If you want to smith a mind shield after this quest, get a third elemental ore and also smelt it into a bar."); killRock = new NpcStep(this, NpcID.ELEM1_QIP_EARTH_ELEMENTAL_ROCK_VERSION, new WorldPoint(2703, 9897, 0), "Kill the rock elemental that appeared."); pickUpOre = new ItemStep(this, "Pick up the elemental ore.", elementalOre); @@ -520,7 +525,7 @@ public void setupSteps() raiseCraneFromBar = new ObjectStep(this, ObjectID.ELEM2_FIRE_LEVER_2, new WorldPoint(1953, 5148, 2), "Pull the south west lever to raise the claw once more."); pullLeverToMoveToPress = new ObjectStep(this, ObjectID.ELEM2_LEVER_3WAY, new WorldPoint(1953, 5151, 2), - "Pull the central lever to move the jig to the press."); + "Pull the central lever to activate the press."); lowerPress = new ObjectStep(this, ObjectID.ELEM2_EARTH_LEVER_1, new WorldPoint(1950, 5153, 2), "Pull the west lever to move the jig to the press."); pullLeverToMoveToTank = new ObjectStep(this, ObjectID.ELEM2_LEVER_3WAY, new WorldPoint(1953, 5151, 2), @@ -558,6 +563,7 @@ public void setupSteps() pullLeverToMoveToLava = new ObjectStep(this, ObjectID.ELEM2_LEVER_3WAY, new WorldPoint(1953, 5151, 2), "Pull the central lever to move the jig back to the start."); pickUpBar = new NpcStep(this, NpcID.ELEM2_CART_NPC_FLAT_BAR_DRY, new WorldPoint(1954, 5147, 2), "Pick up the primed bar."); + pickUpBar.addText("If you want to smith a mind shield after this quest, repeat this process one more time."); goDownToBasement = new ObjectStep(this, ObjectID.ELEM2_STAIRS_DOOR_OPEN_NO_HATCH, new WorldPoint(1949, 5159, 2), "Go down from the priming room."); @@ -568,11 +574,13 @@ public void setupSteps() "Sit in the extractor chair.", magic20); takeMindBar = new ObjectStep(this, ObjectID.ELEM_EXTRACTOR_GUN, new WorldPoint(1962, 5148, 0), "Take the mind bar."); + takeMindBar.addText("If you want to smith a mind shield after this quest, repeat this process one more time."); goUpFromBasement = new ObjectStep(this, ObjectID.ELEM2_STAIRS2, new WorldPoint(1949, 5160, 0), "Go up the stairs."); makeMindHelmet = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_WORKBENCH, new WorldPoint(2717, 9888, 0), - "Use the mind bar on one of the workbenches in the central room.", mindBar.highlighted(), hammer, + "Use the mind bar on one of the workbenches in the central room with the beaten book in your inventory.", mindBar.highlighted(), hammer, beatenBook); + makeMindHelmet.addText("If you want to smith a mind shield after this quest, use the remaining mind bar on one of the workbenches with the slashed book in your inventory."); makeMindHelmet.addIcon(ItemID.ELEM_MIND_BAR); goToWorkshopTopFloor = new ConditionalStep(this, enterWorkshop); @@ -605,7 +613,7 @@ public List getItemRequirements() @Override public List getItemRecommended() { - return Arrays.asList(digsiteTeleport, camelotTeleport); + return Arrays.asList(digsiteTeleport, camelotTeleport, slashedBook); } @Override @@ -656,8 +664,8 @@ public ArrayList getPanels() ArrayList allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Starting off", Arrays.asList(searchBookcase, readBook, readScroll))); - allSteps.add(new PanelDetails("Unlocking the Hatch", Arrays.asList(getKey, unlockHatch), batteredKey, pickaxe, - coal.quantity(8), hammer)); + allSteps.add(new PanelDetails("Unlocking the Hatch", Arrays.asList(getKey, unlockHatch), Arrays.asList(batteredKey, pickaxe, + coal.quantity(8), hammer, beatenBook), Collections.singletonList(slashedBook))); allSteps.add(new PanelDetails("Repairing the crane", Arrays.asList(takeSchematics, goMakeClaw, goRepairCrane))); allSteps.add(new PanelDetails("Repairing the workshop", Arrays.asList(goSortTubes, getCogsAndPipe, goRepairPipe, goPlaceCogs))); @@ -666,10 +674,10 @@ public ArrayList getPanels() pullLeverToMoveToPress, lowerPress, pullLeverToMoveToTank, pullLeverToOpenTankDoor, turnCorkscrew, turnCorkscrewAgain, pullLeverToCloseTankDoor, turnWestValve, turnEastValve, turnEastValveAgain, turnWestValveAgain, pullLeverToOpenTankDoorAgain, turnCorkscrewToRetrieve, turnCorkscrewToRetrieveAgain, pullLeverToCloseTankDoorAgain, pullLeverToMoveToFan, pullFanLever, - pullFanLeverAgain, pullLeverToMoveToLava, pickUpBar), elementalBar)); + pullFanLeverAgain, pullLeverToMoveToLava, pickUpBar), Collections.singletonList(elementalBar))); allSteps.add(new PanelDetails("Making a Mind Helm", Arrays.asList(goDownToBasement, useBarOnGun, operateHat, - takeMindBar, goMakeMindHelmet), primedBar, hammer, beatenBook)); + takeMindBar, goMakeMindHelmet), Arrays.asList(primedBar, hammer, beatenBook), Collections.singletonList(slashedBook))); return allSteps; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java index b1a55691093..39713541b00 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java @@ -51,10 +51,7 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class EnakhrasLament extends BasicQuestHelper { @@ -265,7 +262,10 @@ protected void setupRequirements() camelHead.setHighlightInInventory(true); breadOrCake = new ItemRequirement("Bread or cake", ItemID.BREAD); - breadOrCake.addAlternates(ItemID.CAKE); + // Excluded mud pie, botanical pie, mushroom pie, dragonfruit pie as unsure if those would work due to inedibility and/or newness of pie + breadOrCake.addAlternates(ItemID.CAKE, ItemID.CHOCOLATE_CAKE, ItemID.REDBERRY_PIE, ItemID.MEAT_PIE, ItemID.APPLE_PIE, ItemID.GARDEN_PIE, ItemID.FISH_PIE, ItemID.ADMIRAL_PIE, ItemID.WILD_PIE, ItemID.SUMMER_PIE); + breadOrCake.addAlternates(ItemID.PLAIN_PIZZA, ItemID.MEAT_PIZZA, ItemID.ANCHOVIE_PIZZA, ItemID.PINEAPPLE_PIZZA); + breadOrCake.addAlternates(ItemID.POTATO_BUTTER, ItemID.POTATO_CHILLI_CARNE, ItemID.POTATO_CHEESE, ItemID.POTATO_EGG_TOMATO, ItemID.POTATO_MUSHROOM_ONION, ItemID.POTATO_TUNA_SWEETCORN); breadOrCake.setHighlightInInventory(true); breadOrCake.setDisplayMatchedItemName(true); @@ -469,7 +469,8 @@ public void setupSteps() goUpFromPuzzleRoom = new ObjectStep(this, ObjectID.ENAKH_TEMPLE_LADDERUP, new WorldPoint(3104, 9332, 1), "Go up the ladder."); passBarrier.addSubSteps(goUpFromPuzzleRoom); - castCrumbleUndead = new NpcStep(this, NpcID.ENAKH_BONEGUARD, new WorldPoint(3104, 9307, 2), "Cast crumble undead on the Boneguard.", earth2, + castCrumbleUndead = new NpcStep(this, NpcID.ENAKH_BONEGUARD, new WorldPoint(3104, 9307, 2), "Cast crumble undead on the Boneguard. " + + "Make sure you take off any armour or weapons which give you a negative magic attack bonus or else you might splash.", earth2, airRuneOrStaff, chaos, onNormals); goDownToFinalRoom = new ObjectStep(this, ObjectID.ENAKH_TEMPLE_PILLAR_LADDER_TOP, new WorldPoint(3105, 9300, 2), "Climb down the stone ladder past " + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java index 823408f9057..db91052f077 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java @@ -196,7 +196,7 @@ public void setupSteps() "Bowl."); talkToAugusteWithBranches = new ObjectStep(this, ObjectID.ZEP_MULTI_BASKET_ENTRANA, new WorldPoint(2807, 3356, 0), - "Get 12 willow branches and use them to make the basket.", willowBranches12.highlighted()); + "Get 12 willow branches and use them on the platform next to Auguste to make the basket.", willowBranches12.highlighted()); talkToAugusteWithBranches.addIcon(ItemID.WILLOW_BRANCH); talkToAugusteWithLogsAndTinderbox = new NpcStep(this, NpcID.ZEP_PICCARD, new WorldPoint(2809, 3354, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java index f02e3723d9a..8804eb76984 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java @@ -216,6 +216,7 @@ public void setupSteps() "you're right!"); talkToFarmers = new NpcStep(this, NpcID.ELSTAN, "Talk to 5 farmers, then return to Martin in Draynor Village. The recommended 5 are:"); + talkToFarmers.addText("If you don't already have one, a secateurs can be purchased from Sarah in South Falador Farm"); talkToFarmers.addText("Frizzy in Port Sarim."); talkToFarmers.addText("Elstan north west of Draynor."); talkToFarmers.addText("Heskel in Falador Park."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java index e582ddf6ba3..26ea977cd56 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java @@ -266,10 +266,10 @@ public void setupSteps() dramenOrLunarStaff.equipped()); goToHideout = new ObjectStep(this, ObjectID.FAIRYRING_HOMEHUB, new WorldPoint(2412, 4434, 0), - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); goToHideoutSurface = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); goToHideout.addSubSteps(goToHideoutSurface); //varp 817 2->112->133->31 for each destination @@ -285,20 +285,20 @@ public void setupSteps() pickpocketGodfather.addSubSteps(returnToZanarisFromBase, goToZanarisToPickpocket); goToHideoutWithSec = new ObjectStep(this, ObjectID.FAIRYRING_HOMEHUB, new WorldPoint(2412, 4434, 0), - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate, queensSecateurs); goToHideoutSurfaceWithSec = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate, queensSecateurs); giveSecateursToNuff = new NpcStep(this, NpcID.FAIRY_NUFF2, new WorldPoint(2355, 4455, 0), "Give Fairy Nuff the Queen's Secateurs.", queensSecateurs); goToHideoutAfterSec = new ObjectStep(this, ObjectID.FAIRYRING_HOMEHUB, new WorldPoint(2412, 4434, 0), - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); goToHideoutSurfaceAfterSec = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); talkToNuffAfterSec = new NpcStep(this, NpcID.FAIRY_NUFF2, new WorldPoint(2355, 4455, 0), "Talk to Fairy Nuff."); @@ -327,7 +327,7 @@ public void setupSteps() gorakClawPowder.highlighted(), magicEssenceUnf.highlighted(), herbReq); goToHideout2 = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate, magicEssence); ((ObjectStep) goToHideout2).addAlternateObjects(ObjectID.FAIRYRING_HOMEHUB); @@ -336,7 +336,7 @@ public void setupSteps() usePotionOnQueen.addIcon(ItemID._3DOSEMAGICESS); goToHideoutToFinish = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); ((ObjectStep) goToHideoutToFinish).addAlternateObjects(ObjectID.FAIRYRING_HOMEHUB); talkToQueen = new NpcStep(this, NpcID.FAIRY_QUEEN2, new WorldPoint(2354, 4455, 0), "Talk to the Fairy Queen."); @@ -414,7 +414,7 @@ public ArrayList getPanels() allSteps.add(new PanelDetails("Making a cure", Arrays.asList(goToCkp, waitForStarFlower, pickStarFlower, goToDir, killGorak, pickupGorakClaw, useStarFlowerOnVial, usePestleOnClaw, usePowderOnPotion, - goToHideout2, usePotionOnQueen, talkToQueen), dramenOrLunarStaff, vialOfWater, pestleAndMortar)); + goToHideout2, usePotionOnQueen, talkToQueen), dramenOrLunarStaff, vialOfWater, pestleAndMortar, fairyCertificate)); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java index 8d6552c90a6..4376f9b050a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java @@ -32,6 +32,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -41,19 +42,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class FightArena extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java index 3c6629d3029..aa59562de79 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java @@ -69,7 +69,7 @@ public class ForgettableTale extends BasicQuestHelper Requirement inKelgdagrim, inWolfUnderground, inPubUpstairs, inConsortium, inPuzzleRoom, givenBeerToDrunkenDwarf, rowdyDwarfMadeRequest, gotRowdySeed, gotKhorvakSeed, gotGaussSeed, plotRaked, keldaGrowing, keldaGrown, - addedWater, addedYeast, addedHop, addedMalt, keldaBrewed, keldaInBarrel, handsFree, shieldFree; + addedWater, addedYeast, addedHop, addedMalt, keldaBrewed, keldaInBarrel, handsFree; Requirement inPurple, inYellow, inBlue, inGreen, inSilver, inWhite, inBrown; @@ -448,8 +448,7 @@ public void setupConditions() inSilver = new VarbitRequirement(VarbitID.GIANTDWARF_CURRENT_COMPANY, 6); // Silver Cog inBrown = new VarbitRequirement(VarbitID.GIANTDWARF_CURRENT_COMPANY, 7); // Brown Engine - handsFree = new NoItemRequirement("No weapon equipped", ItemSlots.WEAPON); - shieldFree = new NoItemRequirement("No shield equipped", ItemSlots.SHIELD); + handsFree = new NoItemRequirement("No weapon or shield equipped", ItemSlots.EMPTY_HANDS); // 837 = 1, entered first puzzle // 839 = 1, cutscene entering done @@ -654,7 +653,7 @@ else if (inBrown.check(client)) goDownFromDirector = new ObjectStep(this, ObjectID.DWARF_KELDAGRIM_WIDE_STAIRS_UPPER, new WorldPoint(2895, 10210, 1), "Go downstairs."); takeSecretCart = new ObjectStep(this, ObjectID.KELDAGRIM_TRAIN_CART, new WorldPoint(2919, 10164, 0), - "", handsFree, shieldFree); + "", handsFree); searchBox1 = new ObjectStep(this, ObjectID.KELDAGRIM_TRACK_JUNCTION_CARD_BOX, new WorldPoint(1862, 4954, 1), "Search the box."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java index 8a33e111406..2fcf1cf347e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java @@ -457,7 +457,7 @@ public void setupSteps() wateringCan.highlighted()); talkToAlthric = new NpcStep(this, NpcID.BROTHER_ALTHRIC, new WorldPoint(3052, 3502, 0), - "Talk to Brother Altheric in the Edgeville Monastery.", ringOfCharosA.equipped()); + "Talk to Brother Althric in the Edgeville Monastery.", ringOfCharosA.equipped()); talkToAlthric.addDialogSteps("[Charm] These are the most beautiful rosebushes I've ever seen."); useCharosOnWell = new ObjectStep(this, ObjectID.WELL, new WorldPoint(3085, 3503, 0), "Use the Ring of charos(a) on the well in Edgeville.", ringOfCharosA.highlighted()); @@ -571,7 +571,7 @@ public void setupSteps() talkToEllmariaAfterGrown = new NpcStep(this, NpcID.QUEEN_ELLAMARIA, new WorldPoint(3230, 3478, 0), "Talk to Ellamaria once everything's finished growing."); - talkToRoald = new NpcStep(this, NpcID.KING_ROALD_CUTSCENE, new WorldPoint(3221, 3473, 0), + talkToRoald = new NpcStep(this, NpcID.KING_ROALD, new WorldPoint(3221, 3473, 0), "Talk to King Roald in Varrock Castle, watch the cutscene, then finish the dialog with Ellamaria to finish" + " the quest!", ringOfCharosA.equipped()); talkToRoald.addDialogSteps("Ask King Roald to follow me.", "[Charm] Of course, your majesty - please forgive " + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java index 25d3ace8fa4..83a56940a55 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java @@ -29,7 +29,9 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -37,20 +39,21 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class GertrudesCat extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java index 8208a588653..2bad7e60a27 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java @@ -38,15 +38,12 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.text.Rs2TextSanitizer; -import lombok.extern.slf4j.Slf4j; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; -@Slf4j public class DyeShipSteps extends DetailedOwnerStep { boolean coloursKnown = false; @@ -99,54 +96,36 @@ private void updateCurrentColours() { return; } - String normalized = Rs2TextSanitizer.normalizeGameText(text); - String[] splitOnNewLines = normalized.split("
"); - boolean handledLines = false; + String[] splitOnNewLines = text.split("
"); if (splitOnNewLines.length > 1) { for (String splitOnNewLine : splitOnNewLines) { - if (updateCurrentColoursFromString(Rs2TextSanitizer.stripTagsToSpace(splitOnNewLine))) - { - handledLines = true; - } + updateCurrentColoursFromString(splitOnNewLine); } } - if (handledLines) - { - return; - } - String plain = Rs2TextSanitizer.stripTagsToSpace(normalized); - String[] splitText = plain.split("dye the "); + String[] splitText = text.split("dye the "); if (splitText.length < 2) { - if (log.isDebugEnabled()) - { - int h = plain.hashCode(); - int len = plain.length(); - String prefix = plain.length() > 60 ? plain.substring(0, 60) + "…" : plain; - log.debug("DyeShipSteps: expected 'dye the ' in objectbox text; len={} hash={} prefix='{}'", len, Integer.toHexString(h), prefix); - } return; } updateCurrentColoursFromString(splitText[1]); } - private boolean updateCurrentColoursFromString(String text) + private void updateCurrentColoursFromString(String text) { String[] shapeAndColour = text.split(" (emblem|of the flag) "); if (shapeAndColour.length < 2) { - return false; + return; } String shape = shapeAndColour[0]; String colour = shapeAndColour[1]; shape = shape.replace("The ", ""); colour = colour.replace("is ", ""); currentColours.put(shape, FlagColour.findByKey(colour)); - return true; } public void updateSteps() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java index 899c5a3926e..1327f9eb07c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java @@ -26,17 +26,24 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -44,62 +51,47 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class GoblinDiplomacy extends BasicQuestHelper { - //Required items - ItemRequirement goblinMailThree, orangeDye, blueDye, goblinMail, goblinMailTwo, blueArmour, orangeArmour, mailReq; - - Requirement isUpstairs, hasUpstairsArmour, hasWestArmour, hasNorthArmour; - - QuestStep talkToGeneral1, talkToGeneral2, talkToGeneral3, goUpLadder, searchUpLadder, goDownLadder, searchWestHut, searchBehindGenerals, - dyeOrange, dyeBlue, getCrate2, getCrate3; - - //Zones + // Required items + ItemRequirement goblinMailThree; + ItemRequirement orangeDye; + ItemRequirement blueDye; + + // Mid-quest item requirements + ItemRequirement goblinMail; + ItemRequirement goblinMailTwo; + ItemRequirement blueArmour; + ItemRequirement orangeArmour; + ItemRequirement mailReq; + + // Zones Zone upstairs; + // Miscellaneous requirements + ZoneRequirement isUpstairs; + VarbitRequirement hasUpstairsArmour; + VarbitRequirement hasWestArmour; + VarbitRequirement hasNorthArmour; + + // Steps + NpcStep talkToGeneral1; + NpcStep talkToGeneral2; + NpcStep talkToGeneral3; + ObjectStep goUpLadder; + ObjectStep searchUpLadder; + ObjectStep goDownLadder; + ObjectStep searchWestHut; + ObjectStep searchBehindGenerals; + DetailedQuestStep dyeOrange; + DetailedQuestStep dyeBlue; + DetailedQuestStep getCrate2; + DetailedQuestStep getCrate3; + @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - ConditionalStep lootArmour = new ConditionalStep(this, goUpLadder); - lootArmour.addStep(new Conditions(isUpstairs, hasUpstairsArmour), goDownLadder); - lootArmour.addStep(new Conditions(hasUpstairsArmour, hasWestArmour), searchBehindGenerals); - lootArmour.addStep(hasUpstairsArmour, searchWestHut); - lootArmour.addStep(isUpstairs, searchUpLadder); - - ConditionalStep prepareForQuest = new ConditionalStep(this, lootArmour); - prepareForQuest.addStep(new Conditions(goblinMail, blueArmour), dyeOrange); - prepareForQuest.addStep(new Conditions(LogicType.OR, goblinMailThree, new Conditions(hasUpstairsArmour, hasWestArmour, - hasNorthArmour)), dyeBlue); - - ConditionalStep step1 = new ConditionalStep(this, prepareForQuest); - step1.addStep(new Conditions(goblinMail, blueArmour, orangeArmour), talkToGeneral1); - - steps.put(0, step1); - steps.put(3, step1); - - ConditionalStep prepareBlueArmour = new ConditionalStep(this, lootArmour); - prepareBlueArmour.addStep(new Conditions(LogicType.OR, goblinMailTwo, new Conditions(hasUpstairsArmour, hasWestArmour, - hasNorthArmour)), dyeBlue); - - ConditionalStep step2 = new ConditionalStep(this, prepareBlueArmour); - step2.addStep(blueArmour, talkToGeneral2); - - steps.put(4, step2); - - ConditionalStep step3 = new ConditionalStep(this, lootArmour); - step3.addStep(new Conditions(LogicType.OR, goblinMail, new Conditions(hasUpstairsArmour, hasWestArmour, - hasNorthArmour)), talkToGeneral3); - - steps.put(5, step3); - - return steps; + upstairs = new Zone(new WorldPoint(2952, 3495, 2), new WorldPoint(2959, 3498, 2)); } @Override @@ -123,26 +115,16 @@ protected void setupRequirements() blueArmour = new ItemRequirement("Blue goblin mail", ItemID.GOBLIN_ARMOUR_DARKBLUE); orangeArmour = new ItemRequirement("Orange goblin mail", ItemID.GOBLIN_ARMOUR_ORANGE); - } - public void setupConditions() - { isUpstairs = new ZoneRequirement(upstairs); hasUpstairsArmour = new VarbitRequirement(VarbitID.GOBDIP_CRATE3_SEARCHED, 1); hasWestArmour = new VarbitRequirement(VarbitID.GOBDIP_CRATE2_SEARCHED, 1); hasNorthArmour = new VarbitRequirement(VarbitID.GOBDIP_CRATE1_SEARCHED, 1); } - @Override - protected void setupZones() - { - upstairs = new Zone(new WorldPoint(2952, 3495, 2), new WorldPoint(2959, 3498, 2)); - } - public void setupSteps() { - goUpLadder = new ObjectStep(this, ObjectID.GOBLIN_LADDER_BOTTOM, new WorldPoint(2954, 3497, 0), "You need three goblin mails, which you can find around the Goblin " + - "Village. The first is up the ladder in a crate in the south of the village."); + goUpLadder = new ObjectStep(this, ObjectID.GOBLIN_LADDER_BOTTOM, new WorldPoint(2954, 3497, 0), "You need three goblin mails, which you can find around the Goblin Village. The first is up the ladder in a crate in the south of the village."); searchUpLadder = new ObjectStep(this, ObjectID.GOBLIN_OUTPOST_LARGE_CRATE_ARMOUR3, new WorldPoint(2955, 3498, 2), "Search the crate up the ladder."); goUpLadder.addSubSteps(searchUpLadder); goDownLadder = new ObjectStep(this, ObjectID.GOBLIN_LADDER_TOP, new WorldPoint(2954, 3497, 2), "Go back down the ladder."); @@ -158,10 +140,11 @@ public void setupSteps() dyeOrange = new DetailedQuestStep(this, "Use the orange dye on one of the goblin mail.", orangeDye, goblinMail); talkToGeneral1 = new NpcStep(this, NpcID.GENERAL_BENTNOZE_RED, new WorldPoint(2958, 3512, 0), "Talk to one of the Goblin Generals in Goblin Village.", orangeArmour); - talkToGeneral1.addDialogStep("So how is life for the goblins?"); - talkToGeneral1.addDialogStep("Yes, Wartface looks fat"); talkToGeneral1.addDialogStep("Do you want me to pick an armour colour for you?"); talkToGeneral1.addDialogStep("What about a different colour?"); + talkToGeneral1.addDialogStep("Yes."); + talkToGeneral1.addDialogStep("So how is life for the goblins?"); + talkToGeneral1.addDialogStep("Yes, Wartface looks fat"); talkToGeneral1.addDialogStep("I have some orange armour here."); talkToGeneral2 = new NpcStep(this, NpcID.GENERAL_BENTNOZE_RED, new WorldPoint(2958, 3512, 0), "Talk to one of the Goblin Generals in Goblin Village again.", blueArmour); @@ -174,14 +157,54 @@ public void setupSteps() talkToGeneral3.addDialogStep("I have some brown armour here."); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + var lootArmour = new ConditionalStep(this, goUpLadder); + lootArmour.addStep(and(isUpstairs, hasUpstairsArmour), goDownLadder); + lootArmour.addStep(and(hasUpstairsArmour, hasWestArmour), searchBehindGenerals); + lootArmour.addStep(hasUpstairsArmour, searchWestHut); + lootArmour.addStep(isUpstairs, searchUpLadder); + + var prepareForQuest = new ConditionalStep(this, lootArmour); + prepareForQuest.addStep(and(goblinMail, blueArmour), dyeOrange); + prepareForQuest.addStep(or(goblinMailThree, and(hasUpstairsArmour, hasWestArmour, hasNorthArmour)), dyeBlue); + + var step1 = new ConditionalStep(this, prepareForQuest); + step1.addStep(and(goblinMail, blueArmour, orangeArmour), talkToGeneral1); + + steps.put(0, step1); + steps.put(3, step1); + + var prepareBlueArmour = new ConditionalStep(this, lootArmour); + prepareBlueArmour.addStep(or(goblinMailTwo, and(hasUpstairsArmour, hasWestArmour, hasNorthArmour)), dyeBlue); + + var step2 = new ConditionalStep(this, prepareBlueArmour); + step2.addStep(blueArmour, talkToGeneral2); + + steps.put(4, step2); + + var step3 = new ConditionalStep(this, lootArmour); + step3.addStep(or(goblinMail, and(hasUpstairsArmour, hasWestArmour, hasNorthArmour)), talkToGeneral3); + + steps.put(5, step3); + + return steps; + } + @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(blueDye); - reqs.add(orangeDye); - reqs.add(mailReq); - return reqs; + return List.of( + blueDye, + orangeDye, + mailReq + ); } @Override @@ -193,24 +216,42 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.CRAFTING, 200)); + return List.of( + new ExperienceReward(Skill.CRAFTING, 200) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("A Gold Bar", ItemID.GOLD_BAR, 1)); + return List.of( + new ItemReward("A Gold Bar", ItemID.GOLD_BAR, 1) + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - PanelDetails getArmours = new PanelDetails("Prepare goblin mail", - Arrays.asList(goUpLadder, getCrate2, getCrate3, dyeBlue, dyeOrange), blueDye, orangeDye, goblinMailThree); - allSteps.add(getArmours); - - allSteps.add(new PanelDetails("Present the armours", Arrays.asList(talkToGeneral1, talkToGeneral2, talkToGeneral3))); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Prepare goblin mail", List.of( + goUpLadder, + getCrate2, + getCrate3, + dyeBlue, + dyeOrange + ), List.of( + blueDye, + orangeDye, + goblinMailThree + ))); + + sections.add(new PanelDetails("Present the armours", List.of( + talkToGeneral1, + talkToGeneral2, + talkToGeneral3 + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java index 4a337966ef7..ae7d3678c9b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java @@ -167,7 +167,8 @@ protected void setupRequirements() tarrominUnfHighlight = new ItemRequirement("Tarromin potion (unf)", ItemID.TARROMINVIAL); tarrominUnfHighlight.setHighlightInInventory(true); - dibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).isNotConsumed(); + var knowsBarbarianPlanting = new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, 3); + dibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).hideConditioned(knowsBarbarianPlanting).isNotConsumed(); can = new ItemRequirement("Watering can with at least 1 use", ItemCollections.WATERING_CANS).isNotConsumed(); can.setTooltip("Gricollers' can is also valid. "); axe = new ItemRequirement("Any axe", ItemCollections.AXES).isNotConsumed(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java index d945cd5e5c6..edae421f0e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; @@ -293,7 +297,7 @@ public void setupSteps() pullLeverG = new ObjectStep(this, ObjectID.HAUNTEDMINE_POINT_LEVER7, new WorldPoint(2769, 4533, 0), "Pull the marked lever."); pullLeverH = new ObjectStep(this, ObjectID.HAUNTEDMINE_POINT_LEVER8, new WorldPoint(2770, 4533, 0), "Pull the marked lever."); - solvePuzzle = new DetailedQuestStep(this, "Pull levers until the tracks are lined up to take the cart to the north east corner."); + solvePuzzle = new DetailedQuestStep(this, "Pull levers until the tracks are lined up to take the cart to the north west corner (the panel's map UI shows north as pointing to the right)."); solvePuzzle.addSubSteps(pullLeverA, pullLeverB, pullLeverC, pullLeverD, pullLeverE, pullLeverF, pullLeverG, pullLeverH); useKeyOnValve = new ObjectStep(this, ObjectID.HAUNTEDMINE_LIFT_VALVE, new WorldPoint(2808, 4496, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java index 73dd07c3175..d4009711993 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java @@ -31,6 +31,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -38,7 +40,17 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.MultiNpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -46,11 +58,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class HazeelCult extends BasicQuestHelper { // Recommended items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java index a8a70fd1175..78e7348ff1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java @@ -198,8 +198,8 @@ protected void setupRequirements() fishingRod.addAlternates(ItemID.OILY_FISHING_ROD); fishingBait = new ItemRequirement("Fishing bait", ItemID.FISHING_BAIT); jailKey = new ItemRequirement("Jail key", ItemID.JAIL_KEY).isNotConsumed(); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); - dustyKeyHint = new KeyringRequirement("Dusty key (obtainable in quest)", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).isNotConsumed(); + dustyKeyHint = new KeyringRequirement("Dusty key (obtainable in quest)", KeyringCollection.DUSTY_KEY).isNotConsumed(); harralanderUnf = new ItemRequirement("Harralander potion (unf)", ItemID.HARRALANDERVIAL); pickaxe = new ItemRequirement("Any pickaxe", ItemID.BRONZE_PICKAXE).isNotConsumed(); pickaxe.addAlternates(ItemCollections.PICKAXES); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java index e31e9b165c6..b7e6b1d2e03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java @@ -38,12 +38,24 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -51,13 +63,6 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class HolyGrail extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java index e7673923e48..4c90a010256 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java @@ -33,18 +33,21 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class ImpCatcher extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java index edbb3e5c4c2..3cfa329b5bf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java @@ -36,7 +36,15 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -44,33 +52,61 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class JunglePotion extends BasicQuestHelper { - //Items Required - ItemRequirement grimySnakeWeed, snakeWeed, grimyArdrigal, ardrigal, grimySitoFoil, sitoFoil, grimyVolenciaMoss, volenciaMoss, - roguesPurse, grimyRoguesPurse; - - QuestStep startQuest, finishQuest; - - ObjectStep getSnakeWeed, getArdrigal, getSitoFoil, getVolenciaMoss, enterCave, getRoguePurseHerb; - - ConditionalStep cleanAndReturnSnakeWeed, cleanAndReturnArdrigal, cleanAndReturnSitoFoil, cleanAndReturnVolenciaMoss, - getRoguesPurse, cleanAndReturnRoguesPurse; - + // Recommended items + ItemRequirement food; + ItemRequirement antipoison; + ItemRequirement karaTele; + + // Mid-quest item requirements + ItemRequirement grimySnakeWeed; + ItemRequirement snakeWeed; + ItemRequirement grimyArdrigal; + ItemRequirement ardrigal; + ItemRequirement grimySitoFoil; + ItemRequirement sitoFoil; + ItemRequirement grimyVolenciaMoss; + ItemRequirement volenciaMoss; + ItemRequirement roguesPurse; + ItemRequirement grimyRoguesPurse; + + // Zones + Zone undergroundZone; + + // Miscellaneous requirements ZoneRequirement isUnderground; + // Steps + NpcStep startQuest; + ObjectStep getSnakeWeed; + ConditionalStep cleanAndReturnSnakeWeed; + ObjectStep getArdrigal; + ConditionalStep cleanAndReturnArdrigal; + ObjectStep getSitoFoil; + ConditionalStep cleanAndReturnSitoFoil; + ObjectStep getVolenciaMoss; + ConditionalStep cleanAndReturnVolenciaMoss; + ObjectStep enterCave; + ObjectStep getRoguePurseHerb; + ConditionalStep getRoguesPurse; + ConditionalStep cleanAndReturnRoguesPurse; + NpcStep finishQuest; + @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - return getSteps(); + undergroundZone = new Zone(new WorldPoint(2824, 9462, 0), new WorldPoint(2883, 9533, 0)); } @Override protected void setupRequirements() { + food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); + antipoison = new ItemRequirement("Antipoison", ItemCollections.ANTIPOISONS); + karaTele = new ItemRequirement("Teleport to Karamja (Glory/house teleport)", ItemID.NZONE_TELETAB_BRIMHAVEN); + karaTele.addAlternates(ItemCollections.AMULET_OF_GLORIES); + grimySnakeWeed = new ItemRequirement("Grimy Snake Weed", ItemID.UNIDENTIFIED_SNAKE_WEED); grimySnakeWeed.setHighlightInInventory(true); snakeWeed = new ItemRequirement("Snake Weed", ItemID.SNAKE_WEED); @@ -90,116 +126,53 @@ protected void setupRequirements() grimyRoguesPurse = new ItemRequirement("Grimy Rogues Purse", ItemID.UNIDENTIFIED_ROGUES_PURSE); grimyRoguesPurse.setHighlightInInventory(true); roguesPurse = new ItemRequirement("Rogues Purse", ItemID.ROGUES_PURSE); - } - @Override - protected void setupZones() - { - //2824,9462,0 - //2883, 9533, 0 - Zone undergroundZone = new Zone(new WorldPoint(2824, 9462, 0), new WorldPoint(2883, 9533, 0)); isUnderground = new ZoneRequirement(undergroundZone); } - private Map getSteps() - { - Map steps = new HashMap<>(); - - steps.put(0, startQuestStep()); - steps.put(1, getSnakeWeed()); - steps.put(2, returnSnakeWeed()); - steps.put(3, getArdrigal()); - steps.put(4, returnArdigal()); - steps.put(5, getSitoFoil()); - steps.put(6, returnSitoFoil()); - steps.put(7, getVolenciaMoss()); - steps.put(8, returnVolenciaMoss()); - steps.put(9, getRoguesPurse()); - steps.put(10, returnRoguesPurse()); - steps.put(11, finishQuestStep()); - return steps; - } - - private QuestStep startQuestStep() - { - startQuest = talkToTrufitus("Talk to Trufitus in Tai Bwo Wannai on Karamja."); - startQuest.addDialogSteps("It's a nice village, where is everyone?"); - startQuest.addDialogSteps("Me? How can I help?"); - startQuest.addDialogSteps("It sounds like just the challenge for me."); - return startQuest; - } - - private QuestStep returnArdigal() - { - return cleanAndReturnArdrigal = getReturnHerbStep("Ardrigal", grimyArdrigal, ardrigal); - } - - private QuestStep returnSnakeWeed() - { - return cleanAndReturnSnakeWeed = getReturnHerbStep("Snake Weed", grimySnakeWeed, snakeWeed); - } - - private QuestStep returnSitoFoil() - { - return cleanAndReturnSitoFoil = getReturnHerbStep("Sito Foil", grimySitoFoil, sitoFoil); - } - - private QuestStep returnVolenciaMoss() - { - return cleanAndReturnVolenciaMoss = getReturnHerbStep("Volencia Moss", grimyVolenciaMoss, volenciaMoss); - } - - private QuestStep returnRoguesPurse() - { - cleanAndReturnRoguesPurse = getReturnHerbStep("Rogues Purse", grimyRoguesPurse, roguesPurse); - cleanAndReturnRoguesPurse.addStep(isUnderground, new ObjectStep(this, - ObjectID.JP_CAVEROCKSOUT, new WorldPoint(2830, 9522, 0), "Climb out of the cave.")); - return cleanAndReturnRoguesPurse; - } - private ConditionalStep getReturnHerbStep(String herbName, ItemRequirement grimyHerb, ItemRequirement cleanHerb) { NpcStep returnHerb = talkToTrufitus("", cleanHerb); returnHerb.addDialogSteps("Of course!"); - DetailedQuestStep cleanGrimyHerb = new DetailedQuestStep(this, "", grimyHerb); + var cleanGrimyHerb = new DetailedQuestStep(this, "", grimyHerb); - ConditionalStep cleanAndReturnHerb = new ConditionalStep(this, cleanGrimyHerb, "Clean and return the " + herbName + " to Trufitus."); + var cleanAndReturnHerb = new ConditionalStep(this, cleanGrimyHerb, "Clean and return the " + herbName + " to Trufitus."); cleanAndReturnHerb.addStep(cleanHerb, returnHerb); return cleanAndReturnHerb; } - private QuestStep getSnakeWeed() + private NpcStep talkToTrufitus(String text, Requirement... requirements) { - getSnakeWeed = new ObjectStep(this, ObjectID.SNAKE_VINE_FULL, new WorldPoint(2763, 3044, 0), - "Search a marshy jungle vine south of Tai Bwo Wannai for some snake weed."); - getSnakeWeed.addText("If you want to do Zogre Flesh Eaters or Legends' Quest grab one for each as you will need them later."); - return getSnakeWeed; + return new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), text, requirements); } - private QuestStep getArdrigal() + private void setupSteps() { - getArdrigal = new ObjectStep(this, ObjectID.ARDRIGAL_PALM_FULL, new WorldPoint(2871, 3116, 0), - "Search the palm trees north east of Tai Bwo Wannai for an Ardrigal herb."); + startQuest = talkToTrufitus("Talk to Trufitus in Tai Bwo Wannai on Karamja."); + startQuest.addDialogStep("It's a nice village, where is everyone?"); + startQuest.addDialogStep("Me? How can I help?"); + startQuest.addDialogStep("It sounds like just the challenge for me."); + startQuest.addDialogStep("Yes."); + + getSnakeWeed = new ObjectStep(this, ObjectID.SNAKE_VINE_FULL, new WorldPoint(2763, 3044, 0), "Search a marshy jungle vine south of Tai Bwo Wannai for some snake weed."); + getSnakeWeed.addText("If you want to do Zogre Flesh Eaters or Legends' Quest grab one for each as you will need them later."); + + cleanAndReturnSnakeWeed = getReturnHerbStep("Snake Weed", grimySnakeWeed, snakeWeed); + + getArdrigal = new ObjectStep(this, ObjectID.ARDRIGAL_PALM_FULL, new WorldPoint(2871, 3116, 0), "Search the palm trees north east of Tai Bwo Wannai for an Ardrigal herb."); getArdrigal.addText("If you want to do Legends' Quest grab one extra as you will need it later."); - return getArdrigal; - } - private QuestStep getSitoFoil() - { - return getSitoFoil = new ObjectStep(this, ObjectID.SITO_SOIL_FULL, new WorldPoint(2791, 3047, 0), - "Search the scorched earth in the south of Tai Bwo Wannai for a Sito Foil herb."); - } + cleanAndReturnArdrigal = getReturnHerbStep("Ardrigal", grimyArdrigal, ardrigal); - private QuestStep getVolenciaMoss() - { - getVolenciaMoss = new ObjectStep(this, ObjectID.VOLENCIA_MOSS_ROCK_FULL, new WorldPoint(2851, 3036, 0), - "Search the rock for a Volencia Moss herb at the mine south east of Tai Bwo Wannai."); + getSitoFoil = new ObjectStep(this, ObjectID.SITO_SOIL_FULL, new WorldPoint(2791, 3047, 0), "Search the scorched earth in the south of Tai Bwo Wannai for a Sito Foil herb."); + + cleanAndReturnSitoFoil = getReturnHerbStep("Sito Foil", grimySitoFoil, sitoFoil); + + getVolenciaMoss = new ObjectStep(this, ObjectID.VOLENCIA_MOSS_ROCK_FULL, new WorldPoint(2851, 3036, 0), "Search the rock for a Volencia Moss herb at the mine south east of Tai Bwo Wannai."); getVolenciaMoss.addText("If you plan on doing Fairy Tale I then take an extra."); - return getVolenciaMoss; - } - private QuestStep getRoguesPurse() - { + cleanAndReturnVolenciaMoss = getReturnHerbStep("Volencia Moss", grimyVolenciaMoss, volenciaMoss); + enterCave = new ObjectStep(this, ObjectID.POTHOLE_CAVE_ENTRANCE, new WorldPoint(2825, 3119, 0), "Enter the cave to the north by clicking on the rocks."); enterCave.addDialogStep("Yes, I'll enter the cave."); @@ -212,51 +185,62 @@ private QuestStep getRoguesPurse() getRoguesPurse.addStep(isUnderground, getRoguePurseHerb); getRoguesPurse.addSubSteps(enterCave); - return getRoguesPurse; - } - private QuestStep finishQuestStep() - { + cleanAndReturnRoguesPurse = getReturnHerbStep("Rogues Purse", grimyRoguesPurse, roguesPurse); + cleanAndReturnRoguesPurse.addStep(isUnderground, new ObjectStep(this, ObjectID.JP_CAVEROCKSOUT, new WorldPoint(2830, 9522, 0), "Climb out of the cave.")); + finishQuest = talkToTrufitus("Talk to Trufitus to finish the quest."); - return finishQuest; } - private NpcStep talkToTrufitus(String text, Requirement... requirements) + @Override + public Map loadSteps() { - return new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), text, requirements); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, startQuest); + steps.put(1, getSnakeWeed); + steps.put(2, cleanAndReturnSnakeWeed); + steps.put(3, getArdrigal); + steps.put(4, cleanAndReturnArdrigal); + steps.put(5, getSitoFoil); + steps.put(6, cleanAndReturnSitoFoil); + steps.put(7, getVolenciaMoss); + steps.put(8, cleanAndReturnVolenciaMoss); + steps.put(9, getRoguesPurse); + steps.put(10, cleanAndReturnRoguesPurse); + steps.put(11, finishQuest); + + return steps; } @Override - public List getCombatRequirements() + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Survive against level 53 Jogres and level 46 Harpie Bug Swarms."); - return reqs; + return List.of( + new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED), + new SkillRequirement(Skill.HERBLORE, 3, false) + ); } - //Recommended @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - ItemRequirement food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); - - reqs.add(food); - reqs.add(new ItemRequirement("Antipoison", ItemCollections.ANTIPOISONS)); - ItemRequirement karaTele = new ItemRequirement("Teleport to Karamja (Glory/house teleport)", - ItemID.NZONE_TELETAB_BRIMHAVEN); - karaTele.addAlternates(ItemCollections.AMULET_OF_GLORIES); - reqs.add(karaTele); - return reqs; + return List.of( + food, + antipoison, + karaTele + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.HERBLORE, 3, false)); - return req; + return List.of( + "Survive against level 53 Jogres and level 46 Harpie Bug Swarms." + ); } @Override @@ -268,38 +252,47 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.HERBLORE, 775)); + return List.of( + new ExperienceReward(Skill.HERBLORE, 775) + ); } @Override public List getPanels() { - List steps = new ArrayList<>(); - - PanelDetails startingPanel = new PanelDetails("Starting quest", - Collections.singletonList(startQuest)); - steps.add(startingPanel); - - PanelDetails snakeWeedPanel = new PanelDetails("Snake Weed", - Arrays.asList(getSnakeWeed, cleanAndReturnSnakeWeed)); - steps.add(snakeWeedPanel); - - PanelDetails ardrigalPanel = new PanelDetails("Ardrigal", - Arrays.asList(getArdrigal, cleanAndReturnArdrigal)); - steps.add(ardrigalPanel); - - PanelDetails sitoFoilpanel = new PanelDetails("Sito Foil", - Arrays.asList(getSitoFoil, cleanAndReturnSitoFoil)); - steps.add(sitoFoilpanel); - - PanelDetails volenciaMossPanel = new PanelDetails("Volencia Moss", - Arrays.asList(getVolenciaMoss, cleanAndReturnVolenciaMoss)); - steps.add(volenciaMossPanel); - - PanelDetails roguesPursePanel = new PanelDetails("Rogues Purse", - Arrays.asList(enterCave, getRoguePurseHerb, cleanAndReturnRoguesPurse)); - steps.add(roguesPursePanel); - - return steps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + startQuest + ))); + + sections.add(new PanelDetails("Snake Weed", List.of( + getSnakeWeed, + cleanAndReturnSnakeWeed + ))); + + sections.add(new PanelDetails("Ardrigal", List.of( + getArdrigal, + cleanAndReturnArdrigal + ))); + + sections.add(new PanelDetails("Sito Foil", List.of( + getSitoFoil, + cleanAndReturnSitoFoil + ))); + + sections.add(new PanelDetails("Volencia Moss", List.of( + getVolenciaMoss, + cleanAndReturnVolenciaMoss + ))); + + sections.add(new PanelDetails("Rogues Purse", List.of( + enterCave, + getRoguePurseHerb, + cleanAndReturnRoguesPurse, + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java index 593527e1125..7dec619302c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java @@ -65,7 +65,7 @@ public class LandOfTheGoblins extends BasicQuestHelper { Requirement noPet; ItemRequirement lightSource, toadflaxPotionUnf, goblinMail, yellowDye, blueDye, orangeDye, purpleDye, blackDye, fishingRod, rawSlimyEel, coins, combatGear; - ItemRequirement tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing, salveAmulet; + ItemRequirement tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing; CombatLevelRequirement recommendedCombatLevel; ItemRequirement pharmakosBerryHighlight, toadflaxUnfHighlight, goblinPotion, goblinPotionHighlight, noEquippedItems, dorgeshKaanSphere, blackGoblinMail, huzamogaarbKey, hemensterWhitefish, pestleAndMortar, vial, @@ -379,7 +379,6 @@ protected void setupRequirements() draynorTeleport = new ItemRequirement("Draynor Village teleport", ItemCollections.AMULET_OF_GLORIES, 2); draynorTeleport.setChargedItem(true); explorersRing = new ItemRequirement("Explorer's ring 3 or 4", Arrays.asList(ItemID.LUMBRIDGE_RING_HARD, ItemID.LUMBRIDGE_RING_ELITE)); - salveAmulet = new ItemRequirement("Salve amulet or Salve amulet (e)", ItemCollections.SALVE_AMULET); pharmakosBerryHighlight = new ItemRequirement("Pharmakos berries", ItemID.LOTG_PHARMAKOS_BERRY); pharmakosBerryHighlight.setHighlightInInventory(true); @@ -679,7 +678,7 @@ public ArrayList getItemRequirements() @Override public ArrayList getItemRecommended() { - return new ArrayList<>(Arrays.asList(tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing, salveAmulet)); + return new ArrayList<>(Arrays.asList(tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing)); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java index 3e83f50119a..020c14df1d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java @@ -33,104 +33,102 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class LostCity extends BasicQuestHelper { - //Items Required - ItemRequirement knife, axe, combatGear, teleport, bronzeAxe, dramenBranch, dramenStaff, dramenStaffEquipped; + // Required items + ItemRequirement axe; + ItemRequirement knife; - Requirement onEntrana, inDungeon, shamusNearby, bronzeAxeNearby, dramenSpiritNearby; + // Recommended items + ItemRequirement combatGear; + ItemRequirement teleport; - DetailedQuestStep talkToWarrior, chopTree, talkToShamus, goToEntrana, goDownHole, getAxe, pickupAxe, attemptToCutDramen, killDramenSpirit, cutDramenBranch, - teleportAway, craftBranch, enterZanaris, getAnotherBranch; + // Mid-quest item requirements + ItemRequirement bronzeOrIronAxe; + ItemRequirement dramenBranch; + ItemRequirement dramenStaff; + ItemRequirement dramenStaffEquipped; - //Zones - Zone entrana, entranaDungeon; + // Zones + Zone entrana; + Zone entranaDungeon; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); + // Miscellaneous requirements + ZoneRequirement onEntrana; + ZoneRequirement inDungeon; + NpcCondition shamusNearby; + Conditions axeNearby; + NpcCondition dramenSpiritNearby; - steps.put(0, talkToWarrior); + // Steps + NpcStep talkToWarrior; - ConditionalStep findShamus = new ConditionalStep(this, chopTree); - findShamus.addStep(shamusNearby, talkToShamus); + ObjectStep chopTree; + NpcStep talkToShamus; - steps.put(1, findShamus); + NpcStep goToEntrana; + ObjectStep goDownHole; + DetailedQuestStep getAxe; + DetailedQuestStep pickupAxe; + ObjectStep attemptToCutDramen; + NpcStep killDramenSpirit; - ConditionalStep killingTheSpirit = new ConditionalStep(this, goToEntrana); - killingTheSpirit.addStep(new Conditions(inDungeon, dramenSpiritNearby), killDramenSpirit); - killingTheSpirit.addStep(new Conditions(inDungeon, bronzeAxe), attemptToCutDramen); - killingTheSpirit.addStep(new Conditions(inDungeon, bronzeAxeNearby), pickupAxe); - killingTheSpirit.addStep(inDungeon, getAxe); - killingTheSpirit.addStep(onEntrana, goDownHole); + ObjectStep cutDramenBranch; + DetailedQuestStep teleportAway; + DetailedQuestStep craftBranch; + ObjectStep enterZanaris; + DetailedQuestStep getAnotherBranch; - steps.put(2, killingTheSpirit); - - ConditionalStep finishQuest = new ConditionalStep(this, getAnotherBranch); - finishQuest.addStep(new Conditions(inDungeon, dramenStaff), teleportAway); - finishQuest.addStep(dramenStaff, enterZanaris); - finishQuest.addStep(new Conditions(inDungeon, dramenBranch), teleportAway); - finishQuest.addStep(dramenBranch, craftBranch); - finishQuest.addStep(new Conditions(inDungeon, bronzeAxe), cutDramenBranch); - finishQuest.addStep(new Conditions(inDungeon, bronzeAxeNearby), pickupAxe); - finishQuest.addStep(inDungeon, getAxe); - finishQuest.addStep(onEntrana, goDownHole); - - steps.put(3, finishQuest); - - steps.put(4, finishQuest); - - steps.put(5, finishQuest); - - return steps; + @Override + protected void setupZones() + { + entrana = new Zone(new WorldPoint(2798, 3327, 0), new WorldPoint(2878, 3394, 1)); + entranaDungeon = new Zone(new WorldPoint(2817, 9722, 0), new WorldPoint(2879, 9784, 0)); } @Override protected void setupRequirements() { - knife = new ItemRequirement("Knife", ItemID.KNIFE).isNotConsumed(); - bronzeAxe = new ItemRequirement("Bronze axe", ItemID.BRONZE_AXE).isNotConsumed(); axe = new ItemRequirement("Any axe", ItemID.BRONZE_AXE).isNotConsumed(); axe.addAlternates(ItemCollections.AXES); + knife = new ItemRequirement("Knife", ItemID.KNIFE).isNotConsumed(); + combatGear = new ItemRequirement("Runes, or a way of dealing damage which you can smuggle onto Entrana. Runes for Crumble Undead (level 39 Magic) are best", -1, -1).isNotConsumed(); combatGear.setDisplayItemId(ItemID.SKULL); teleport = new ItemRequirement("Teleport, preferably to Lumbridge. Home teleport will work if off cooldown", ItemID.RING_OF_ELEMENTS_CHARGED); teleport.addAlternates(ItemID.POH_TABLET_LUMBRIDGETELEPORT); + + bronzeOrIronAxe = new ItemRequirement("Bronze or Iron axe", ItemID.BRONZE_AXE).isNotConsumed(); + bronzeOrIronAxe.addAlternates(ItemID.IRON_AXE); dramenBranch = new ItemRequirement("Dramen branch", ItemID.DRAMEN_BRANCH); dramenStaff = new ItemRequirement("Dramen staff", ItemID.DRAMEN_STAFF); - dramenStaffEquipped = new ItemRequirement("Dramen staff", ItemID.DRAMEN_STAFF, 1, true); - } + dramenStaffEquipped = dramenStaff.equipped(); - @Override - protected void setupZones() - { - entrana = new Zone(new WorldPoint(2798, 3327, 0), new WorldPoint(2878, 3394, 1)); - entranaDungeon = new Zone(new WorldPoint(2817, 9722, 0), new WorldPoint(2879, 9784, 0)); - } - - public void setupConditions() - { onEntrana = new ZoneRequirement(entrana); inDungeon = new ZoneRequirement(entranaDungeon); shamusNearby = new NpcCondition(NpcID.ZANARISLEPRECHAUN); - bronzeAxeNearby = new ItemOnTileRequirement(ItemID.BRONZE_AXE); + axeNearby = or(new ItemOnTileRequirement(ItemID.BRONZE_AXE), new ItemOnTileRequirement(ItemID.IRON_AXE)); dramenSpiritNearby = new NpcCondition(NpcID.TREE_SPIRIT); } @@ -141,59 +139,118 @@ public void setupSteps() talkToWarrior.addDialogStep("What makes you think it's out here?"); talkToWarrior.addDialogStep("If it's hidden how are you planning to find it?"); talkToWarrior.addDialogStep("Looks like you don't know either."); + talkToWarrior.addDialogStep("Yes."); + chopTree = new ObjectStep(this, ObjectID.LEPRECHAUNTREE, new WorldPoint(3139, 3213, 0), "Try cutting the tree just to the west.", axe); chopTree.addDialogStep("I've been in that shed, I didn't see a city."); + talkToShamus = new NpcStep(this, NpcID.ZANARISLEPRECHAUN, new WorldPoint(3138, 3212, 0), "Talk to Shamus."); talkToShamus.addDialogStep("I've been in that shed, I didn't see a city."); + goToEntrana = new NpcStep(this, NpcID.SHIPMONK1_C, new WorldPoint(3047, 3236, 0), "Bank all weapons and armour you have (including the axe), and go to Port Sarim to get a boat to Entrana.", combatGear); + goDownHole = new ObjectStep(this, ObjectID.ENTRANALADDERTOP, new WorldPoint(2820, 3374, 0), "Climb down the ladder on the north side of the island. Once you go down, you can only escape via teleport."); goDownHole.addDialogStep("Well that is a risk I will have to take."); - getAxe = new DetailedQuestStep(this, new WorldPoint(2843, 9760, 0), "Kill zombies until one drops a bronze axe."); - pickupAxe = new DetailedQuestStep(this, "Pick up the bronze axe", bronzeAxe); - attemptToCutDramen = new ObjectStep(this, ObjectID.DRAMENTREE, new WorldPoint(2861, 9735, 0), "Attempt to cut a branch from the Dramen tree. Be prepared for a Tree Spirit (level 101) to appear, which you can safespot behind nearby fungus.", bronzeAxe); + + getAxe = new DetailedQuestStep(this, new WorldPoint(2843, 9760, 0), "Kill zombies until one drops an axe."); + pickupAxe = new DetailedQuestStep(this, "Pick up the axe", bronzeOrIronAxe); + getAxe.addSubSteps(pickupAxe); + + attemptToCutDramen = new ObjectStep(this, ObjectID.DRAMENTREE, new WorldPoint(2861, 9735, 0), "Attempt to cut a branch from the Dramen tree. Be prepared for a Tree Spirit (level 101) to appear, which you can safespot behind nearby fungus.", bronzeOrIronAxe); + killDramenSpirit = new NpcStep(this, NpcID.TREE_SPIRIT, new WorldPoint(2859, 9734, 0), "Kill the Tree Spirit. They can be safespotted behind nearby fungi to the east."); + killDramenSpirit.addSafeSpots(new WorldPoint(2856, 9730, 0)); + cutDramenBranch = new ObjectStep(this, ObjectID.DRAMENTREE, new WorldPoint(2861, 9735, 0), "Cut at least one branch from the Dramen tree. It's recommended you cut at least 4 branches so you don't have to return in future quests."); + teleportAway = new DetailedQuestStep(this, "Teleport away with the branches, preferably to Lumbridge.", dramenBranch); teleportAway.addTeleport(teleport); - getAnotherBranch = new DetailedQuestStep(this, "If you've lost your Dramen branch/staff, you will need to return to Entrana and cut another. You will not need to defeat the Tree Spirit again."); - craftBranch = new DetailedQuestStep(this, "Use a knife on the dramen branch to craft a dramen staff.", knife, dramenBranch); - enterZanaris = new ObjectStep(this, ObjectID.ZANARISDOOR, new WorldPoint(3202, 3169, 0), "Enter the shed south of Lumbridge with your Dramen Staff equipped.", dramenStaffEquipped); + + getAnotherBranch = new DetailedQuestStep(this, "If you've lost your Dramen branch/staff, you will need to return to Entrana and cut another. You will not need to defeat the Tree Spirit again.", dramenBranch); + goToEntrana.addSubSteps(getAnotherBranch); + + craftBranch = new DetailedQuestStep(this, "Use a knife on the dramen branch to craft a dramen staff.", knife.highlighted(), dramenBranch.highlighted()); + + enterZanaris = new ObjectStep(this, ObjectID.ZANARISDOOR, new WorldPoint(3202, 3169, 0), "Enter the shed south of Lumbridge with your Dramen Staff equipped.", dramenStaffEquipped.highlighted()); } @Override - public List getCombatRequirements() + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToWarrior); + + var findShamus = new ConditionalStep(this, chopTree); + findShamus.addStep(shamusNearby, talkToShamus); + + steps.put(1, findShamus); + + var killingTheSpirit = new ConditionalStep(this, goToEntrana); + killingTheSpirit.addStep(and(inDungeon, dramenSpiritNearby), killDramenSpirit); + killingTheSpirit.addStep(and(inDungeon, bronzeOrIronAxe), attemptToCutDramen); + killingTheSpirit.addStep(and(inDungeon, axeNearby), pickupAxe); + killingTheSpirit.addStep(inDungeon, getAxe); + killingTheSpirit.addStep(onEntrana, goDownHole); + + steps.put(2, killingTheSpirit); + + var finishQuest = new ConditionalStep(this, getAnotherBranch); + finishQuest.addStep(and(inDungeon, dramenStaff), teleportAway); + finishQuest.addStep(dramenStaff.alsoCheckBank(), enterZanaris); + finishQuest.addStep(and(inDungeon, dramenBranch), teleportAway); + finishQuest.addStep(dramenBranch.alsoCheckBank(), craftBranch); + finishQuest.addStep(and(inDungeon, bronzeOrIronAxe), cutDramenBranch); + finishQuest.addStep(and(inDungeon, axeNearby), pickupAxe); + finishQuest.addStep(inDungeon, getAxe); + finishQuest.addStep(onEntrana, goDownHole); + + steps.put(3, finishQuest); + + steps.put(4, finishQuest); + + steps.put(5, finishQuest); + + return steps; + } + + @Override + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Multiple zombies (level 25) (can be safespotted)"); - reqs.add("Dramen Tree Spirit (level 101) (can be safespotted)"); - return reqs; + return List.of( + new SkillRequirement(Skill.CRAFTING, 31, true), + new SkillRequirement(Skill.WOODCUTTING, 36, true) + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(axe); - reqs.add(knife); - return reqs; + return List.of( + axe, + knife + ); } @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - reqs.add(combatGear); - reqs.add(teleport); - return reqs; + return List.of( + combatGear, + teleport + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new SkillRequirement(Skill.CRAFTING, 31, true)); - req.add(new SkillRequirement(Skill.WOODCUTTING, 36, true)); - return req; + return List.of( + "Multiple zombies (level 25) (can be safespotted)", + "Dramen Tree Spirit (level 101) (can be safespotted)" + ); } @Override @@ -205,22 +262,51 @@ public QuestPointReward getQuestPointReward() @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to Zanaris."), - new UnlockReward("Ability to craft Cosmic Runes"), - new UnlockReward("Ability to buy and wield Dragon Daggers & Longswords")); + return List.of( + new UnlockReward("Access to Zanaris."), + new UnlockReward("Ability to craft Cosmic Runes"), + new UnlockReward("Ability to buy and wield Dragon Daggers & Longswords") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToWarrior), axe)); - allSteps.add(new PanelDetails("Finding Shamus", Arrays.asList(chopTree, talkToShamus))); - allSteps.add(new PanelDetails("Getting a Dramen branch", Arrays.asList(goToEntrana, goDownHole, getAxe, attemptToCutDramen, killDramenSpirit, - cutDramenBranch, teleportAway), List.of(), List.of(combatGear, teleport))); - allSteps.add(new PanelDetails("Entering Zanaris", Arrays.asList(craftBranch, enterZanaris), knife)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToWarrior + ), List.of( + axe + ))); + + sections.add(new PanelDetails("Finding Shamus", List.of( + chopTree, + talkToShamus + ))); + + sections.add(new PanelDetails("Getting a Dramen branch", List.of( + goToEntrana, + goDownHole, + getAxe, + attemptToCutDramen, + killDramenSpirit, + cutDramenBranch, + teleportAway + ), List.of( + // No requirements + ), List.of( + combatGear, + teleport + ))); + + sections.add(new PanelDetails("Entering Zanaris", List.of( + craftBranch, + enterZanaris + ), List.of( + knife + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java index 2cb99b031cd..435a4e3cee7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java @@ -150,7 +150,7 @@ protected void setupRequirements() portPhasmatysEntry.setTooltip(ectoTokens.getTooltip()); ringOfDueling = new ItemRequirement("Ring of Dueling", ItemCollections.RING_OF_DUELINGS); - enchantedKey = new KeyringRequirement("Enchanted key", configManager, KeyringCollection.ENCHANTED_KEY); + enchantedKey = new KeyringRequirement("Enchanted key", KeyringCollection.ENCHANTED_KEY); enchantedKey.setTooltip("You can get another from the silver merchant in East Ardougne's market"); enchantedKeyHighlighted = new ItemRequirement("Enchanted key", ItemID.MAKINGHISTORY_KEY); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java index 44595dcca7b..bed2c7f0d90 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java @@ -32,25 +32,28 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; public class MerlinsCrystal extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java index c1481e5898e..414c9e5160a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java @@ -29,6 +29,7 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -37,17 +38,24 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.WidgetStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class MisthalinMystery extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java index 0eab1b12193..506249ce604 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java @@ -768,7 +768,7 @@ public void setupSteps() )); killZombie = new NpcStep(this, NpcID.MM_TRANSMOGRIFICATION_SMALL_ZOMBIE_MONKEY, new WorldPoint(2808, 9201, 0), "Kill a zombie monkey for their bones.", true, zombieBones); - killGorilla = new NpcStep(this, NpcID.MM_RELIGIOUS_GUARD, new WorldPoint(2801, 2785, 0), "Kill a gorilla in the temple for their bones.", + killGorilla = new NpcStep(this, NpcID.MM_RELIGIOUS_GUARD, new WorldPoint(2801, 2785, 0), "Kill a gorilla in the temple for their bones. If they can attack you they will heal on hit, so it's recommended to safespot or flinch one.", true, gorillaBones); ((NpcStep) killGorilla).addAlternateNpcs(NpcID.MM_RELIGIOUS_TRAPDOOR_GUARD); killGorilla.setLinePoints(Arrays.asList( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java index 7de82ad5d86..0ba1c6e4191 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java @@ -42,9 +42,13 @@ import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; + import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; import java.util.*; @@ -417,7 +421,7 @@ public void checkSection5Successes() { return; } - WorldPoint currentPosition = Rs2Player.getWorldLocation(); + WorldPoint currentPosition = player.getWorldLocation(); for (int i = 0; i < fifthSectionMap.length; i++) { MM2Route[] pathsFromNode = fifthSectionMap[i].getPaths(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java index adfb1bf8309..2129cca22ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java @@ -24,28 +24,31 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.monksfriend; +import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class MonksFriend extends BasicQuestHelper { // Required items @@ -89,12 +92,9 @@ protected void setupRequirements() log = new ItemRequirement("Logs", ItemID.LOGS); jugOfWater = new ItemRequirement("Jug of Water", ItemID.JUG_WATER); + jugOfWater.setTooltip("You can find one in the Yanille cooking shop"); blanket = new ItemRequirement("Child's blanket", ItemID.CHILDS_BLANKET); - ardougneCloak = new ItemRequirement("Ardougne cloak 1 or higher for teleports to the monastery", ItemID.CERT_ARRAVCERTIFICATE).isNotConsumed(); - } - - public void setupConditions() - { + ardougneCloak = new ItemRequirement("Ardougne cloak 1 or higher for teleports to the monastery", ItemCollections.ARDOUGNE_CLOAK).isNotConsumed(); } public void setupSteps() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java index 8656228c9ac..1818879a21b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java @@ -44,7 +44,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java index d078424a57c..4bc1e51ca45 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java @@ -396,7 +396,7 @@ public void setupSteps() askAboutToads = new NpcStep(this, NpcID.MOURNER_HIDEOUT_GNOME_HEAD, new WorldPoint(2035, 4630, 0), "Ask the gnome about ammo."); getToads = new DetailedQuestStep(this, new WorldPoint(2599, 2966, 0), - "You need to make some dyed toads. Go to Feldip Hills, use a dye on your empty bellows, then use the " + + "You need to make some dyed toads. Go to Feldip Hills (AKS), use a dye on your empty bellows, then use the " + "bellows to inflate a toad. Get at least one toad of each colour.", redToad, yellowToad, greenToad, blueToad); loadGreenToad = new DetailedQuestStep(this, "Add a green toad to the fixed device.", greenToad.highlighted(), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java index 9fe790e908b..897b4cd3d6d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java @@ -425,7 +425,7 @@ protected void setupRequirements() ItemCollections.PRAYER_POTIONS, -1); food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); - newKey = new KeyringRequirement("New Key", configManager, KeyringCollection.NEW_KEY); + newKey = new KeyringRequirement("New Key", KeyringCollection.NEW_KEY); newKey.setTooltip("You can get another from Essyllt's desk"); edernsJournal = new ItemRequirement("Edern's journal", ItemID.MOURNING_EDERNS_JOURNAL); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java index dc9ceec725b..7439a54df9a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java @@ -31,6 +31,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -39,17 +42,23 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; public class MurderMystery extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java index dff3eeb43c7..e3647a41ace 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java @@ -385,7 +385,7 @@ public void setupSteps() talkToMyArmAfterBaby = new NpcStep(this, NpcID.MYARM_FIXED, new WorldPoint(2829, 3695, 0), "Talk to My Arm. Be prepared to fight the Giant Roc.", combatGear, spade); - killGiantRoc = new NpcStep(this, NpcID.MYARM_GIANT_ROC, "Kill the Giant Roc. Use protected from ranged, and keep your distance. You can dodge the boulders it throws."); + killGiantRoc = new NpcStep(this, NpcID.MYARM_GIANT_ROC, "Kill the Giant Roc. Use protect from missiles, and keep your distance. You can dodge the boulders it throws."); talkToMyArmAfterHarvest = new NpcStep(this, NpcID.MYARM_FIXED, new WorldPoint(2829, 3695, 0), "Talk to My Arm."); giveSpade = new NpcStep(this, NpcID.MYARM_FIXED, new WorldPoint(2829, 3695, 0), "Give My Arm a spade.", spadeHighlight); giveSpade.addIcon(ItemID.SPADE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java index 1cb97897dfe..ac557aae167 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java @@ -43,7 +43,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -52,113 +60,84 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class NatureSpirit extends BasicQuestHelper { - //Items Required - ItemRequirement ghostspeak, silverSickle, washingBowl, mirror, journal, druidicSpell, druidPouch, blessedSickle, - spellCard, mirrorHighlighted, journalHighlighted, mushroom, mushroomHighlighted, druidPouchFull; - - //Items Recommended - ItemRequirement combatGear, salveTele; - - Requirement inUnderground, fillimanNearby, mirrorNearby, usedMushroom, onOrange, - usedCard, inGrotto, natureSpiritNearby, ghastNearby, prayerPoints; - - QuestStep goDownToDrezel, talkToDrezel, leaveDrezel, enterSwamp, tryToEnterGrotto, talkToFilliman, takeWashingBowl, - takeMirror, useMirrorOnFilliman, searchGrotto, useJournalOnFilliman, goBackDownToDrezel, talkToDrezelForBlessing, - castSpellAndGetMushroom, useMushroom, useSpellCard, standOnOrange, tellFillimanToCast, enterGrotto, searchAltar, - blessSickle, fillPouches, killGhasts, killGhast, enterGrottoAgain, touchAltarAgain, talkToNatureSpiritToFinish, - spawnFillimanForRitual, talkToFillimanInGrotto; - - //Zones - Zone underground, orangeStone, grotto; + // Required items + ItemRequirement ghostspeak; + ItemRequirement silverSickle; + + // Recommended items + ItemRequirement combatGear; + ItemRequirement salveTele; + + // Mid-quest requirements + ItemRequirement washingBowl; + ItemRequirement mirror; + ItemRequirement journal; + ItemRequirement druidicSpell; + ItemRequirement druidPouch; + ItemRequirement blessedSickle; + ItemRequirement spellCard; + ItemRequirement mirrorHighlighted; + ItemRequirement journalHighlighted; + ItemRequirement mushroom; + ItemRequirement mushroomHighlighted; + ItemRequirement druidPouchFull; + + // Zones + Zone underground; + Zone orangeStone; + Zone grotto; + + // Miscellaneous requirements + ZoneRequirement inUnderground; + NpcCondition fillimanNearby; + ItemOnTileRequirement mirrorNearby; + Conditions usedMushroom; + ZoneRequirement onOrange; + Conditions usedCard; + ZoneRequirement inGrotto; + NpcCondition natureSpiritNearby; + NpcCondition ghastNearby; + PrayerPointRequirement prayerPoints; + + // Steps + ObjectStep goDownToDrezel; + NpcStep talkToDrezel; + ObjectStep leaveDrezel; + ObjectStep enterSwamp; + ObjectStep tryToEnterGrotto; + NpcStep talkToFilliman; + DetailedQuestStep takeWashingBowl; + DetailedQuestStep takeMirror; + NpcStep useMirrorOnFilliman; + ObjectStep searchGrotto; + NpcStep useJournalOnFilliman; + ObjectStep goBackDownToDrezel; + NpcStep talkToDrezelForBlessing; + DetailedQuestStep castSpellAndGetMushroom; + ObjectStep useMushroom; + ObjectStep useSpellCard; + DetailedQuestStep standOnOrange; + NpcStep tellFillimanToCast; + ObjectStep enterGrotto; + ObjectStep searchAltar; + NpcStep blessSickle; + DetailedQuestStep fillPouches; + NpcStep killGhasts; + NpcStep killGhast; + ObjectStep enterGrottoAgain; + ObjectStep touchAltarAgain; + NpcStep talkToNatureSpiritToFinish; + ObjectStep spawnFillimanForRitual; + NpcStep talkToFillimanInGrotto; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - ConditionalStep startQuest = new ConditionalStep(this, goDownToDrezel); - startQuest.addStep(inUnderground, talkToDrezel); - - steps.put(0, startQuest); - - ConditionalStep goEnterSwamp = new ConditionalStep(this, enterSwamp); - goEnterSwamp.addStep(inUnderground, leaveDrezel); - steps.put(1, goEnterSwamp); - steps.put(2, goEnterSwamp); - steps.put(3, goEnterSwamp); - steps.put(4, goEnterSwamp); - steps.put(5, goEnterSwamp); - - ConditionalStep goTalkToFilliman = new ConditionalStep(this, tryToEnterGrotto); - goTalkToFilliman.addStep(fillimanNearby, talkToFilliman); - steps.put(10, goTalkToFilliman); - steps.put(15, goTalkToFilliman); - - ConditionalStep showFillimanReflection = new ConditionalStep(this, takeWashingBowl); - showFillimanReflection.addStep(new Conditions(mirror, fillimanNearby), useMirrorOnFilliman); - showFillimanReflection.addStep(mirror, tryToEnterGrotto); - showFillimanReflection.addStep(mirrorNearby, takeMirror); - steps.put(20, showFillimanReflection); - - ConditionalStep goGetJournal = new ConditionalStep(this, searchGrotto); - goGetJournal.addStep(new Conditions(journal, fillimanNearby), useJournalOnFilliman); - goGetJournal.addStep(journal, tryToEnterGrotto); - steps.put(25, goGetJournal); - - ConditionalStep goOfferHelp = new ConditionalStep(this, tryToEnterGrotto); - goOfferHelp.addStep(fillimanNearby, useJournalOnFilliman); - steps.put(30, goOfferHelp); - - ConditionalStep getBlessed = new ConditionalStep(this, goBackDownToDrezel); - getBlessed.addStep(inUnderground, talkToDrezelForBlessing); - steps.put(35, getBlessed); - - ConditionalStep performRitual = new ConditionalStep(this, castSpellAndGetMushroom); - performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby, onOrange), tellFillimanToCast); - performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby), standOnOrange); - performRitual.addStep(new Conditions(usedMushroom, usedCard), spawnFillimanForRitual); - performRitual.addStep(usedMushroom, useSpellCard); - performRitual.addStep(mushroom, useMushroom); - steps.put(40, performRitual); - steps.put(45, performRitual); - steps.put(50, performRitual); - steps.put(55, performRitual); - - ConditionalStep goTalkInGrotto = new ConditionalStep(this, enterGrotto); - goTalkInGrotto.addStep(new Conditions(inGrotto, fillimanNearby), talkToFillimanInGrotto); - goTalkInGrotto.addStep(inGrotto, searchAltar); - steps.put(60, goTalkInGrotto); - - ConditionalStep goBlessSickle = new ConditionalStep(this, enterGrotto); - goBlessSickle.addStep(new Conditions(inGrotto, natureSpiritNearby), blessSickle); - goBlessSickle.addStep(inGrotto, searchAltar); - steps.put(65, goBlessSickle); - steps.put(70, goBlessSickle); - - ConditionalStep goKillGhasts = new ConditionalStep(this, fillPouches); - // TODO: Fix ghast changing form not counting towards becoming nearby - goKillGhasts.addStep(ghastNearby, killGhast); - goKillGhasts.addStep(druidPouchFull, killGhasts); - steps.put(75, goKillGhasts); - steps.put(80, goKillGhasts); - steps.put(85, goKillGhasts); - steps.put(90, goKillGhasts); - steps.put(95, goKillGhasts); - steps.put(100, goKillGhasts); - - ConditionalStep finishOff = new ConditionalStep(this, enterGrottoAgain); - finishOff.addStep(new Conditions(inGrotto, natureSpiritNearby), talkToNatureSpiritToFinish); - finishOff.addStep(inGrotto, touchAltarAgain); - steps.put(105, finishOff); - - return steps; + underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); + orangeStone = new Zone(new WorldPoint(3440, 3335, 0), new WorldPoint(3440, 3335, 0)); + grotto = new Zone(new WorldPoint(3435, 9733, 0), new WorldPoint(3448, 9746, 0)); } @Override @@ -184,23 +163,10 @@ protected void setupRequirements() spellCard.addAlternates(ItemID.BLOOM_SPELL); spellCard.setTooltip("You can get another spell from Filliman"); mushroom = new ItemRequirement("Mort myre fungus", ItemID.MORTMYREMUSHROOM); - mushroomHighlighted = new ItemRequirement("Mort myre fungus", ItemID.MORTMYREMUSHROOM); - mushroomHighlighted.setHighlightInInventory(true); + mushroomHighlighted = mushroom.highlighted(); salveTele = new ItemRequirement("Salve Graveyard Teleports", ItemID.TELETAB_SALVE, 2); combatGear = new ItemRequirement("Combat gear to kill the ghasts", -1, -1).isNotConsumed(); combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); - } - - @Override - protected void setupZones() - { - underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); - orangeStone = new Zone(new WorldPoint(3440, 3335, 0), new WorldPoint(3440, 3335, 0)); - grotto = new Zone(new WorldPoint(3435, 9733, 0), new WorldPoint(3448, 9746, 0)); - } - - public void setupConditions() - { inUnderground = new ZoneRequirement(underground); onOrange = new ZoneRequirement(orangeStone); inGrotto = new ZoneRequirement(grotto); @@ -223,12 +189,13 @@ public void setupConditions() public void setupSteps() { goDownToDrezel = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Talk to Drezel under the Paterdomus Temple."); - ((ObjectStep) (goDownToDrezel)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + goDownToDrezel.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); talkToDrezel = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Talk to Drezel under the Paterdomus Temple."); talkToDrezel.addDialogSteps("Well, what is it, I may be able to help?", "Yes."); talkToDrezel.addSubSteps(goDownToDrezel); leaveDrezel = new ObjectStep(this, ObjectID.PIP_UNDERGROUND_WALL_SIDE_WITHPORTAL, new WorldPoint(3440, 9886, 0), "Enter the Mort Myre from the north gate."); enterSwamp = new ObjectStep(this, ObjectID.MORTMYRE_METALGATECLOSED_L, new WorldPoint(3444, 3458, 0), "Enter the Mort Myre from the north gate.", ghostspeak); + enterSwamp.addSubSteps(leaveDrezel); tryToEnterGrotto = new ObjectStep(this, ObjectID.GROTTO_DOOR_DRUIDICSPIRIT, new WorldPoint(3440, 3337, 0), "Attempt to enter the Grotto in the south of Mort Myre.", ghostspeak); tryToEnterGrotto.addDialogStep("How long have you been a ghost?"); talkToFilliman = new NpcStep(this, NpcID.FILLIMAN_TARLOCK_SPIRIT, new WorldPoint(3440, 3336, 0), "Talk to Filliman Tarlock.", ghostspeak); @@ -242,12 +209,13 @@ public void setupSteps() useJournalOnFilliman = new NpcStep(this, NpcID.FILLIMAN_TARLOCK_SPIRIT, new WorldPoint(3440, 3336, 0), "Use the journal on Filliman Tarlock.", ghostspeak, journalHighlighted); useJournalOnFilliman.addIcon(ItemID.FILLIMAN_JOURNAL); useJournalOnFilliman.addDialogStep("How can I help?"); - goBackDownToDrezel = new ObjectStep(this, ObjectID.PIPEASTSIDETRAPDOOR, new WorldPoint(3422, 3485, 0), "Talk to Drezel to get blessed."); - ((ObjectStep) (goBackDownToDrezel)).addAlternateObjects(ObjectID.PIPEASTSIDETRAPDOOR_OPEN); - talkToDrezelForBlessing = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Talk to Drezel under the Paterdomus Temple."); + goBackDownToDrezel = new ObjectStep(this, ObjectID.PIPEASTSIDETRAPDOOR, new WorldPoint(3422, 3485, 0), "Return to Drezel under the Paterdomus Temple to get blessed."); + goBackDownToDrezel.addAlternateObjects(ObjectID.PIPEASTSIDETRAPDOOR_OPEN); + talkToDrezelForBlessing = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Return to Drezel under the Paterdomus Temple to get blessed."); talkToDrezelForBlessing.addSubSteps(goBackDownToDrezel); talkToDrezelForBlessing.addSubSteps(goBackDownToDrezel); - castSpellAndGetMushroom = new DetailedQuestStep(this, "Cast the druidic spell next to a rotten log in Mort Myre to grow a mushroom. Pick it. If you already have, open the quest journal to re-sync your state.", druidicSpell); + castSpellAndGetMushroom = new ObjectStep(this, ObjectID.LOG_DRUIDICSPIRIT2, "Cast the druidic spell next to a rotten log in Mort Myre to grow a mushroom. Pick it. If you already have, open the quest journal to re-sync your state.", druidicSpell); + castSpellAndGetMushroom.addDialogStep("Could I have another bloom scroll please?"); useMushroom = new ObjectStep(this, ObjectID.STONEDISC_DS_NATURE, new WorldPoint(3439, 3336, 0), "Use the mushroom on the brown stone outside the grotto. If you already have, search it instead.", mushroomHighlighted); useMushroom.addIcon(ItemID.MORTMYREMUSHROOM); useSpellCard = new ObjectStep(this, ObjectID.STONEDISC_DS_SPIRIT, new WorldPoint(3441, 3336, 0), "Use the used spell on the gray stone outside the grotto. If you already have, search it instead.", spellCard); @@ -265,7 +233,7 @@ public void setupSteps() blessSickle = new NpcStep(this, NpcID.FILLIMAN_TARLOCK_NS, new WorldPoint(3441, 9738, 0), "Talk to the Nature Spirit in the grotto to bless your sickle.", ghostspeak, silverSickle); fillPouches = new DetailedQuestStep(this, "Right-click 'bloom' the blessed sickle next to rotten logs for mort myre fungi. Use these to fill the druid pouch.", blessedSickle, prayerPoints - , druidPouch); + , druidPouch); killGhasts = new NpcStep(this, NpcID.GHAST_INVIS, "Use the filled druid pouch on a ghast to make it attackable and kill it. You'll need to kill 3.", druidPouchFull); killGhast = new NpcStep(this, NpcID.GHAST_VIS, "Kill the ghast.", druidPouchFull); killGhasts.addSubSteps(killGhast); @@ -276,36 +244,132 @@ public void setupSteps() } @Override - public List getItemRequirements() + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + var startQuest = new ConditionalStep(this, goDownToDrezel); + startQuest.addStep(inUnderground, talkToDrezel); + steps.put(0, startQuest); + + var goEnterSwamp = new ConditionalStep(this, enterSwamp); + goEnterSwamp.addStep(inUnderground, leaveDrezel); + steps.put(1, goEnterSwamp); + steps.put(2, goEnterSwamp); + steps.put(3, goEnterSwamp); + steps.put(4, goEnterSwamp); + steps.put(5, goEnterSwamp); + + var goTalkToFilliman = new ConditionalStep(this, tryToEnterGrotto); + goTalkToFilliman.addStep(fillimanNearby, talkToFilliman); + steps.put(10, goTalkToFilliman); + steps.put(15, goTalkToFilliman); + + var showFillimanReflection = new ConditionalStep(this, takeWashingBowl); + showFillimanReflection.addStep(new Conditions(mirror, fillimanNearby), useMirrorOnFilliman); + showFillimanReflection.addStep(mirror, tryToEnterGrotto); + showFillimanReflection.addStep(mirrorNearby, takeMirror); + steps.put(20, showFillimanReflection); + + var goGetJournal = new ConditionalStep(this, searchGrotto); + goGetJournal.addStep(new Conditions(journal, fillimanNearby), useJournalOnFilliman); + goGetJournal.addStep(journal, tryToEnterGrotto); + steps.put(25, goGetJournal); + + var goOfferHelp = new ConditionalStep(this, tryToEnterGrotto); + goOfferHelp.addStep(fillimanNearby, useJournalOnFilliman); + steps.put(30, goOfferHelp); + + var getBlessed = new ConditionalStep(this, goBackDownToDrezel); + getBlessed.addStep(inUnderground, talkToDrezelForBlessing); + steps.put(35, getBlessed); + + var performRitual = new ConditionalStep(this, castSpellAndGetMushroom); + performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby, onOrange), tellFillimanToCast); + performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby), standOnOrange); + performRitual.addStep(new Conditions(usedMushroom, usedCard), spawnFillimanForRitual); + performRitual.addStep(usedMushroom, useSpellCard); + performRitual.addStep(mushroom, useMushroom); + steps.put(40, performRitual); + steps.put(45, performRitual); + steps.put(50, performRitual); + steps.put(55, performRitual); + + var goTalkInGrotto = new ConditionalStep(this, enterGrotto); + goTalkInGrotto.addStep(new Conditions(inGrotto, fillimanNearby), talkToFillimanInGrotto); + goTalkInGrotto.addStep(inGrotto, searchAltar); + steps.put(60, goTalkInGrotto); + + var goBlessSickle = new ConditionalStep(this, enterGrotto); + goBlessSickle.addStep(new Conditions(inGrotto, natureSpiritNearby), blessSickle); + goBlessSickle.addStep(inGrotto, searchAltar); + steps.put(65, goBlessSickle); + steps.put(70, goBlessSickle); + + var goKillGhasts = new ConditionalStep(this, fillPouches); + // TODO: Fix ghast changing form not counting towards becoming nearby + goKillGhasts.addStep(ghastNearby, killGhast); + goKillGhasts.addStep(druidPouchFull, killGhasts); + steps.put(75, goKillGhasts); + steps.put(80, goKillGhasts); + steps.put(85, goKillGhasts); + steps.put(90, goKillGhasts); + steps.put(95, goKillGhasts); + steps.put(100, goKillGhasts); + + var finishOff = new ConditionalStep(this, enterGrottoAgain); + finishOff.addStep(new Conditions(inGrotto, natureSpiritNearby), talkToNatureSpiritToFinish); + finishOff.addStep(inGrotto, touchAltarAgain); + steps.put(105, finishOff); + + return steps; + } + + + @Override + public List getGeneralRequirements() { - return Arrays.asList(ghostspeak, silverSickle); + return List.of( + new QuestRequirement(QuestHelperQuest.THE_RESTLESS_GHOST, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.PRIEST_IN_PERIL, QuestState.FINISHED) + ); } @Override - public List getItemRecommended() + public List getItemRequirements() { - return Arrays.asList(salveTele, combatGear); + return List.of( + ghostspeak, + silverSickle + ); } @Override - public List getNotes() + public List getItemRecommended() { - return Collections.singletonList("Whilst in Mort Myre, the Ghasts will occasionally rot the food in your inventory."); + return List.of( + salveTele, + combatGear + ); } @Override public List getCombatRequirements() { - return Collections.singletonList("3 Ghasts (level 30)"); + return List.of( + "3 Ghasts (level 30)" + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.THE_RESTLESS_GHOST, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.PRIEST_IN_PERIL, QuestState.FINISHED)); - return req; + return List.of( + "Whilst in Mort Myre, the Ghasts will occasionally rot the food in your inventory." + ); } @Override @@ -317,33 +381,70 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Arrays.asList( - new ExperienceReward(Skill.CRAFTING, 3000), - new ExperienceReward(Skill.DEFENCE, 2000), - new ExperienceReward(Skill.HITPOINTS, 2000)); + return List.of( + new ExperienceReward(Skill.CRAFTING, 3000), + new ExperienceReward(Skill.DEFENCE, 2000), + new ExperienceReward(Skill.HITPOINTS, 2000) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to Mort Myre Swamp"), - new UnlockReward("Ability to fight Ghasts.")); + return List.of( + new UnlockReward("Access to Mort Myre Swamp"), + new UnlockReward("Ability to fight Ghasts.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Start the quest", - Arrays.asList(talkToDrezel, enterSwamp, tryToEnterGrotto, talkToFilliman, takeWashingBowl, - takeMirror, useMirrorOnFilliman, searchGrotto, useJournalOnFilliman), ghostspeak, silverSickle, prayerPoints)); - allSteps.add(new PanelDetails("Helping Filliman", - Arrays.asList(talkToDrezelForBlessing, castSpellAndGetMushroom, useMushroom, useSpellCard, standOnOrange, - tellFillimanToCast, enterGrotto, searchAltar, talkToFillimanInGrotto, blessSickle), ghostspeak, silverSickle)); - allSteps.add(new PanelDetails("Killing Ghasts", - Arrays.asList(fillPouches, killGhasts, enterGrottoAgain, talkToNatureSpiritToFinish), ghostspeak, blessedSickle, prayerPoints)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Start the quest", List.of( + talkToDrezel, + enterSwamp, + tryToEnterGrotto, + talkToFilliman, + takeWashingBowl, + takeMirror, + useMirrorOnFilliman, + searchGrotto, + useJournalOnFilliman + ), List.of( + ghostspeak, + silverSickle, + prayerPoints + ))); + + sections.add(new PanelDetails("Helping Filliman", List.of( + talkToDrezelForBlessing, + castSpellAndGetMushroom, + useMushroom, + useSpellCard, + standOnOrange, + tellFillimanToCast, + enterGrotto, + searchAltar, + talkToFillimanInGrotto, + blessSickle + ), List.of( + ghostspeak, + silverSickle + ))); + + sections.add(new PanelDetails("Killing Ghasts", List.of( + fillPouches, + killGhasts, + enterGrottoAgain, + talkToNatureSpiritToFinish + ), List.of( + ghostspeak, + blessedSickle, + prayerPoints + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java index ecea6eb3551..b4760fc6bb9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java @@ -30,6 +30,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -37,18 +39,23 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; public class ObservatoryQuest extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/StarSignAnswer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/StarSignAnswer.java deleted file mode 100644 index 89661aad860..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/StarSignAnswer.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2021, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.helpers.quests.observatoryquest; - -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.VarbitChanged; -import net.runelite.api.gameval.NpcID; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestVarPlayer; -import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; - -import java.util.HashMap; - -public class StarSignAnswer extends NpcStep -{ - HashMap starSign = new HashMap<>(); - int currentValue = -1; - - public StarSignAnswer(QuestHelper questHelper) - { - super(questHelper, NpcID.OBSERVATORY_PROFESSOR, new WorldPoint(2440, 3159, - 1), "Tell the professor the constellation you observed."); - starSign.put(0, "Aquarius"); - starSign.put(1, "Capricorn"); - starSign.put(2, "Sagittarius"); - starSign.put(3, "Scorpio"); - starSign.put(4, "Libra"); - starSign.put(5, "Virgo"); - starSign.put(6, "Leo"); - starSign.put(7, "Cancer"); - starSign.put(8, "Gemini"); - starSign.put(9, "Taurus"); - starSign.put(10, "Aries"); - starSign.put(11, "Pisces"); - } - - @Override - public void startUp() - { - super.startUp(); - updateCorrectChoice(); - } - - @Override - public void onVarbitChanged(VarbitChanged varbitChanged) - { - super.onVarbitChanged(varbitChanged); - updateCorrectChoice(); - } - - private void updateCorrectChoice() - { - addDialogSteps("Talk about the Observatory quest."); - int currentStep = client.getVarpValue(QuestVarPlayer.QUEST_OBSERVATORY_QUEST.getId()); - if (currentStep < 2) - { - return; - } - - int newValue = client.getVarbitValue(3828); - if (currentValue != newValue) - { - currentValue = newValue; - String constellation = starSign.get(newValue); - setText("Tell the professor you observed " + constellation + "."); - addDialogStep(constellation); - } - - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java index 18224d1ca4e..b273261a7ca 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.onesmallfavour; +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; @@ -32,16 +33,32 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.TileStep; +import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -50,265 +67,302 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class OneSmallFavour extends BasicQuestHelper { - //Items Required - ItemRequirement steelBars4, steelBars3, steelBar, bronzeBar, ironBar, chisel, guam2, guam, marrentill, harralander, hammer, hammerHighlight, emptyCup, pigeonCages5, pot, hotWaterBowl, softClay, - opal, jade, sapphire, redTopaz, bluntAxe, herbalTincture, guthixRest, uncutSapphire, cupOfWater, - uncutOpal, uncutJade, uncutRedTopaz, stodgyMattress, mattress, animateRockScroll, animateRockScrollHighlight, ironOxide, brokenVane1, brokenVane2, brokenVane3, ornament, - weathervanePillar, directionals, weatherReport, unfiredPotLid, potLid, potWithLid, breathingSalts, chickenCages5, sharpenedAxe, redMahog; - - ItemRequirement guamTea, guam2Tea, harrTea, marrTea, guamMarrTea, guamHarrTea, harrMarrTea, guam2MarrTea, - guam2HarrTea, guamHarrMarrTea, herbTeaMix; - - //Items Recommended - ItemRequirement draynorVillageTeleports, lumbridgeTeleports, varrockTeleports, taverleyOrFaladorTeleports, camelotTeleports, fishingGuildAndDwarvenMineTeleports, ardougneTeleports, khazardTeleports, feldipHillsTeleports, pickaxe; - - Requirement inSanfewRoom, inHamBase, inDwarvenMine, inGoblinCave, lamp1Empty, lamp1Full, lamp2Empty, lamp2Full, - lamp3Empty, lamp3Full, lamp4Empty, lamp4Full, lamp5Empty, lamp5Full, lamp6Empty, lamp6Full, lamp7Empty, lamp7Full, lamp8Empty, lamp8Full, allEmpty, allFull, inScrollSpot, - slagilithNearby, petraNearby, inSeersVillageUpstairs, onRoof, addedOrnaments, addedDirectionals, addedWeathervanePillar, hasOrUsedOrnament, hasOrUsedDirectionals, - hasOrUsedWeathervanePillar; - - DetailedQuestStep talkToYanni, talkToJungleForester, talkToBrian, talkToAggie, goDownToJohanhus, talkToJohanhus, talkToFred, talkToSeth, talkToHorvik, - talkToApoth, talkToTassie, goDownToHammerspike, talkToHammerspike, goUpToSanfew, talkToSanfew, makeGuthixRest, talkToBleemadge, talkToArhein, talkToPhantuwti, enterGoblinCave, - searchWall, talkToCromperty, talkToTindel, talkToRantz, talkToGnormadium, talkToBleemadgeNoTea, take1, take2, take3, take4, take5, take6, take7, take8, - cutSaph, cutJade, cutTopaz, cutOpal, put1, put2, put3, put4, put5, put6, put7, put8, talkToGnormadiumAgain, returnToRantz, returnToTindel, returnToCromperty, getPigeonCages, - enterGoblinCaveAgain, standNextToSculpture, readScroll, killSlagilith, readScrollAgain, talkToPetra, returnToPhantuwti, goUpLadder, goUpToRoof, searchVane, useHammerOnVane, - goDownFromRoof, goDownLadderToSeers, useVane123OnAnvil, useVane2OnAnvil, useVane3OnAnvil, goBackUpLadder, goBackUpToRoof, useVane1, useVane2, useVane3, - goFromRoofToPhantuwti, goDownLadderToPhantuwti, finishWithPhantuwti, returnToArhein, returnToBleemadge, returnToSanfew, goDownToHammerspikeAgain, returnToHammerspike, - killGangMembers, talkToHammerspikeFinal, returnToTassie, spinPotLid, pickUpPot, firePotLid, usePotLidOnPot, returnToApothecary, returnToHorvik, talkToHorvikFinal, returnToSeth, - returnDownToJohnahus, returnToJohnahus, returnToAggie, returnToBrian, returnToForester, returnToYanni, returnUpToSanfew, returnToPhantuwti2, useVane12OnAnvil, useVane13OnAnvil, - useVane23OnAnvil, useVane1OnAnvil, fixAllLamps, searchVaneAgain; - - DetailedQuestStep useBowlOnCup, useHerbsOnCup; - - //Zones - Zone sanfewRoom, hamBase, dwarvenMine, goblinCave, scrollSpot, seersVillageUpstairs, roof; - - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToYanni); - steps.put(5, talkToJungleForester); - - steps.put(10, talkToBrian); - steps.put(15, talkToBrian); - - steps.put(20, talkToAggie); - - ConditionalStep goTalkToJohanhus = new ConditionalStep(this, goDownToJohanhus); - goTalkToJohanhus.addStep(inHamBase, talkToJohanhus); - - steps.put(25, goTalkToJohanhus); - steps.put(30, goTalkToJohanhus); - steps.put(35, goTalkToJohanhus); - steps.put(40, goTalkToJohanhus); - - steps.put(45, talkToFred); - steps.put(50, talkToSeth); - steps.put(55, talkToHorvik); - steps.put(60, talkToApoth); - steps.put(62, talkToApoth); - steps.put(63, talkToApoth); - - steps.put(65, talkToTassie); - - ConditionalStep goTalkToHammerspike = new ConditionalStep(this, goDownToHammerspike); - goTalkToHammerspike.addStep(inDwarvenMine, talkToHammerspike); - steps.put(70, goTalkToHammerspike); - - ConditionalStep goTalkToSanfew = new ConditionalStep(this, goUpToSanfew); - goTalkToSanfew.addStep(inSanfewRoom, talkToSanfew); - - steps.put(75, goTalkToSanfew); - - ConditionalStep makeGuthixRestForGnome = new ConditionalStep(this, useBowlOnCup); - makeGuthixRestForGnome.addStep(guthixRest, talkToBleemadge); - makeGuthixRestForGnome.addStep(new Conditions(LogicType.OR, herbTeaMix, cupOfWater), useHerbsOnCup); - - steps.put(80, makeGuthixRestForGnome); - steps.put(81, makeGuthixRestForGnome); - steps.put(82, makeGuthixRestForGnome); - steps.put(83, makeGuthixRestForGnome); - steps.put(84, makeGuthixRestForGnome); - - steps.put(86, talkToBleemadgeNoTea); - - steps.put(88, talkToArhein); - - steps.put(90, talkToPhantuwti); - - ConditionalStep investigateWall = new ConditionalStep(this, enterGoblinCave); - investigateWall.addStep(inGoblinCave, searchWall); - - steps.put(95, investigateWall); - - steps.put(100, talkToCromperty); - - steps.put(105, talkToTindel); - - steps.put(110, talkToRantz); - - steps.put(115, talkToGnormadium); - - ConditionalStep repairLights = new ConditionalStep(this, take1); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty, sapphire), put8); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty), cutSaph); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full), take8); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty, opal), put7); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty), cutOpal); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full), take7); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty, redTopaz), - put6); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty), cutTopaz); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full), take6); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty, jade), put5); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty), cutJade); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full), take5); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Empty, sapphire), put4); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Empty), cutSaph); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full), take4); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Empty, opal), put3); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Empty), cutOpal); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full), take3); - repairLights.addStep(new Conditions(lamp1Full, lamp2Empty, redTopaz), put2); - repairLights.addStep(new Conditions(lamp1Full, lamp2Empty), cutTopaz); - repairLights.addStep(lamp1Full, take2); - repairLights.addStep(new Conditions(lamp1Empty, jade), put1); - repairLights.addStep(lamp1Empty, cutJade); - - steps.put(120, repairLights); - - steps.put(125, talkToGnormadiumAgain); - - steps.put(130, returnToRantz); - - steps.put(135, returnToTindel); - - steps.put(140, returnToCromperty); - - ConditionalStep fightSlagilith = new ConditionalStep(this, getPigeonCages); - fightSlagilith.addStep(slagilithNearby, killSlagilith); - fightSlagilith.addStep(inScrollSpot, readScroll); - fightSlagilith.addStep(inGoblinCave, standNextToSculpture); - fightSlagilith.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); - - steps.put(145, fightSlagilith); - steps.put(150, fightSlagilith); - - ConditionalStep freePetra = new ConditionalStep(this, getPigeonCages); - freePetra.addStep(petraNearby, talkToPetra); - freePetra.addStep(inScrollSpot, readScroll); - freePetra.addStep(inGoblinCave, standNextToSculpture); - freePetra.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); + // Required items + ItemRequirement steelBars4; + ItemRequirement bronzeBar; + ItemRequirement ironBar; + ItemRequirement chisel; + ItemRequirement guam2; + ItemRequirement marrentill; + ItemRequirement harralander; + ItemRequirement hammer; + ItemRequirement emptyCup; + ItemRequirement pot; + ItemRequirement hotWaterBowl; + + // Recommended items + ItemRequirement draynorVillageTeleports; + ItemRequirement lumbridgeTeleports; + ItemRequirement varrockTeleports; + ItemRequirement taverleyOrFaladorTeleports; + ItemRequirement camelotTeleports; + ItemRequirement fishingGuildAndDwarvenMineTeleports; + ItemRequirement ardougneTeleports; + ItemRequirement khazardTeleports; + ItemRequirement feldipHillsTeleports; + ItemRequirement pickaxe; + ItemRequirement opal2; + ItemRequirement jade2; + ItemRequirement redTopaz2; + ItemRequirement coins3000; + ItemRequirement combatGear; + + // Mid-quest item requirements + ItemRequirement opal; + ItemRequirement jade; + ItemRequirement redTopaz; + ItemRequirement sapphire; + ItemRequirement softClay; + ItemRequirement bluntAxe; + ItemRequirement herbalTincture; + ItemRequirement guthixRest; + ItemRequirement uncutSapphire; + ItemRequirement cupOfWater; + ItemRequirement uncutOpal; + ItemRequirement uncutJade; + ItemRequirement uncutRedTopaz; + ItemRequirement stodgyMattress; + ItemRequirement mattress; + ItemRequirement animateRockScroll; + ItemRequirement animateRockScrollHighlight; + ItemRequirement ironOxide; + ItemRequirement brokenVane1; + ItemRequirement brokenVane2; + ItemRequirement brokenVane3; + ItemRequirement ornament; + ItemRequirement weathervanePillar; + ItemRequirement directionals; + ItemRequirement weatherReport; + ItemRequirement unfiredPotLid; + ItemRequirement potLid; + ItemRequirement potWithLid; + ItemRequirement breathingSalts; + ItemRequirement chickenCages5; + ItemRequirement sharpenedAxe; + ItemRequirement redMahog; + ItemRequirement steelBars3; + ItemRequirement steelBar; + ItemRequirement guam; + ItemRequirement hammerHighlight; + ItemRequirement pigeonCages5; + ItemRequirement guamTea; + ItemRequirement guam2Tea; + ItemRequirement harrTea; + ItemRequirement marrTea; + ItemRequirement guamMarrTea; + ItemRequirement guamHarrTea; + ItemRequirement harrMarrTea; + ItemRequirement guam2MarrTea; + ItemRequirement guam2HarrTea; + ItemRequirement guamHarrMarrTea; + ItemRequirement herbTeaMix; + + // Zones + Zone sanfewRoom; + Zone hamBase; + Zone dwarvenMine; + Zone goblinCave; + Zone scrollSpot; + Zone seersVillageUpstairs; + Zone roof; + + // Miscellaneous requirements + ZoneRequirement inSanfewRoom; + ZoneRequirement inHamBase; + ZoneRequirement inDwarvenMine; + ZoneRequirement inGoblinCave; + VarbitRequirement lamp1Empty; + VarbitRequirement lamp1Full; + VarbitRequirement lamp2Empty; + VarbitRequirement lamp2Full; + VarbitRequirement lamp3Empty; + VarbitRequirement lamp3Full; + VarbitRequirement lamp4Empty; + VarbitRequirement lamp4Full; + VarbitRequirement lamp5Empty; + VarbitRequirement lamp5Full; + VarbitRequirement lamp6Empty; + VarbitRequirement lamp6Full; + VarbitRequirement lamp7Empty; + VarbitRequirement lamp7Full; + VarbitRequirement lamp8Empty; + VarbitRequirement lamp8Full; + VarbitRequirement allFull; + ZoneRequirement inScrollSpot; + NpcCondition slagilithNearby; + NpcCondition petraNearby; + ZoneRequirement inSeersVillageUpstairs; + ZoneRequirement onRoof; + VarbitRequirement addedOrnaments; + VarbitRequirement addedDirectionals; + VarbitRequirement addedWeathervanePillar; + Conditions hasOrUsedOrnament; + Conditions hasOrUsedDirectionals; + Conditions hasOrUsedWeathervanePillar; + FreeInventorySlotRequirement freeSlots3; + + // Steps + NpcStep talkToYanni; + + NpcStep talkToJungleForester; + + NpcStep talkToBrian; + + NpcStep talkToAggie; + + ObjectStep goDownToJohanhus; + NpcStep talkToJohanhus; + + NpcStep talkToFred; + + NpcStep talkToSeth; + + NpcStep talkToHorvik; + + NpcStep talkToApoth; + + NpcStep talkToTassie; + + ObjectStep goDownToHammerspike; + NpcStep talkToHammerspike; + + ObjectStep goUpToSanfew; + NpcStep talkToSanfew; + + DetailedQuestStep useBowlOnCup; + DetailedQuestStep useHerbsOnCup; + DetailedQuestStep makeGuthixRest; + NpcStep talkToBleemadge; + + NpcStep talkToBleemadgeNoTea; + + NpcStep talkToArhein; + + NpcStep talkToPhantuwti; + + ObjectStep enterGoblinCave; + ObjectStep searchWall; + + NpcStep talkToCromperty; + + NpcStep talkToTindel; + + NpcStep talkToRantz; + + NpcStep talkToGnormadium; - steps.put(152, freePetra); - steps.put(155, freePetra); + ObjectStep take1; + ObjectStep take2; + ObjectStep take3; + ObjectStep take4; + ObjectStep take5; + ObjectStep take6; + ObjectStep take7; + ObjectStep take8; + DetailedQuestStep cutSaph; + DetailedQuestStep cutJade; + DetailedQuestStep cutTopaz; + DetailedQuestStep cutOpal; + ObjectStep put1; + ObjectStep put2; + ObjectStep put3; + ObjectStep put4; + ObjectStep put5; + ObjectStep put6; + ObjectStep put7; + ObjectStep put8; + DetailedQuestStep fixAllLamps; - steps.put(160, returnToPhantuwti); - steps.put(165, returnToPhantuwti2); - steps.put(170, returnToPhantuwti2); + NpcStep talkToGnormadiumAgain; - ConditionalStep repairVane = new ConditionalStep(this, goUpLadder); - repairVane.addStep(onRoof, searchVane); - repairVane.addStep(inSeersVillageUpstairs, goUpToRoof); - - steps.put(175, repairVane); + NpcStep returnToRantz; - ConditionalStep hitVane = new ConditionalStep(this, goUpLadder); - hitVane.addStep(onRoof, useHammerOnVane); - hitVane.addStep(inSeersVillageUpstairs, goUpToRoof); + NpcStep returnToTindel; - steps.put(176, hitVane); + NpcStep returnToCromperty; - ConditionalStep getVaneBits = new ConditionalStep(this, goUpLadder); - getVaneBits.addStep(onRoof, searchVaneAgain); - getVaneBits.addStep(inSeersVillageUpstairs, goUpToRoof); + DetailedQuestStep getPigeonCages; + ObjectStep enterGoblinCaveAgain; + DetailedQuestStep standNextToSculpture; + DetailedQuestStep readScroll; + NpcStep killSlagilith; - steps.put(177, getVaneBits); + DetailedQuestStep readScrollAgain; + NpcStep talkToPetra; - ConditionalStep repairVaneParts = new ConditionalStep(this, useVane123OnAnvil); + NpcStep returnToPhantuwti; - repairVaneParts.addStep(new Conditions(addedOrnaments, addedDirectionals, weathervanePillar, onRoof), useVane3); - repairVaneParts.addStep(new Conditions(addedOrnaments, directionals, onRoof), useVane2); - repairVaneParts.addStep(new Conditions(ornament, onRoof), useVane1); - repairVaneParts.addStep(onRoof, goDownFromRoof); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar, inSeersVillageUpstairs), goBackUpToRoof); - repairVaneParts.addStep(inSeersVillageUpstairs, goDownLadderToSeers); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar), goBackUpLadder); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedOrnament), useVane3OnAnvil); - repairVaneParts.addStep(new Conditions(hasOrUsedOrnament, hasOrUsedWeathervanePillar), useVane1OnAnvil); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedWeathervanePillar), useVane2OnAnvil); - repairVaneParts.addStep(hasOrUsedOrnament, useVane13OnAnvil); - repairVaneParts.addStep(hasOrUsedWeathervanePillar, useVane12OnAnvil); - repairVaneParts.addStep(hasOrUsedDirectionals, useVane23OnAnvil); + NpcStep returnToPhantuwti2; - steps.put(180, repairVaneParts); + ObjectStep goUpLadder; + ObjectStep goUpToRoof; + ObjectStep searchVane; - ConditionalStep reportBackToPhantuwti = new ConditionalStep(this, finishWithPhantuwti); - reportBackToPhantuwti.addStep(inSeersVillageUpstairs, goDownLadderToPhantuwti); - reportBackToPhantuwti.addStep(onRoof, goFromRoofToPhantuwti); + ObjectStep useHammerOnVane; - steps.put(185, reportBackToPhantuwti); + ObjectStep searchVaneAgain; - steps.put(190, returnToArhein); + ObjectStep goDownFromRoof; + ObjectStep goDownLadderToSeers; + ObjectStep useVane123OnAnvil; + ObjectStep useVane12OnAnvil; + ObjectStep useVane13OnAnvil; + ObjectStep useVane23OnAnvil; + ObjectStep useVane1OnAnvil; + ObjectStep useVane2OnAnvil; + ObjectStep useVane3OnAnvil; - steps.put(195, returnToBleemadge); + ObjectStep goBackUpLadder; + ObjectStep goBackUpToRoof; + ObjectStep useVane1; + ObjectStep useVane2; + ObjectStep useVane3; - ConditionalStep goAndReturnToSanfew = new ConditionalStep(this, returnUpToSanfew); - goAndReturnToSanfew.addStep(inSanfewRoom, returnToSanfew); - steps.put(200, goAndReturnToSanfew); + ObjectStep goFromRoofToPhantuwti; + ObjectStep goDownLadderToPhantuwti; + NpcStep finishWithPhantuwti; - ConditionalStep dealWithHammerspike = new ConditionalStep(this, goDownToHammerspikeAgain); - dealWithHammerspike.addStep(inDwarvenMine, returnToHammerspike); + NpcStep returnToArhein; - steps.put(205, dealWithHammerspike); + NpcStep returnToBleemadge; - ConditionalStep sortOutGangMembers = new ConditionalStep(this, goDownToHammerspikeAgain); - sortOutGangMembers.addStep(inDwarvenMine, killGangMembers); + ObjectStep returnUpToSanfew; + NpcStep returnToSanfew; - steps.put(210, sortOutGangMembers); - steps.put(215, sortOutGangMembers); - steps.put(220, sortOutGangMembers); - steps.put(225, dealWithHammerspike); + ObjectStep goDownToHammerspikeAgain; + NpcStep returnToHammerspike; - steps.put(230, returnToTassie); + NpcStep killGangMembers; - ConditionalStep makePotAndReturnToApoth = new ConditionalStep(this, spinPotLid); - makePotAndReturnToApoth.addStep(potWithLid, returnToApothecary); - makePotAndReturnToApoth.addStep(new Conditions(potLid, pot), usePotLidOnPot); - makePotAndReturnToApoth.addStep(potLid, pickUpPot); - makePotAndReturnToApoth.addStep(unfiredPotLid, firePotLid); + NpcStep talkToHammerspikeFinal; - steps.put(235, makePotAndReturnToApoth); + NpcStep returnToTassie; - steps.put(240, returnToHorvik); + ObjectStep spinPotLid; + ItemStep pickUpPot; + ObjectStep firePotLid; + DetailedQuestStep usePotLidOnPot; + NpcStep returnToApothecary; - steps.put(245, talkToHorvikFinal); + NpcStep returnToHorvik; - steps.put(250, returnToSeth); + NpcStep talkToHorvikFinal; - ConditionalStep goFinishWithJohanhus = new ConditionalStep(this, returnDownToJohnahus); - goFinishWithJohanhus.addStep(inHamBase, returnToJohnahus); + NpcStep returnToSeth; - steps.put(255, goFinishWithJohanhus); + ObjectStep returnDownToJohnahus; + NpcStep returnToJohnahus; - steps.put(260, returnToAggie); + NpcStep returnToAggie; - steps.put(265, returnToBrian); + NpcStep returnToBrian; - steps.put(270, returnToForester); + NpcStep returnToForester; - steps.put(275, returnToYanni); + NpcStep returnToYanni; - return steps; + @Override + protected void setupZones() + { + sanfewRoom = new Zone(new WorldPoint(2893, 3423, 1), new WorldPoint(2903, 3433, 1)); + hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); + dwarvenMine = new Zone(new WorldPoint(2960, 9696, 0), new WorldPoint(3062, 9854, 0)); + goblinCave = new Zone(new WorldPoint(2560, 9792, 0), new WorldPoint(2623, 9855, 0)); + scrollSpot = new Zone(new WorldPoint(2616, 9835, 0), new WorldPoint(2619, 9835, 0)); + seersVillageUpstairs = new Zone(new WorldPoint(2698, 3468, 1), new WorldPoint(2717, 3476, 1)); + roof = new Zone(new WorldPoint(2695, 3469, 3), new WorldPoint(2716, 3476, 3)); } @Override @@ -353,6 +407,18 @@ protected void setupRequirements() pickaxe = new ItemRequirement("Any pickaxe to kill Slagilith", ItemCollections.PICKAXES).isNotConsumed(); + combatGear = new ItemRequirement("Combat gear to fight Slagilith and the dwarf gang members", -1, -1); + combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); + + opal2 = new ItemRequirement("Opal", ItemID.OPAL, 2); + opal2.setHighlightInInventory(true); + jade2 = new ItemRequirement("Jade", ItemID.JADE, 2); + jade2.setHighlightInInventory(true); + redTopaz2 = new ItemRequirement("Red topaz", ItemID.RED_TOPAZ, 2); + redTopaz2.setHighlightInInventory(true); + coins3000 = new ItemRequirement("Coins", ItemID.COINS, 3000); + coins3000.setTooltip("Alternatively for purchasing backup gems from Gnormadium Avlafrim"); + bluntAxe = new ItemRequirement("Blunt axe", ItemID.FAVOUR_JUNGLEFORESTERAXE_BLUNT); bluntAxe.setTooltip("You can get another from a Jungle Forester south of Shilo Village"); herbalTincture = new ItemRequirement("Herbal tincture", ItemID.FAVOUR_HERBAL_TINCTURE); @@ -360,9 +426,9 @@ protected void setupRequirements() harrTea = new ItemRequirement("Herb tea mix (harralander)", ItemID.FAVOUR_CUP_HARRALANDER); guamTea = new ItemRequirement("Herb tea mix (guam)", ItemID.FAVOUR_CUP_GUAM); - marrTea = new ItemRequirement("Herb tea mix (marrentill)", ItemID.FAVOUR_CUP_MARRENTILL); + marrTea = new ItemRequirement("Herb tea mix (marrentill)", ItemID.FAVOUR_CUP_MARRENTILL); harrMarrTea = new ItemRequirement("Herb tea mix (harr/marr)", ItemID.FAVOUR_CUP_HARRALANDER_MARRENTILL); - guamHarrTea = new ItemRequirement("Herb tea mix (harr/guam)", ItemID.FAVOUR_CUP_HARRALANDER_GUAM); + guamHarrTea = new ItemRequirement("Herb tea mix (harr/guam)", ItemID.FAVOUR_CUP_HARRALANDER_GUAM); guam2Tea = new ItemRequirement("Herb tea mix (2 guam)", ItemID.FAVOUR_CUP_GUAM_GUAM); guamMarrTea = new ItemRequirement("Herb tea mix (marr/guam)", ItemID.FAVOUR_CUP_GUAM_MARRENTILL); guamHarrMarrTea = new ItemRequirement("Herb tea mix (harr/marr/guam)", ItemID.FAVOUR_CUP_HARRALANDER_MARRENTILL_GUAM); @@ -377,12 +443,9 @@ protected void setupRequirements() sapphire = new ItemRequirement("Sapphire", ItemID.SAPPHIRE); sapphire.setHighlightInInventory(true); - opal = new ItemRequirement("Opal", ItemID.OPAL); - opal.setHighlightInInventory(true); - jade = new ItemRequirement("Jade", ItemID.JADE); - jade.setHighlightInInventory(true); - redTopaz = new ItemRequirement("Red topaz", ItemID.RED_TOPAZ); - redTopaz.setHighlightInInventory(true); + opal = opal2.quantity(1); + jade = jade2.quantity(1); + redTopaz = redTopaz2.quantity(1); uncutSapphire = new ItemRequirement("Uncut sapphire", ItemID.UNCUT_SAPPHIRE); uncutSapphire.setHighlightInInventory(true); @@ -440,29 +503,14 @@ protected void setupRequirements() breathingSalts.setTooltip("You can get more by bringing the Apothecary another airtight pot and 200 gp"); chickenCages5 = new ItemRequirement("Chicken cage", ItemID.FAVOUR_CHICKEN_CAGE, 5); - chickenCages5.setTooltip("You can get more chicken cages by bringing Horvik a pidgeon cage and 100 coins per cage"); + chickenCages5.setTooltip("You can get more chicken cages by bringing Horvik a pigeon cage and 100 coins per cage"); sharpenedAxe = new ItemRequirement("Sharpened axe", ItemID.FAVOUR_JUNGLEFORESTERAXE_SHARP); sharpenedAxe.setTooltip("You can get another from Brian in Port Sarim"); redMahog = new ItemRequirement("Red mahogany log", ItemID.FAVOUR_MAHOGANY_LOG); redMahog.setTooltip("You can get another from a jungle forester for 200 gp"); - } - - @Override - protected void setupZones() - { - sanfewRoom = new Zone(new WorldPoint(2893, 3423, 1), new WorldPoint(2903, 3433, 1)); - hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); - dwarvenMine = new Zone(new WorldPoint(2960, 9696, 0), new WorldPoint(3062, 9854, 0)); - goblinCave = new Zone(new WorldPoint(2560, 9792, 0), new WorldPoint(2623, 9855, 0)); - scrollSpot = new Zone(new WorldPoint(2616, 9835, 0), new WorldPoint(2619, 9835, 0)); - seersVillageUpstairs = new Zone(new WorldPoint(2698, 3468, 1), new WorldPoint(2717, 3476, 1)); - roof = new Zone(new WorldPoint(2695, 3469, 3), new WorldPoint(2716, 3476, 3)); - } - public void setupConditions() - { inSanfewRoom = new ZoneRequirement(sanfewRoom); inHamBase = new ZoneRequirement(hamBase); inDwarvenMine = new ZoneRequirement(dwarvenMine); @@ -477,8 +525,6 @@ public void setupConditions() lamp7Empty = new VarbitRequirement(VarbitID.OPALLIGHT2_TAKEN, 1); lamp8Empty = new VarbitRequirement(VarbitID.SAPPHIRELIGHT2_TAKEN, 1); - allEmpty = new VarbitRequirement(VarbitID.CHECKLANDINGLIGHTS, 255); - lamp1Full = new VarbitRequirement(VarbitID.JADELIGHT1_FIXED, 1); lamp2Full = new VarbitRequirement(VarbitID.TOPAZLIGHT1_FIXED, 1); lamp3Full = new VarbitRequirement(VarbitID.OPALLIGHT1_FIXED, 1); @@ -501,19 +547,23 @@ public void setupConditions() addedDirectionals = new VarbitRequirement(VarbitID.DIRECTIONALSFIXED, 1); addedWeathervanePillar = new VarbitRequirement(VarbitID.ROTATINGPILLARFIXED, 1); - hasOrUsedDirectionals = new Conditions(LogicType.OR, addedDirectionals, directionals.alsoCheckBank()); - hasOrUsedOrnament = new Conditions(LogicType.OR, addedOrnaments, ornament.alsoCheckBank()); - hasOrUsedWeathervanePillar = new Conditions(LogicType.OR, addedWeathervanePillar, weathervanePillar.alsoCheckBank()); + hasOrUsedDirectionals = or(addedDirectionals, directionals.alsoCheckBank()); + hasOrUsedOrnament = or(addedOrnaments, ornament.alsoCheckBank()); + hasOrUsedWeathervanePillar = or(addedWeathervanePillar, weathervanePillar.alsoCheckBank()); + + freeSlots3 = new FreeInventorySlotRequirement(3); } - public void setupSteps() + void setupSteps() { talkToYanni = new NpcStep(this, NpcID.SHILOANTIQUES, new WorldPoint(2836, 2983, 0), "Talk to Yanni Salika in Shilo Village. CKR fairy ring or take cart from Brimhaven."); + talkToYanni.addDialogStep("Is there anything else interesting to do around here?"); talkToYanni.addDialogStep("Yes."); - talkToYanni.addDialogSteps("Is there anything else interesting to do around here?", "Ok, see you in a tick!"); + talkToJungleForester = new NpcStep(this, new int[]{NpcID.JUNGLEFORESTER_F, NpcID.JUNGLEFORESTER_M}, new WorldPoint(2861, 2942, 0), "Talk to a Jungle Forester south of Shilo Village.", true); - talkToJungleForester.addDialogSteps("I'll get going then!", "I need to talk to you about red mahogany."); + talkToJungleForester.addDialogStep("I need to talk to you about red mahogany."); talkToJungleForester.addDialogStep("Okay, I'll take your axe to get it sharpened."); + talkToBrian = new NpcStep(this, NpcID.BRIAN, new WorldPoint(3027, 3249, 0), "Talk to Brian in the Port Sarim axe shop.", bluntAxe); talkToBrian.addDialogStep("Do you sharpen axes?"); talkToBrian.addDialogStepWithExclusion("Look, can you sharpen this cursed axe or what?", "Ok, ok, I'll do it! I'll go and see Aggie."); @@ -561,32 +611,24 @@ public void setupSteps() talkToSanfew.addDialogSteps("A dwarf I know wants to become an initiate.", "Yep, it's a deal."); talkToSanfew.addSubSteps(goUpToSanfew); - useBowlOnCup = new DetailedQuestStep(this, "Use a bowl of hot water on an empty cup.", - hotWaterBowl.highlighted(), emptyCup.highlighted()); - useHerbsOnCup = new DetailedQuestStep(this, - "Use 2 guams, a marrentill and a harralander on the cup.", - guam2.hideConditioned(new Conditions(LogicType.OR, guamTea, guam2Tea, guamMarrTea, guamHarrTea, - guamHarrMarrTea)).highlighted(), - guam.hideConditioned(new Conditions(LogicType.OR, cupOfWater, marrTea, harrTea, guam2Tea, guam2MarrTea, - guam2HarrTea)).highlighted(), - marrentill.hideConditioned(new Conditions(LogicType.OR, marrTea, harrMarrTea, guamMarrTea, guam2MarrTea, - guamHarrMarrTea)).highlighted(), - harralander.hideConditioned(new Conditions(LogicType.OR, harrTea, harrMarrTea, guamHarrTea, guam2HarrTea, - guamHarrMarrTea)).highlighted(), - cupOfWater.hideConditioned(new Conditions(LogicType.OR, guamTea, harrTea, marrTea, harrMarrTea, guamHarrTea, - guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted(), - herbTeaMix.hideConditioned(new Conditions(LogicType.NOR, guamTea, harrTea, marrTea, harrMarrTea, - guamHarrTea, guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted()); + useBowlOnCup = new DetailedQuestStep(this, "Use a bowl of hot water on an empty cup.", hotWaterBowl.highlighted(), emptyCup.highlighted()); + useHerbsOnCup = new DetailedQuestStep(this, "Use 2 guams, a marrentill and a harralander on the cup.", + guam2.hideConditioned(or(guamTea, guam2Tea, guamMarrTea, guamHarrTea, guamHarrMarrTea)).highlighted(), + guam.hideConditioned(or(cupOfWater, marrTea, harrTea, guam2Tea, guam2MarrTea, guam2HarrTea)).highlighted(), + marrentill.hideConditioned(or(marrTea, harrMarrTea, guamMarrTea, guam2MarrTea, guamHarrMarrTea)).highlighted(), + harralander.hideConditioned(or(harrTea, harrMarrTea, guamHarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted(), + cupOfWater.hideConditioned(or(guamTea, harrTea, marrTea, harrMarrTea, guamHarrTea, guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted(), + herbTeaMix.hideConditioned(nor(guamTea, harrTea, marrTea, harrMarrTea, guamHarrTea, guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted()); makeGuthixRest = new DetailedQuestStep(this, "Make Guthix Rest by using a bowl of hot water on an empty tea cup, then using 2 guams, a marrentill and a harralander on it.", emptyCup, hotWaterBowl, guam2, marrentill, harralander); makeGuthixRest.addSubSteps(useBowlOnCup, useHerbsOnCup); talkToBleemadge = new NpcStep(this, NpcID.PILOT_WHITE_WOLF_BASE, new WorldPoint(2847, 3498, 0), "Right-click talk to Captain Bleemadge on White Wolf Mountain.", guthixRest); - ((NpcStep) talkToBleemadge).addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, + talkToBleemadge.addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, NpcID.PILOT_WHITE_WOLF_AL_KHARID, NpcID.PILOT_WHITE_WOLF_VARROCK, NpcID.PILOT_WHITE_WOLF_OGRE, NpcID.PILOT_WHITE_WOLF_APE); talkToBleemadge.addDialogStep("I have a special tea here for you from Sanfew!"); talkToBleemadgeNoTea = new NpcStep(this, NpcID.PILOT_WHITE_WOLF_BASE, new WorldPoint(2847, 3498, 0), "Right-click talk to Captain Bleemadge on White Wolf Mountain."); - ((NpcStep) talkToBleemadgeNoTea).addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, + talkToBleemadgeNoTea.addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, NpcID.PILOT_WHITE_WOLF_AL_KHARID, NpcID.PILOT_WHITE_WOLF_VARROCK, NpcID.PILOT_WHITE_WOLF_OGRE, NpcID.PILOT_WHITE_WOLF_APE); talkToBleemadgeNoTea.addDialogStep("How was that tea?"); @@ -607,7 +649,7 @@ public void setupSteps() searchWall = new ObjectStep(this, ObjectID.FAVOUR_LADY_IN_WALL, new WorldPoint(2621, 9835, 0), "Right-click search the sculpture in the wall in the north east corner of the cave."); talkToCromperty = new NpcStep(this, NpcID.CROMPERTY_PRE_DIARY, new WorldPoint(2684, 3323, 0), "Talk to Wizard Cromperty in north east Ardougne."); - ((NpcStep) talkToCromperty).addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); + talkToCromperty.addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); talkToCromperty.addDialogStep("Chat."); talkToCromperty.addDialogStep("I need to talk to you about a girl stuck in some rock!"); talkToCromperty.addDialogStep("Oh! Ok, one more 'small favour' isn't going to kill me...I hope!"); @@ -668,7 +710,7 @@ public void setupSteps() returnToTindel.addDialogStep("I have the mattress."); returnToCromperty = new NpcStep(this, NpcID.CROMPERTY_PRE_DIARY, new WorldPoint(2684, 3323, 0), "Return to Wizard Cromperty in north east Ardougne.", ironOxide); - ((NpcStep) returnToCromperty).addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); + returnToCromperty.addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); returnToCromperty.addDialogStep("Chat."); returnToCromperty.addDialogStep("I have that iron oxide you asked for!"); @@ -676,14 +718,14 @@ public void setupSteps() enterGoblinCaveAgain = new ObjectStep(this, ObjectID.MCANNONCAVE, new WorldPoint(2624, 3393, 0), "Enter the cave south east of the Fishing Guild. " + "Be prepared to fight the Slagilith(level 92, takes reduced damage from anything other than pickaxes).", Arrays.asList(pigeonCages5, animateRockScroll), Collections.singletonList(pickaxe)); - standNextToSculpture = new DetailedQuestStep(this, new WorldPoint(2616, 9835, 0), "Use the animate rock scroll next to the sculpture in the north east cavern.", animateRockScroll); + standNextToSculpture = new TileStep(this, new WorldPoint(2616, 9835, 0), "Use the animate rock scroll next to the sculpture in the north east cavern.", animateRockScroll); readScroll = new DetailedQuestStep(this, "Read the animate rock scroll.", animateRockScrollHighlight); standNextToSculpture.addSubSteps(readScroll); killSlagilith = new NpcStep(this, NpcID.SLAGILITH, new WorldPoint(2617, 9837, 0), "Kill the Slagilith. They take reduced damage from anything other than a pickaxe."); killSlagilith.addRecommended(pickaxe); - readScrollAgain = new DetailedQuestStep(this, "Read the animate rock scroll.", animateRockScrollHighlight); + readScrollAgain = new DetailedQuestStep(this, "Read the animate rock scroll again.", animateRockScrollHighlight); talkToPetra = new NpcStep(this, NpcID.FAVOUR_PETRA, new WorldPoint(2617, 9837, 0), "Talk to Petra Fiyed."); returnToPhantuwti = new NpcStep(this, NpcID.FAVOUR_PHANTUWTI_FARSIGHT, new WorldPoint(2702, 3473, 0), "Return to Phantuwti in the south west house of Seers' Village."); @@ -705,9 +747,11 @@ public void setupSteps() searchVane.addSubSteps(goUpLadder, goUpToRoof); useHammerOnVane = new ObjectStep(this, ObjectID.OSF_WEATHERVANE, new WorldPoint(2702, 3476, 3), "Use a hammer on the weathervane.", hammerHighlight); useHammerOnVane.addIcon(ItemID.HAMMER); - searchVaneAgain = new ObjectStep(this, ObjectID.OSF_WEATHERVANE, new WorldPoint(2702, 3476, 3), "Right-click search the weathervane on top of the Seers' building again."); + + searchVaneAgain = new ObjectStep(this, ObjectID.OSF_WEATHERVANE, new WorldPoint(2702, 3476, 3), "Right-click search the weathervane on top of the Seers' building again.", freeSlots3); goDownFromRoof = new ObjectStep(this, ObjectID.FAVOUR_ROOF_TRAPDOOR, new WorldPoint(2715, 3472, 3), "Climb down from the roof."); + goDownFromRoof.addDialogStep("Yes."); goDownLadderToSeers = new ObjectStep(this, ObjectID.KR_LADDERTOP, new WorldPoint(2715, 3470, 1), "Repair the vane parts on the anvil in north Seers' Village."); useVane123OnAnvil = new ObjectStep(this, ObjectID.ANVIL, new WorldPoint(2712, 3495, 0), "Repair the vane parts on an anvil. You can find one in the north of Seers' Village.", brokenVane1, brokenVane2, brokenVane3, hammer, steelBar, ironBar, bronzeBar); useVane12OnAnvil = new ObjectStep(this, ObjectID.ANVIL, new WorldPoint(2712, 3495, 0), "Repair the vane parts on an anvil. You can find one in the north of Seers' Village.", brokenVane1, brokenVane2, hammer, steelBar, bronzeBar); @@ -726,6 +770,7 @@ public void setupSteps() goBackUpLadder.addSubSteps(goBackUpToRoof, useVane1, useVane2, useVane3); goFromRoofToPhantuwti = new ObjectStep(this, ObjectID.FAVOUR_ROOF_TRAPDOOR, new WorldPoint(2715, 3472, 3), "Return to Phantuwti."); + goFromRoofToPhantuwti.addDialogStep("Yes."); goDownLadderToPhantuwti = new ObjectStep(this, ObjectID.KR_LADDERTOP_DIRECTIONAL, new WorldPoint(2699, 3476, 1), "Return to Phantuwti."); finishWithPhantuwti = new NpcStep(this, NpcID.FAVOUR_PHANTUWTI_FARSIGHT, new WorldPoint(2702, 3473, 0), "Return to Phantuwti in the south west house of Seers' Village."); finishWithPhantuwti.addSubSteps(goFromRoofToPhantuwti, goDownLadderToPhantuwti); @@ -737,28 +782,29 @@ public void setupSteps() returnToBleemadge = new NpcStep(this, NpcID.PILOT_WHITE_WOLF_BASE, new WorldPoint(2847, 3498, 0), "Right-click talk to Captain Bleemadge on White Wolf Mountain."); returnToBleemadge.addDialogStep("Hey there, did you get your T.R.A.S.H?"); - ((NpcStep) returnToBleemadge).addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, + returnToBleemadge.addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, NpcID.PILOT_WHITE_WOLF_AL_KHARID, NpcID.PILOT_WHITE_WOLF_VARROCK, NpcID.PILOT_WHITE_WOLF_OGRE, NpcID.PILOT_WHITE_WOLF_APE); returnUpToSanfew = new ObjectStep(this, ObjectID.SPIRALSTAIRS, new WorldPoint(2899, 3429, 0), "Return to Sanfew upstairs in the Taverley herblore store."); returnToSanfew = new NpcStep(this, NpcID.SANFEW, new WorldPoint(2899, 3429, 1), "Return to Sanfew upstairs in the Taverley herblore store."); returnToSanfew.addDialogStep("Hi there, the Gnome Pilot has agreed to take you to see the ogres!"); + returnToSanfew.addSubSteps(returnUpToSanfew); goDownToHammerspikeAgain = new ObjectStep(this, ObjectID.FAI_DWARF_TRAPDOOR_DOWN, new WorldPoint(3019, 3450, 0), "Return to the Dwarven Mine and talk to Hammerspike Stoutbeard in the west side."); returnToHammerspike = new NpcStep(this, NpcID.FAVOUR_HAMMERSPIKE_STOUTBEARD, new WorldPoint(2968, 9811, 0), "Return to Hammerspike Stoutbeard in the west cavern of the Dwarven Mine."); returnToHammerspike.addSubSteps(goDownToHammerspikeAgain); killGangMembers = new NpcStep(this, NpcID.FAVOUR_GANGSTER_DWARF, new WorldPoint(2968, 9811, 0), - "Kill 3 dwarf gang members until Hammerspike gives in. One dwarf gang member should appear after each kill.", true); - ((NpcStep) killGangMembers).addAlternateNpcs(NpcID.FAVOUR_GANGSTER_DWARF_2, NpcID.FAVOUR_GANGSTER_DWARF_3); - talkToHammerspikeFinal = new NpcStep(this, NpcID.FAVOUR_HAMMERSPIKE_STOUTBEARD, new WorldPoint(2968, 9811, 0), "Return to Hammerspike Stoutbeard in the west cavern of the Dwarven Mine."); + "Kill 3 dwarf gang members until Hammerspike gives in. One dwarf gang member should appear after each kill.", true); + killGangMembers.addAlternateNpcs(NpcID.FAVOUR_GANGSTER_DWARF_2, NpcID.FAVOUR_GANGSTER_DWARF_3); + talkToHammerspikeFinal = new NpcStep(this, NpcID.FAVOUR_HAMMERSPIKE_STOUTBEARD, new WorldPoint(2968, 9811, 0), "Return to Hammerspike Stoutbeard in the west cavern of the Dwarven Mine after killing his dwarf gang members."); returnToTassie = new NpcStep(this, NpcID.FAVOUR_TASSIE_SLIPCAST, new WorldPoint(3085, 3409, 0), "Return to Tassie Slipcast in the Barbarian Village pottery building."); spinPotLid = new ObjectStep(this, ObjectID.POTTERYWHEEL, new WorldPoint(3087, 3409, 0), "Spin the clay into a pot lid.", softClay); - spinPotLid.addWidgetHighlightWithItemIdRequirement(270, 19, ItemID.POTLID_UNFIRED, true); + spinPotLid.addWidgetHighlight(WidgetHighlight.createMultiskillByItemId(ItemID.POTLID_UNFIRED)); pickUpPot = new ItemStep(this, "Get a pot to put your lid on. There's one in the Barbarian Village helmet shop.", pot); firePotLid = new ObjectStep(this, ObjectID.FAI_BARBARIAN_POTTERY_OVEN, new WorldPoint(3085, 3407, 0), "Fire the unfired pot lid.", unfiredPotLid); - firePotLid.addWidgetHighlightWithItemIdRequirement(270, 19, ItemID.POTLID, true); + firePotLid.addWidgetHighlight(WidgetHighlight.createMultiskillByItemId(ItemID.POTLID_UNFIRED)); usePotLidOnPot = new DetailedQuestStep(this, "Use the pot lid on a pot.", pot, potLid); returnToApothecary = new NpcStep(this, NpcID.APOTHECARY, new WorldPoint(3196, 3404, 0), "Return to the Apothecary in west Varrock.", potWithLid); returnToApothecary.addDialogStep("Talk about One Small Favour."); @@ -784,62 +830,293 @@ public void setupSteps() } @Override - public List getItemRequirements() + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + Map steps = new HashMap<>(); + + steps.put(0, talkToYanni); + steps.put(5, talkToJungleForester); + + steps.put(10, talkToBrian); + steps.put(15, talkToBrian); + + steps.put(20, talkToAggie); + + var goTalkToJohanhus = new ConditionalStep(this, goDownToJohanhus); + goTalkToJohanhus.addStep(inHamBase, talkToJohanhus); + + steps.put(25, goTalkToJohanhus); + steps.put(30, goTalkToJohanhus); + steps.put(35, goTalkToJohanhus); + steps.put(40, goTalkToJohanhus); + + steps.put(45, talkToFred); + steps.put(50, talkToSeth); + steps.put(55, talkToHorvik); + steps.put(60, talkToApoth); + steps.put(62, talkToApoth); + steps.put(63, talkToApoth); + + steps.put(65, talkToTassie); + + var goTalkToHammerspike = new ConditionalStep(this, goDownToHammerspike); + goTalkToHammerspike.addStep(inDwarvenMine, talkToHammerspike); + steps.put(70, goTalkToHammerspike); + + var goTalkToSanfew = new ConditionalStep(this, goUpToSanfew); + goTalkToSanfew.addStep(inSanfewRoom, talkToSanfew); + + steps.put(75, goTalkToSanfew); + + var makeGuthixRestForGnome = new ConditionalStep(this, useBowlOnCup); + makeGuthixRestForGnome.addStep(guthixRest, talkToBleemadge); + makeGuthixRestForGnome.addStep(or(herbTeaMix, cupOfWater), useHerbsOnCup); + + steps.put(80, makeGuthixRestForGnome); + steps.put(81, makeGuthixRestForGnome); + steps.put(82, makeGuthixRestForGnome); + steps.put(83, makeGuthixRestForGnome); + steps.put(84, makeGuthixRestForGnome); + + steps.put(86, talkToBleemadgeNoTea); + + steps.put(88, talkToArhein); + + steps.put(90, talkToPhantuwti); + + var investigateWall = new ConditionalStep(this, enterGoblinCave); + investigateWall.addStep(inGoblinCave, searchWall); + + steps.put(95, investigateWall); + + steps.put(100, talkToCromperty); + + steps.put(105, talkToTindel); + + steps.put(110, talkToRantz); + + steps.put(115, talkToGnormadium); + + var repairLights = new ConditionalStep(this, take1); + repairLights.addStep(allFull, talkToGnormadiumAgain); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty, sapphire), put8); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty), cutSaph); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full), take8); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty, opal), put7); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty), cutOpal); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full), take7); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty, redTopaz), put6); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty), cutTopaz); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full), take6); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty, jade), put5); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty), cutJade); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full), take5); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Empty, sapphire), put4); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Empty), cutSaph); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full), take4); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Empty, opal), put3); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Empty), cutOpal); + repairLights.addStep(and(lamp1Full, lamp2Full), take3); + repairLights.addStep(and(lamp1Full, lamp2Empty, redTopaz), put2); + repairLights.addStep(and(lamp1Full, lamp2Empty), cutTopaz); + repairLights.addStep(lamp1Full, take2); + repairLights.addStep(and(lamp1Empty, jade), put1); + repairLights.addStep(lamp1Empty, cutJade); + + steps.put(120, repairLights); + + steps.put(125, talkToGnormadiumAgain); + + steps.put(130, returnToRantz); + + steps.put(135, returnToTindel); + + steps.put(140, returnToCromperty); + + var fightSlagilith = new ConditionalStep(this, getPigeonCages); + fightSlagilith.addStep(slagilithNearby, killSlagilith); + fightSlagilith.addStep(inScrollSpot, readScroll); + fightSlagilith.addStep(inGoblinCave, standNextToSculpture); + fightSlagilith.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); + + steps.put(145, fightSlagilith); + steps.put(150, fightSlagilith); + + var freePetra = new ConditionalStep(this, getPigeonCages); + freePetra.addStep(petraNearby, talkToPetra); + freePetra.addStep(inScrollSpot, readScrollAgain); + freePetra.addStep(inGoblinCave, standNextToSculpture); + freePetra.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); + + steps.put(152, freePetra); + steps.put(155, freePetra); + + steps.put(160, returnToPhantuwti); + steps.put(165, returnToPhantuwti2); + steps.put(170, returnToPhantuwti2); + + var repairVane = new ConditionalStep(this, goUpLadder); + repairVane.addStep(onRoof, searchVane); + repairVane.addStep(inSeersVillageUpstairs, goUpToRoof); + + steps.put(175, repairVane); + + var hitVane = new ConditionalStep(this, goUpLadder); + hitVane.addStep(onRoof, useHammerOnVane); + hitVane.addStep(inSeersVillageUpstairs, goUpToRoof); + + steps.put(176, hitVane); + + var getVaneBits = new ConditionalStep(this, goUpLadder); + getVaneBits.addStep(onRoof, searchVaneAgain); + getVaneBits.addStep(inSeersVillageUpstairs, goUpToRoof); + + steps.put(177, getVaneBits); + + var repairVaneParts = new ConditionalStep(this, useVane123OnAnvil); + + repairVaneParts.addStep(and(addedOrnaments, addedDirectionals, weathervanePillar, onRoof), useVane3); + repairVaneParts.addStep(and(addedOrnaments, directionals, onRoof), useVane2); + repairVaneParts.addStep(and(ornament, onRoof), useVane1); + repairVaneParts.addStep(onRoof, goDownFromRoof); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar, inSeersVillageUpstairs), goBackUpToRoof); + repairVaneParts.addStep(inSeersVillageUpstairs, goDownLadderToSeers); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar), goBackUpLadder); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedOrnament), useVane3OnAnvil); + repairVaneParts.addStep(and(hasOrUsedOrnament, hasOrUsedWeathervanePillar), useVane1OnAnvil); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedWeathervanePillar), useVane2OnAnvil); + repairVaneParts.addStep(hasOrUsedOrnament, useVane13OnAnvil); + repairVaneParts.addStep(hasOrUsedWeathervanePillar, useVane12OnAnvil); + repairVaneParts.addStep(hasOrUsedDirectionals, useVane23OnAnvil); + + steps.put(180, repairVaneParts); + + var reportBackToPhantuwti = new ConditionalStep(this, finishWithPhantuwti); + reportBackToPhantuwti.addStep(inSeersVillageUpstairs, goDownLadderToPhantuwti); + reportBackToPhantuwti.addStep(onRoof, goFromRoofToPhantuwti); + + steps.put(185, reportBackToPhantuwti); + + steps.put(190, returnToArhein); + + steps.put(195, returnToBleemadge); + + var goAndReturnToSanfew = new ConditionalStep(this, returnUpToSanfew); + goAndReturnToSanfew.addStep(inSanfewRoom, returnToSanfew); + steps.put(200, goAndReturnToSanfew); + + var dealWithHammerspike = new ConditionalStep(this, goDownToHammerspikeAgain); + dealWithHammerspike.addStep(inDwarvenMine, returnToHammerspike); + + steps.put(205, dealWithHammerspike); + + var sortOutGangMembers = new ConditionalStep(this, goDownToHammerspikeAgain); + sortOutGangMembers.addStep(inDwarvenMine, killGangMembers); + + steps.put(210, sortOutGangMembers); + steps.put(215, sortOutGangMembers); + steps.put(220, sortOutGangMembers); + + var dealWithHammerspikeAfterKillingHisGang = new ConditionalStep(this, goDownToHammerspikeAgain); + dealWithHammerspikeAfterKillingHisGang.addStep(inDwarvenMine, talkToHammerspikeFinal); + steps.put(225, dealWithHammerspikeAfterKillingHisGang); + + steps.put(230, returnToTassie); + + var makePotAndReturnToApoth = new ConditionalStep(this, spinPotLid); + makePotAndReturnToApoth.addStep(potWithLid, returnToApothecary); + makePotAndReturnToApoth.addStep(and(potLid, pot), usePotLidOnPot); + makePotAndReturnToApoth.addStep(potLid, pickUpPot); + makePotAndReturnToApoth.addStep(unfiredPotLid, firePotLid); + + steps.put(235, makePotAndReturnToApoth); + + steps.put(240, returnToHorvik); + + steps.put(245, talkToHorvikFinal); + + steps.put(250, returnToSeth); + + var goFinishWithJohanhus = new ConditionalStep(this, returnDownToJohnahus); + goFinishWithJohanhus.addStep(inHamBase, returnToJohnahus); + + steps.put(255, goFinishWithJohanhus); + + steps.put(260, returnToAggie); + + steps.put(265, returnToBrian); + + steps.put(270, returnToForester); + + steps.put(275, returnToYanni); + + return steps; + } + + @Override + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(steelBars4); - reqs.add(bronzeBar); - reqs.add(ironBar); - reqs.add(chisel); - reqs.add(guam2); - reqs.add(marrentill); - reqs.add(harralander); - reqs.add(hammer); - reqs.add(emptyCup); - reqs.add(pot); - reqs.add(hotWaterBowl); - - return reqs; + return List.of( + new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.SHILO_VILLAGE, QuestState.FINISHED), + new SkillRequirement(Skill.AGILITY, 36, true), + new SkillRequirement(Skill.CRAFTING, 25, true), + new SkillRequirement(Skill.HERBLORE, 18, true), + new SkillRequirement(Skill.SMITHING, 30, true) + ); } + @Override - public List getItemRecommended() + public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(draynorVillageTeleports); - reqs.add(lumbridgeTeleports); - reqs.add(varrockTeleports); - reqs.add(taverleyOrFaladorTeleports); - reqs.add(camelotTeleports); - reqs.add(fishingGuildAndDwarvenMineTeleports); - reqs.add(ardougneTeleports); - reqs.add(khazardTeleports); - reqs.add(feldipHillsTeleports); - reqs.add(opal.quantity(2)); - reqs.add(jade.quantity(2)); - reqs.add(redTopaz.quantity(2)); - reqs.add(pickaxe); - return reqs; + return List.of( + steelBars4, + bronzeBar, + ironBar, + chisel, + guam2, + marrentill, + harralander, + hammer, + emptyCup, + pot, + hotWaterBowl + ); } @Override - public List getCombatRequirements() + public List getItemRecommended() { - return Arrays.asList("Slagilith (level 92)", "3x Dwarf gang members (level 44)"); + return List.of( + draynorVillageTeleports, + lumbridgeTeleports, + varrockTeleports, + taverleyOrFaladorTeleports, + camelotTeleports, + fishingGuildAndDwarvenMineTeleports, + ardougneTeleports, + khazardTeleports, + feldipHillsTeleports, + opal2, + jade2, + redTopaz2, + coins3000, + pickaxe + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.SHILO_VILLAGE, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.AGILITY, 36, true)); - req.add(new SkillRequirement(Skill.CRAFTING, 25, true)); - req.add(new SkillRequirement(Skill.HERBLORE, 18, true)); - req.add(new SkillRequirement(Skill.SMITHING, 30, true)); - return req; + return List.of( + "Slagilith (level 92)", + "3x Dwarf gang members (level 44)" + ); } @Override @@ -851,36 +1128,117 @@ public QuestPointReward getQuestPointReward() @Override public List getItemRewards() { - return Arrays.asList( - new ItemReward("10,000 Experience Lamps (Any skill over level 30)", ItemID.THOSF_REWARD_LAMP, 2), //4447 is placeholder for filter - new ItemReward("A Steel Keyring", ItemID.FAVOUR_KEY_RING, 1)); + return List.of( + new ItemReward("10,000 Experience Lamps (Any skill over level 30)", ItemID.THOSF_REWARD_LAMP, 2), + new ItemReward("A Steel Keyring", ItemID.FAVOUR_KEY_RING, 1) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("The ability to make Guthix Rest tea."), - new UnlockReward("Gnome Glider in Feldip Hills.")); + return List.of( + new UnlockReward("The ability to make Guthix Rest tea."), + new UnlockReward("Gnome Glider in Feldip Hills.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToYanni))); - allSteps.add(new PanelDetails("A few small favours", Arrays.asList(talkToJungleForester, talkToBrian, talkToAggie, talkToJohanhus, talkToFred, talkToSeth, - talkToHorvik, talkToApoth, talkToTassie, talkToHammerspike, talkToSanfew, makeGuthixRest, talkToBleemadge, talkToArhein, talkToPhantuwti, enterGoblinCave, - searchWall, talkToCromperty, talkToTindel, talkToRantz, talkToGnormadium, fixAllLamps), - chisel, steelBars3, emptyCup, hotWaterBowl, guam2, marrentill, harralander)); - allSteps.add(new PanelDetails("Completing the favours", Arrays.asList(talkToGnormadiumAgain, returnToRantz, - returnToTindel, returnToCromperty, getPigeonCages, enterGoblinCaveAgain, standNextToSculpture, killSlagilith, - readScrollAgain, talkToPetra, returnToPhantuwti, searchVane, useHammerOnVane, searchVaneAgain, - useVane123OnAnvil, goBackUpLadder, finishWithPhantuwti, returnToArhein, returnToBleemadge, returnToSanfew, - returnToHammerspike, killGangMembers, talkToHammerspikeFinal, returnToTassie, spinPotLid, firePotLid, pickUpPot, - usePotLidOnPot, returnToApothecary, returnToHorvik, talkToHorvikFinal, returnToSeth, returnToJohnahus, returnToAggie, - returnToBrian, returnToForester, returnToYanni), bronzeBar, ironBar, steelBar, hammer, pot)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToYanni + ))); + + sections.add(new PanelDetails("A few small favours", List.of( + talkToJungleForester, + talkToBrian, + talkToAggie, + talkToJohanhus, + talkToFred, + talkToSeth, + talkToHorvik, + talkToApoth, + talkToTassie, + talkToHammerspike, + talkToSanfew, + makeGuthixRest, + talkToBleemadge, + talkToArhein, + talkToPhantuwti, + enterGoblinCave, + searchWall, + talkToCromperty, + talkToTindel, + talkToRantz, + talkToGnormadium, + fixAllLamps + ), List.of( + chisel, + steelBars3, + emptyCup, + hotWaterBowl, + guam2, + marrentill, + harralander + ), List.of( + opal2, + jade2, + redTopaz2, + coins3000 + ))); + + sections.add(new PanelDetails("Completing the favours", List.of( + talkToGnormadiumAgain, + returnToRantz, + returnToTindel, + returnToCromperty, + getPigeonCages, + enterGoblinCaveAgain, + standNextToSculpture, + killSlagilith, + readScrollAgain, + talkToPetra, + returnToPhantuwti, + searchVane, + useHammerOnVane, + searchVaneAgain, + useVane123OnAnvil, + goBackUpLadder, + finishWithPhantuwti, + returnToArhein, + returnToBleemadge, + returnToSanfew, + returnToHammerspike, + killGangMembers, + talkToHammerspikeFinal, + returnToTassie, + spinPotLid, + firePotLid, + pickUpPot, + usePotLidOnPot, + returnToApothecary, + returnToHorvik, + talkToHorvikFinal, + returnToSeth, + returnToJohnahus, + returnToAggie, + returnToBrian, + returnToForester, + returnToYanni + ), List.of( + bronzeBar, + ironBar, + steelBar, + hammer, + pot + ), List.of( + combatGear, + pickaxe + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java index 1d1cfc0ac43..8360d6e8904 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java @@ -27,11 +27,14 @@ import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.NoItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.ShipInPortRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.ItemSlots; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Port; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; @@ -41,143 +44,106 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.BoardShipStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.SailStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - -import java.util.*; -import java.util.regex.Pattern; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class Pandemonium extends BasicQuestHelper { - NpcStep getToPandemonium, talkToWill, boardWAShip, explainJob, explainJob2, learnWhereYouAre, learnWhoWAare, talkToRibs, findLocationWA, enterShipyard, informAboutShip, showCup, getLogBook, getNewJob, talkToJim, meetGrog, finishQuest; - ObjectStep buildCargoHold, embarkShipSY, disembarkShipSY, leaveShipyard,dropCargoInCargoHold, disembarkShipPS, deliverCargo, disembarkShipP, getHammer, getSaw; - Zone pandemonium, portSarim, pandemoniumDockZone, portSarimDockZone, shipWreckZone; - DetailedQuestStep navigateShip, watchSalvageCutscene, takeHelm, takeHelm2, takeHelm3, raiseSails, raiseSails2, raiseSails3, salvageShipwreck, sailToPortSarim, pickupCargo, pickupCargoShip, sailToPandemonium, letGoOfHelm, letGoOfHelm2; - BoardShipStep boardShip, boardShip2, boardShip3; - Requirement onPandemonium, boatAtPortSarim, onboardShip, takenHelm, setSails, sailing, atShipwreck, notAtShipwreck, canSalvage, hammerAndSaw, atShipyard, atPortSarimDock, atPandemoniumDock, holdingCargo, cargoPickedUp, cargoNotPickedUp, cargoInCargoHold; - ItemRequirement hammer, saw, cup; + // Required items + ItemRequirement hammer; + ItemRequirement saw; + + // Mid-quest item requirements + ItemRequirement cup; + + // Zones + Zone pandemonium; + Zone portSarim; + Zone pandemoniumDockZone; + Zone portSarimDockZone; + Zone shipWreckZone; + + // Miscellaneous requirements + ZoneRequirement onPandemonium; + ShipInPortRequirement boatAtPortSarim; + VarbitRequirement onboardShip; + VarbitRequirement takenHelm; + VarbitRequirement setSails; + Conditions sailing; + VarbitRequirement atShipwreck; + Conditions canSalvage; + VarbitRequirement atShipyard; + VarbitRequirement holdingCargo; + VarbitRequirement cargoPickedUp; + Conditions cargoNotPickedUp; + ZoneRequirement atPortSarimDock; + ZoneRequirement atPandemoniumDock; + Conditions cargoInCargoHold; NoItemRequirement nothingInHands; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToWill); - steps.put(2, talkToWill); - - steps.put(4, boardWAShip); - - ConditionalStep goListenOnShip = new ConditionalStep(this, talkToWill); - goListenOnShip.addStep(onboardShip, explainJob); - steps.put(6, goListenOnShip); - - ConditionalStep cNavigateToShipwreckOnShip = new ConditionalStep(this, takeHelm); - cNavigateToShipwreckOnShip.addStep(canSalvage, salvageShipwreck); - cNavigateToShipwreckOnShip.addStep(atShipwreck, explainJob2); - cNavigateToShipwreckOnShip.addStep(sailing, navigateShip); - cNavigateToShipwreckOnShip.addStep(takenHelm, raiseSails); - cNavigateToShipwreckOnShip.addStep(notAtShipwreck, takeHelm); - - ConditionalStep cNavigateToShipwreck = new ConditionalStep(this, boardWAShip); - cNavigateToShipwreck.addStep(and(new VarbitRequirement(VarbitID.CUTSCENE_STATUS, 1), canSalvage), watchSalvageCutscene); - cNavigateToShipwreck.addStep(onboardShip, cNavigateToShipwreckOnShip); - steps.put(8, cNavigateToShipwreck); - steps.put(10, cNavigateToShipwreck); - steps.put(12, cNavigateToShipwreck); - steps.put(14, cNavigateToShipwreck); - - ConditionalStep cLearnWhereYouAre = new ConditionalStep(this, getToPandemonium); - cLearnWhereYouAre.addStep(onPandemonium, learnWhereYouAre); - steps.put(16, cLearnWhereYouAre); - ConditionalStep cLearnWhoWAare = new ConditionalStep(this, getToPandemonium); - cLearnWhoWAare.addStep(onPandemonium, learnWhoWAare); - steps.put(18, cLearnWhoWAare); - ConditionalStep cTalkToRibs = new ConditionalStep(this, getToPandemonium); - cTalkToRibs.addStep(onPandemonium, talkToRibs); - steps.put(20, cTalkToRibs); - ConditionalStep cFindLocationWA = new ConditionalStep(this, getToPandemonium); - cFindLocationWA.addStep(onPandemonium, findLocationWA); - steps.put(22, cFindLocationWA); - ConditionalStep cInformAboutShip = new ConditionalStep(this, getToPandemonium); - cInformAboutShip.addStep(onPandemonium, informAboutShip); - steps.put(24, cInformAboutShip); - ConditionalStep cShowCup = new ConditionalStep(this, getToPandemonium); - cShowCup.addStep(onPandemonium, showCup); - steps.put(26, cShowCup); - - ConditionalStep cBuildCargoHold = new ConditionalStep(this, getToPandemonium); - cBuildCargoHold.addStep(and(atShipyard, onboardShip), buildCargoHold); - cBuildCargoHold.addStep(and(atShipyard, hammerAndSaw), embarkShipSY); - cBuildCargoHold.addStep(and(atShipyard, saw), getHammer); - cBuildCargoHold.addStep(atShipyard, getSaw); - cBuildCargoHold.addStep(onPandemonium, enterShipyard); - steps.put(28, cBuildCargoHold); - - - ConditionalStep cGetLogBook = new ConditionalStep(this, getToPandemonium); - cGetLogBook.addStep(onPandemonium, getLogBook); - cGetLogBook.addStep(atShipyard, leaveShipyard); - steps.put(30, cGetLogBook); // Jim - - steps.put(32, getNewJob); // Jim - steps.put(34, boardShip); - ConditionalStep cSailToPortSarim = new ConditionalStep(this, boardShip); - cSailToPortSarim.addStep(and(not(atPortSarimDock), sailing), sailToPortSarim); - cSailToPortSarim.addStep(and(not(atPortSarimDock), takenHelm), raiseSails2); - cSailToPortSarim.addStep(and(not(atPortSarimDock), onboardShip), takeHelm2); - steps.put(36, cSailToPortSarim); - ConditionalStep cCheckPortMaster = new ConditionalStep(this, cSailToPortSarim); - cCheckPortMaster.addStep(and(boatAtPortSarim, holdingCargo, not(onboardShip)), boardShip2); - cCheckPortMaster.addStep(and(boatAtPortSarim, cargoNotPickedUp, not(onboardShip)), pickupCargo); - cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, takenHelm), letGoOfHelm); - cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, onboardShip), disembarkShipPS); - steps.put(38, cCheckPortMaster); - ConditionalStep cSailToPandemonium = new ConditionalStep(this, cCheckPortMaster); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm, sailing), sailToPandemonium); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm), raiseSails3); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip), takeHelm3); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoPickedUp, holdingCargo, onboardShip), dropCargoInCargoHold); - - ConditionalStep cDeliverCargo = new ConditionalStep(this, cSailToPandemonium); - cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), holdingCargo), deliverCargo); - cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, holdingCargo), disembarkShipP); - cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, nor(takenHelm, setSails), cargoInCargoHold), pickupCargoShip); - cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), cargoInCargoHold), boardShip3); - cDeliverCargo.addStep(and(atPandemoniumDock, cargoInCargoHold, takenHelm), letGoOfHelm2); - steps.put(40, cDeliverCargo); - steps.put(42, cDeliverCargo); - steps.put(44, talkToJim); - steps.put(46, meetGrog); - steps.put(48, finishQuest); - - return steps; - } - - public void setupConditions() - { - onboardShip = new VarbitRequirement(VarbitID.SAILING_BOARDED_BOAT, 1); - takenHelm = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_HELM_STATUS, 2); - setSails = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_BOAT_MOVE_MODE, 0, Operation.GREATER); - canSalvage = and(atShipwreck, new VarbitRequirement(VarbitID.SAILING_INTRO, 14, Operation.GREATER_EQUAL)); // At wreck, with explanation about salvaging - sailing = and(takenHelm, setSails, onboardShip); - - atShipyard = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_SHIPYARD_MODE, 1); - holdingCargo = new VarbitRequirement(VarbitID.SAILING_CARRYING_CARGO, 1); - - cargoPickedUp = new VarbitRequirement(VarbitID.PORT_TASK_SLOT_0_CARGO_TAKEN, 1); - cargoNotPickedUp = not(cargoPickedUp); - cargoInCargoHold = and(cargoPickedUp, not(holdingCargo)); - - nothingInHands = new NoItemRequirement("Nothing equipped in your hands.",ItemSlots.WEAPON, ItemSlots.SHIELD); - } + // Steps + NpcStep getToPandemonium; + NpcStep talkToWill; + NpcStep boardWAShip; + NpcStep explainJob; + NpcStep explainJob2; + NpcStep learnWhereYouAre; + NpcStep learnWhoWAare; + NpcStep talkToRibs; + NpcStep findLocationWA; + NpcStep enterShipyard; + NpcStep informAboutShip; + NpcStep showCup; + NpcStep getLogBook; + NpcStep getNewJob; + NpcStep talkToJim; + NpcStep meetGrog; + NpcStep finishQuest; + ObjectStep buildCargoHold; + ObjectStep embarkShipSY; + ObjectStep disembarkShipSY; + ObjectStep leaveShipyard; + ObjectStep dropCargoInCargoHold; + ObjectStep disembarkShipPS; + ObjectStep deliverCargo; + ObjectStep disembarkShipP; + ObjectStep getHammer; + ObjectStep getSaw; + DetailedQuestStep navigateShip; + DetailedQuestStep watchSalvageCutscene; + DetailedQuestStep takeHelm; + DetailedQuestStep takeHelm2; + DetailedQuestStep takeHelm3; + DetailedQuestStep raiseSails; + DetailedQuestStep raiseSails2; + DetailedQuestStep raiseSails3; + DetailedQuestStep salvageShipwreck; + DetailedQuestStep sailToPortSarim; + DetailedQuestStep pickupCargo; + DetailedQuestStep pickupCargoShip; + DetailedQuestStep sailToPandemonium; + DetailedQuestStep letGoOfHelm; + DetailedQuestStep letGoOfHelm2; + BoardShipStep boardShip; + BoardShipStep boardShip2; + BoardShipStep boardShip3; @Override protected void setupZones() @@ -187,12 +153,6 @@ protected void setupZones() portSarim = new Zone(new WorldPoint(3027, 3192, 0), new WorldPoint(3050, 3204, 0)); pandemoniumDockZone = new Zone(new WorldPoint(3065, 2974, 0), new WorldPoint(3084, 2998, 0)); portSarimDockZone = new Zone(new WorldPoint(3045, 3183, 0), new WorldPoint(3061, 3208, 0)); - atShipwreck = new VarbitRequirement(VarbitID.SAILING_INTRO_REACHED_WRECK, 1); - notAtShipwreck = not(atShipwreck); - onPandemonium = new ZoneRequirement(pandemonium); - boatAtPortSarim = new ShipInPortRequirement(Port.PORT_SARIM); - atPandemoniumDock = new ZoneRequirement(pandemoniumDockZone); - atPortSarimDock = new ZoneRequirement(portSarimDockZone); } @Override @@ -202,11 +162,32 @@ protected void setupRequirements() hammer.setTooltip("You can pick this up at the shipyard."); saw = new ItemRequirement("Saw", ItemCollections.SAW).isNotConsumed().canBeObtainedDuringQuest(); saw.setTooltip("You can pick this up at the shipyard."); - hammerAndSaw = and(hammer, saw); // Quest items cup = new ItemRequirement("Old cup", ItemID.SAILING_INTRO_CUP); cup.setTooltip("You can get another from Steve Beanie behind the bar on Pandemonium"); + + atShipwreck = new VarbitRequirement(VarbitID.SAILING_INTRO_REACHED_WRECK, 1); + onPandemonium = new ZoneRequirement(pandemonium); + boatAtPortSarim = new ShipInPortRequirement(Port.PORT_SARIM); + atPandemoniumDock = new ZoneRequirement(pandemoniumDockZone); + atPortSarimDock = new ZoneRequirement(portSarimDockZone); + + // Miscellaneous requirements + onboardShip = new VarbitRequirement(VarbitID.SAILING_BOARDED_BOAT, 1); + takenHelm = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_HELM_STATUS, 2); + setSails = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_BOAT_MOVE_MODE, 0, Operation.GREATER); + canSalvage = and(atShipwreck, new VarbitRequirement(VarbitID.SAILING_INTRO, 14, Operation.GREATER_EQUAL)); // At wreck, with explanation about salvaging + sailing = and(takenHelm, setSails, onboardShip); + + atShipyard = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_SHIPYARD_MODE, 1); + holdingCargo = new VarbitRequirement(VarbitID.SAILING_CARRYING_CARGO, 1); + + cargoPickedUp = new VarbitRequirement(VarbitID.PORT_TASK_SLOT_0_CARGO_TAKEN, 1); + cargoNotPickedUp = not(cargoPickedUp); + cargoInCargoHold = and(cargoPickedUp, not(holdingCargo)); + + nothingInHands = new NoItemRequirement("Nothing equipped in your hands.", ItemSlots.EMPTY_HANDS); } public void setupSteps() @@ -248,7 +229,7 @@ public void setupSteps() // Your mighty vessel enterShipyard = new NpcStep(this, NpcID.JUNIOR_JIM, new WorldPoint(3059, 2979, 0), "Talk to Junior Jim to enter the shipyard."); getHammer = new ObjectStep(this, ObjectID.CRATE_HAMMERS, "Pick up a hammer from the crate of hammers."); - getSaw = new ObjectStep(this, ObjectID.CRATE_SAWS, "Pick up a from the crate of saws."); + getSaw = new ObjectStep(this, ObjectID.CRATE_SAWS, "Pick up a saw from the crate of saws."); embarkShipSY = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_PROXY_WIDE, "Board your vessel."); buildCargoHold = new ObjectStep(this, ObjectID.SAILING_BOAT_FACILITY_PLACEHOLDER_RAFT_0, "Build the Cargo Hold."); disembarkShipSY = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_SHIPYARD_DISEMBARK, "Disembark your vessel."); @@ -264,7 +245,7 @@ public void setupSteps() sailToPortSarim = new SailStep(this, Port.PORT_SARIM); letGoOfHelm = new ObjectStep(this, ObjectID.SAILING_BOAT_STEERING_KANDARIN_1X3_WOOD_IN_USE, new WorldPoint(3843, 6460, 1), "Let go of the helm."); disembarkShipPS = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(3051, 3193, 0), "Leave your ship."); - + pickupCargo = new ObjectStep(this, ObjectID.DOCK_LOADING_BAY_LEDGER_TABLE_WITHDRAW, new WorldPoint(3028, 3194, 0), "Pick up the cargo from the ledger table on the docks.", nothingInHands); boardShip2 = new BoardShipStep(this); dropCargoInCargoHold = new ObjectStep(this, ObjectID.SAILING_BOAT_CARGO_HOLD_REGULAR_RAFT, "Deposit the crate into your cargo hold."); @@ -274,7 +255,11 @@ public void setupSteps() sailToPandemonium = new SailStep(this, Port.PANDEMONIUM); letGoOfHelm2 = new ObjectStep(this, ObjectID.SAILING_BOAT_STEERING_KANDARIN_1X3_WOOD_IN_USE, new WorldPoint(3843, 6460, 1), "Let go of the helm."); pickupCargoShip = new ObjectStep(this, ObjectID.SAILING_BOAT_CARGO_HOLD_REGULAR_RAFT, "Pick up the cargo from your ship's cargo hold.", nothingInHands); + + // In case the user boards the Pandemonium without picking up the cargo from their ship boardShip3 = new BoardShipStep(this); + pickupCargoShip.addSubSteps(boardShip3); + disembarkShipP = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(3070, 2987, 0), "Leave your ship."); deliverCargo = new ObjectStep(this, ObjectID.DOCK_LOADING_BAY_LEDGER_TABLE_DEPOSIT, new WorldPoint(3061, 2985, 0), "Deliver the cargo at the ledger table on the docks."); //Finish up @@ -284,15 +269,119 @@ public void setupSteps() } @Override - public QuestPointReward getQuestPointReward() + public Map loadSteps() { - return new QuestPointReward(1); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToWill); + steps.put(2, talkToWill); + + steps.put(4, boardWAShip); + + var goListenOnShip = new ConditionalStep(this, talkToWill); + goListenOnShip.addStep(onboardShip, explainJob); + steps.put(6, goListenOnShip); + + var cNavigateToShipwreckOnShip = new ConditionalStep(this, takeHelm); + cNavigateToShipwreckOnShip.addStep(canSalvage, salvageShipwreck); + cNavigateToShipwreckOnShip.addStep(atShipwreck, explainJob2); + cNavigateToShipwreckOnShip.addStep(sailing, navigateShip); + cNavigateToShipwreckOnShip.addStep(takenHelm, raiseSails); + cNavigateToShipwreckOnShip.addStep(not(atShipwreck), takeHelm); + + var cNavigateToShipwreck = new ConditionalStep(this, boardWAShip); + cNavigateToShipwreck.addStep(and(new VarbitRequirement(VarbitID.CUTSCENE_STATUS, 1), canSalvage), watchSalvageCutscene); + cNavigateToShipwreck.addStep(onboardShip, cNavigateToShipwreckOnShip); + steps.put(8, cNavigateToShipwreck); + steps.put(10, cNavigateToShipwreck); + steps.put(12, cNavigateToShipwreck); + steps.put(14, cNavigateToShipwreck); + + var cLearnWhereYouAre = new ConditionalStep(this, getToPandemonium); + cLearnWhereYouAre.addStep(onPandemonium, learnWhereYouAre); + steps.put(16, cLearnWhereYouAre); + var cLearnWhoWAare = new ConditionalStep(this, getToPandemonium); + cLearnWhoWAare.addStep(onPandemonium, learnWhoWAare); + steps.put(18, cLearnWhoWAare); + var cTalkToRibs = new ConditionalStep(this, getToPandemonium); + cTalkToRibs.addStep(onPandemonium, talkToRibs); + steps.put(20, cTalkToRibs); + var cFindLocationWA = new ConditionalStep(this, getToPandemonium); + cFindLocationWA.addStep(onPandemonium, findLocationWA); + steps.put(22, cFindLocationWA); + var cInformAboutShip = new ConditionalStep(this, getToPandemonium); + cInformAboutShip.addStep(onPandemonium, informAboutShip); + steps.put(24, cInformAboutShip); + var cShowCup = new ConditionalStep(this, getToPandemonium); + cShowCup.addStep(onPandemonium, showCup); + steps.put(26, cShowCup); + + var cBuildCargoHold = new ConditionalStep(this, getToPandemonium); + cBuildCargoHold.addStep(and(atShipyard, onboardShip), buildCargoHold); + cBuildCargoHold.addStep(and(atShipyard, hammer, saw), embarkShipSY); + cBuildCargoHold.addStep(and(atShipyard, saw), getHammer); + cBuildCargoHold.addStep(atShipyard, getSaw); + cBuildCargoHold.addStep(onPandemonium, enterShipyard); + steps.put(28, cBuildCargoHold); + + + var cGetLogBook = new ConditionalStep(this, getToPandemonium); + cGetLogBook.addStep(onPandemonium, getLogBook); + cGetLogBook.addStep(atShipyard, leaveShipyard); + steps.put(30, cGetLogBook); // Jim + + steps.put(32, getNewJob); // Jim + steps.put(34, boardShip); + var cSailToPortSarim = new ConditionalStep(this, boardShip); + cSailToPortSarim.addStep(and(atPortSarimDock, cargoNotPickedUp, takenHelm), letGoOfHelm); + cSailToPortSarim.addStep(and(atPortSarimDock, cargoNotPickedUp, onboardShip), disembarkShipPS); + cSailToPortSarim.addStep(and(not(atPortSarimDock), sailing), sailToPortSarim); + cSailToPortSarim.addStep(and(not(atPortSarimDock), takenHelm), raiseSails2); + cSailToPortSarim.addStep(and(not(atPortSarimDock), onboardShip), takeHelm2); + steps.put(36, cSailToPortSarim); + var cCheckPortMaster = new ConditionalStep(this, cSailToPortSarim); + cCheckPortMaster.addStep(and(boatAtPortSarim, holdingCargo, not(onboardShip)), boardShip2); + cCheckPortMaster.addStep(and(boatAtPortSarim, cargoNotPickedUp, not(onboardShip)), pickupCargo); + cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, takenHelm), letGoOfHelm); + cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, onboardShip), disembarkShipPS); + steps.put(38, cCheckPortMaster); + var cSailToPandemonium = new ConditionalStep(this, cCheckPortMaster); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm, sailing), sailToPandemonium); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm), raiseSails3); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip), takeHelm3); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoPickedUp, holdingCargo, onboardShip), dropCargoInCargoHold); + + var cDeliverCargo = new ConditionalStep(this, cSailToPandemonium); + cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), holdingCargo), deliverCargo); + cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, holdingCargo), disembarkShipP); + cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, nor(takenHelm, setSails), cargoInCargoHold), pickupCargoShip); + cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), cargoInCargoHold), boardShip3); + cDeliverCargo.addStep(and(atPandemoniumDock, cargoInCargoHold, takenHelm), letGoOfHelm2); + steps.put(40, cDeliverCargo); + steps.put(42, cDeliverCargo); + steps.put(44, talkToJim); + steps.put(46, meetGrog); + steps.put(48, finishQuest); + + return steps; } @Override public List getItemRequirements() { - return Arrays.asList(hammer, saw); + return List.of( + hammer, + saw + ); + } + + @Override + public QuestPointReward getQuestPointReward() + { + return new QuestPointReward(1); } @Override @@ -304,29 +393,93 @@ public List getExperienceRewards() @Override public List getItemRewards() { - return Arrays.asList( + return List.of( new ItemReward("Sawmill Coupon (wood plank)", ItemID.SAWMILL_COUPON, 25), new ItemReward("Repair kits", ItemID.BOAT_REPAIR_KIT, 2), - new ItemReward("Spyglass", ItemID.SAILING_CHARTING_SPYGLASS, 1)); + new ItemReward("Spyglass", ItemID.SAILING_CHARTING_SPYGLASS, 1) + ); } @Override public List getUnlockRewards() { - return Arrays.asList(new UnlockReward("Access to the Sailing Skill"), new UnlockReward("Access to Pandemonium"), new UnlockReward("Your very own mighty ship!")); + return List.of( + new UnlockReward("Access to the Sailing Skill"), + new UnlockReward("Access to Pandemonium"), + new UnlockReward("Your very own mighty ship!") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("You got the job!", Arrays.asList(talkToWill, boardWAShip))); - allSteps.add(new PanelDetails("What's the job?", Arrays.asList(explainJob, takeHelm, raiseSails, navigateShip, explainJob2, salvageShipwreck, watchSalvageCutscene))); - allSteps.add(new PanelDetails("You lost the job!", Arrays.asList(getToPandemonium, learnWhereYouAre, learnWhoWAare, talkToRibs, findLocationWA, informAboutShip, showCup))); - allSteps.add(new PanelDetails("Your mighty vessel", Arrays.asList(enterShipyard, getSaw, getHammer, embarkShipSY, buildCargoHold, disembarkShipSY, leaveShipyard, getLogBook))); - allSteps.add(new PanelDetails("You got the job... again!", Arrays.asList(getNewJob, boardShip, takeHelm2, raiseSails2, sailToPortSarim, letGoOfHelm, disembarkShipPS, pickupCargo, boardShip2))); - allSteps.add(new PanelDetails("Deliver the cargo.", Arrays.asList(dropCargoInCargoHold, takeHelm3, raiseSails3, sailToPandemonium, letGoOfHelm2, pickupCargoShip, disembarkShipP, deliverCargo))); - allSteps.add(new PanelDetails("Finishing up", Arrays.asList(talkToJim, meetGrog, finishQuest))); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("You got the job!", List.of( + talkToWill, + boardWAShip + ))); + + sections.add(new PanelDetails("What's the job?", List.of( + explainJob, + takeHelm, + raiseSails, + navigateShip, + explainJob2, + salvageShipwreck, + watchSalvageCutscene + ))); + + sections.add(new PanelDetails("You lost the job!", List.of( + getToPandemonium, + learnWhereYouAre, + learnWhoWAare, + talkToRibs, + findLocationWA, + informAboutShip, + showCup + ))); + + sections.add(new PanelDetails("Your mighty vessel", List.of( + enterShipyard, + getSaw, + getHammer, + embarkShipSY, + buildCargoHold, + disembarkShipSY, + leaveShipyard, + getLogBook + ))); + + sections.add(new PanelDetails("You got the job... again!", List.of( + getNewJob, + boardShip, + takeHelm2, + raiseSails2, + sailToPortSarim, + letGoOfHelm, + disembarkShipPS, + pickupCargo, + boardShip2 + ))); + + sections.add(new PanelDetails("Deliver the cargo.", List.of( + dropCargoInCargoHold, + takeHelm3, + raiseSails3, + sailToPandemonium, + letGoOfHelm2, + pickupCargoShip, + disembarkShipP, + deliverCargo + ))); + + sections.add(new PanelDetails("Finishing up", List.of( + talkToJim, + meetGrog, + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java index 0766746b7b1..c3c4b80bb61 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java @@ -33,16 +33,20 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DigStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; public class PiratesTreasure extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java index 805f3e4c309..8075c234ceb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java @@ -32,22 +32,24 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.List; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class RumSmugglingStep extends ConditionalStep { private final PiratesTreasure pt; @@ -171,7 +173,7 @@ private void setupRequirements() private void setupSteps() { goToKaramja = new NpcStep(getQuestHelper(), NpcID.SEAMAN_LORRIS, new WorldPoint(3027, 3222, 0), - "Talk to one of the Seamen on the docks in Port Sarim to go to Karamja.", new ItemRequirement("Coins", ItemCollections.COINS, 60)); + "Talk to one of the Seamen on the docks in Port Sarim to go to Musa Point.", new ItemRequirement("Coins", ItemCollections.COINS, 60)); goToKaramja.addDialogStep("Yes please."); talkToZambo = new NpcStep(getQuestHelper(), NpcID.ZEMBO, new WorldPoint(2929, 3145, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java index f2e6906212c..ea5c10ad94c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java @@ -28,13 +28,22 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -42,13 +51,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class PlagueCity extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java index 9bbc2830699..c739999b538 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java @@ -27,10 +27,11 @@ import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -38,150 +39,104 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class PriestInPeril extends BasicQuestHelper { - //Items Required - ItemRequirement runeEssence, lotsOfRuneEssence, bucket, weaponAndArmour, goldenKey, rangedMagedGear, - murkyWater, ironKey, blessedWaterHighlighted, bucketHighlighted, goldenKeyHighlighted; - - //Items Recommended - ItemRequirement runePouches, varrockTeleport; - - Requirement inUnderground, hasGoldenOrIronKey, inTempleGroundFloor, inTemple, inTempleFirstFloor, inTempleSecondFloor; - - QuestStep talkToRoald, goToTemple, goDownToDog, killTheDog, climbUpAfterKillingDog, returnToKingRoald, returnToTemple, killMonk, talkToDrezel, - goUpToFloorTwoTemple, goUpToFloorOneTemple, goDownToFloorOneTemple, goDownToGroundFloorTemple, enterUnderground, fillBucket, useKeyForKey, - openDoor, useBlessedWater, blessWater, goUpWithWaterToSurface, goUpWithWaterToFirstFloor, goUpWithWaterToSecondFloor, talkToDrezelAfterFreeing, - goDownToFloorOneAfterFreeing, goDownToGroundFloorAfterFreeing, enterUndergroundAfterFreeing, talkToDrezelUnderground, bringDrezelEssence; + // Required items + ItemRequirement runeEssence; + ItemRequirement bucket; + + // Recommended items + ItemRequirement varrockTeleport; + ItemRequirement runePouches; + + // Mid-quest requirements + ItemRequirement lotsOfRuneEssence; + ItemRequirement weaponAndArmour; + ItemRequirement goldenKey; + ItemRequirement rangedMagedGear; + ItemRequirement murkyWater; + ItemRequirement ironKey; + ItemRequirement blessedWaterHighlighted; + ItemRequirement bucketHighlighted; + ItemRequirement goldenKeyHighlighted; + + // Zones + Zone underground; + Zone temple1; + Zone temple2; + Zone temple3; + Zone temple4; + Zone temple5; + Zone temple6; + Zone templeFloorOne; + Zone templeFloorTwo; + + // Miscellaneous requirements + ZoneRequirement inUnderground; + ZoneRequirement inTempleGroundFloor; + ZoneRequirement inTemple; + ZoneRequirement inTempleFirstFloor; + ZoneRequirement inTempleSecondFloor; + Conditions hasGoldenOrIronKey; + + // Steps + NpcStep talkToRoald; + ObjectStep goToTemple; + ObjectStep goDownToDog; + NpcStep killTheDog; + ObjectStep climbUpAfterKillingDog; + NpcStep returnToKingRoald; + ObjectStep returnToTemple; + NpcStep killMonk; + NpcStep talkToDrezel; + ObjectStep goUpToFloorTwoTemple; + ObjectStep goUpToFloorOneTemple; + ObjectStep goDownToFloorOneTemple; + ObjectStep goDownToGroundFloorTemple; + ObjectStep enterUnderground; + ObjectStep fillBucket; + DetailedQuestStep useKeyForKey; + ObjectStep openDoor; + ObjectStep useBlessedWater; + NpcStep blessWater; + ObjectStep goUpWithWaterToSurface; + ObjectStep goUpWithWaterToFirstFloor; + ObjectStep goUpWithWaterToSecondFloor; + NpcStep talkToDrezelAfterFreeing; + ObjectStep goDownToFloorOneAfterFreeing; + ObjectStep goDownToGroundFloorAfterFreeing; + ObjectStep enterUndergroundAfterFreeing; + NpcStep talkToDrezelUnderground; + NpcStep bringDrezelEssence; - //Zones - Zone underground, temple1, temple2, temple3, temple4, temple5, temple6, templeFloorOne, templeFloorTwo; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToRoald); - steps.put(1, goToTemple); - - ConditionalStep goDownAndKillDog = new ConditionalStep(this, goDownToDog); - goDownAndKillDog.addStep(inUnderground, killTheDog); - - steps.put(2, goDownAndKillDog); - - ConditionalStep reportKillingDog = new ConditionalStep(this, returnToKingRoald); - reportKillingDog.addStep(inUnderground, climbUpAfterKillingDog); - steps.put(3, reportKillingDog); - - ConditionalStep goTalkToDrezel = new ConditionalStep(this, returnToTemple); - goTalkToDrezel.addStep(new Conditions(hasGoldenOrIronKey, inTempleSecondFloor), talkToDrezel); - goTalkToDrezel.addStep(new Conditions(hasGoldenOrIronKey, inTempleFirstFloor), goUpToFloorTwoTemple); - goTalkToDrezel.addStep(new Conditions(hasGoldenOrIronKey, inTempleGroundFloor), goUpToFloorOneTemple); - goTalkToDrezel.addStep(inTemple, killMonk); - steps.put(4, goTalkToDrezel); - - ConditionalStep goGetKey = new ConditionalStep(this, returnToTemple); - goGetKey.addStep(new Conditions(ironKey, murkyWater, inTempleSecondFloor), openDoor); - goGetKey.addStep(new Conditions(ironKey, murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); - goGetKey.addStep(new Conditions(ironKey, murkyWater, inUnderground), goUpWithWaterToSurface); - goGetKey.addStep(new Conditions(ironKey, murkyWater), goUpWithWaterToFirstFloor); - goGetKey.addStep(new Conditions(ironKey, inUnderground), fillBucket); - goGetKey.addStep(new Conditions(hasGoldenOrIronKey, inUnderground), useKeyForKey); - goGetKey.addStep(new Conditions(hasGoldenOrIronKey, inTempleSecondFloor), goDownToFloorOneTemple); - goGetKey.addStep(new Conditions(hasGoldenOrIronKey, inTempleFirstFloor), goDownToGroundFloorTemple); - goGetKey.addStep(hasGoldenOrIronKey, enterUnderground); - goGetKey.addStep(inTemple, killMonk); - steps.put(5, goGetKey); - - ConditionalStep goGetWater = new ConditionalStep(this, enterUnderground); - goGetWater.addStep(new Conditions(blessedWaterHighlighted, inTempleSecondFloor), useBlessedWater); - goGetWater.addStep(new Conditions(murkyWater, inTempleSecondFloor), blessWater); - goGetWater.addStep(new Conditions(murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); - goGetWater.addStep(new Conditions(murkyWater, inUnderground), goUpWithWaterToSurface); - goGetWater.addStep(murkyWater, goUpWithWaterToFirstFloor); - goGetWater.addStep(inUnderground, fillBucket); - goGetWater.addStep(inTempleSecondFloor, goDownToFloorOneTemple); - goGetWater.addStep(inTempleFirstFloor, goDownToGroundFloorTemple); - steps.put(6, goGetWater); - - ConditionalStep goTalkToDrezelAfterFreeing = new ConditionalStep(this, goUpWithWaterToFirstFloor); - goTalkToDrezelAfterFreeing.addStep(inTempleSecondFloor, talkToDrezelAfterFreeing); - goTalkToDrezelAfterFreeing.addStep(inTempleFirstFloor, goUpWithWaterToSecondFloor); - steps.put(7, goTalkToDrezelAfterFreeing); - - ConditionalStep goDownToDrezel = new ConditionalStep(this, enterUndergroundAfterFreeing); - goDownToDrezel.addStep(inUnderground, talkToDrezelUnderground); - goDownToDrezel.addStep(inTempleFirstFloor, goDownToGroundFloorAfterFreeing); - goDownToDrezel.addStep(inTempleSecondFloor, goDownToFloorOneAfterFreeing); - steps.put(8, goDownToDrezel); - steps.put(9, goDownToDrezel); - - steps.put(10, bringDrezelEssence); - steps.put(11, bringDrezelEssence); - steps.put(12, bringDrezelEssence); - steps.put(13, bringDrezelEssence); - steps.put(14, bringDrezelEssence); - steps.put(15, bringDrezelEssence); - steps.put(16, bringDrezelEssence); - steps.put(17, bringDrezelEssence); - steps.put(18, bringDrezelEssence); - steps.put(19, bringDrezelEssence); - steps.put(20, bringDrezelEssence); - steps.put(21, bringDrezelEssence); - steps.put(22, bringDrezelEssence); - steps.put(23, bringDrezelEssence); - steps.put(24, bringDrezelEssence); - steps.put(25, bringDrezelEssence); - steps.put(26, bringDrezelEssence); - steps.put(27, bringDrezelEssence); - steps.put(28, bringDrezelEssence); - steps.put(29, bringDrezelEssence); - steps.put(30, bringDrezelEssence); - steps.put(31, bringDrezelEssence); - steps.put(32, bringDrezelEssence); - steps.put(33, bringDrezelEssence); - steps.put(34, bringDrezelEssence); - steps.put(35, bringDrezelEssence); - steps.put(36, bringDrezelEssence); - steps.put(37, bringDrezelEssence); - steps.put(38, bringDrezelEssence); - steps.put(39, bringDrezelEssence); - steps.put(40, bringDrezelEssence); - steps.put(41, bringDrezelEssence); - steps.put(42, bringDrezelEssence); - steps.put(43, bringDrezelEssence); - steps.put(44, bringDrezelEssence); - steps.put(45, bringDrezelEssence); - steps.put(46, bringDrezelEssence); - steps.put(47, bringDrezelEssence); - steps.put(48, bringDrezelEssence); - steps.put(49, bringDrezelEssence); - steps.put(50, bringDrezelEssence); - steps.put(51, bringDrezelEssence); - steps.put(52, bringDrezelEssence); - steps.put(53, bringDrezelEssence); - steps.put(54, bringDrezelEssence); - steps.put(55, bringDrezelEssence); - steps.put(56, bringDrezelEssence); - steps.put(57, bringDrezelEssence); - steps.put(58, bringDrezelEssence); - steps.put(59, bringDrezelEssence); - // There is a 60th step before the final 61, but the 'Quest Completed!' message pops up prior to it - - return steps; + underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); + temple1 = new Zone(new WorldPoint(3409, 3483, 0), new WorldPoint(3411, 3494, 0)); + temple2 = new Zone(new WorldPoint(3408, 3485, 0), new WorldPoint(3408, 3486, 0)); + temple3 = new Zone(new WorldPoint(3408, 3491, 0), new WorldPoint(3408, 3492, 0)); + temple4 = new Zone(new WorldPoint(3412, 3484, 0), new WorldPoint(3415, 3493, 0)); + temple5 = new Zone(new WorldPoint(3416, 3483, 0), new WorldPoint(3417, 3494, 0)); + temple6 = new Zone(new WorldPoint(3418, 3484, 0), new WorldPoint(3418, 3493, 0)); + templeFloorOne = new Zone(new WorldPoint(3408, 3483, 1), new WorldPoint(3419, 3494, 1)); + templeFloorTwo = new Zone(new WorldPoint(3408, 3483, 2), new WorldPoint(3419, 3494, 2)); } @Override @@ -211,36 +166,20 @@ protected void setupRequirements() ironKey = new ItemRequirement("Iron key", ItemID.PIPKEY_IRON); blessedWaterHighlighted = new ItemRequirement("Blessed water", ItemID.BUCKET_BLESSEDWATER); blessedWaterHighlighted.setHighlightInInventory(true); - } - - @Override - protected void setupZones() - { - underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); - temple1 = new Zone(new WorldPoint(3409, 3483, 0), new WorldPoint(3411, 3494, 0)); - temple2 = new Zone(new WorldPoint(3408, 3485, 0), new WorldPoint(3408, 3486, 0)); - temple3 = new Zone(new WorldPoint(3408, 3491, 0), new WorldPoint(3408, 3492, 0)); - temple4 = new Zone(new WorldPoint(3412, 3484, 0), new WorldPoint(3415, 3493, 0)); - temple5 = new Zone(new WorldPoint(3416, 3483, 0), new WorldPoint(3417, 3494, 0)); - temple6 = new Zone(new WorldPoint(3418, 3484, 0), new WorldPoint(3418, 3493, 0)); - templeFloorOne = new Zone(new WorldPoint(3408, 3483, 1), new WorldPoint(3419, 3494, 1)); - templeFloorTwo = new Zone(new WorldPoint(3408, 3483, 2), new WorldPoint(3419, 3494, 2)); - } - public void setupConditions() - { inUnderground = new ZoneRequirement(underground); inTempleGroundFloor = new ZoneRequirement(temple1, temple2, temple3, temple4, temple5, temple6); inTempleFirstFloor = new ZoneRequirement(templeFloorOne); inTempleSecondFloor = new ZoneRequirement(templeFloorTwo); inTemple = new ZoneRequirement(temple1, temple2, temple3, temple4, temple5, temple6, templeFloorOne, templeFloorTwo); - hasGoldenOrIronKey = new Conditions(LogicType.OR, goldenKey, ironKey); + hasGoldenOrIronKey = or(goldenKey, ironKey); } + public void setupSteps() { - talkToRoald = new NpcStep(this, NpcID.KING_ROALD_CUTSCENE, new WorldPoint(3222, 3473, 0), "Speak to King Roald in Varrock Castle."); + talkToRoald = new NpcStep(this, NpcID.KING_ROALD, new WorldPoint(3222, 3473, 0), "Speak to King Roald in Varrock Castle."); talkToRoald.addDialogStep("I'm looking for a quest!"); talkToRoald.addDialogStep("Yes."); goToTemple = new ObjectStep(this, ObjectID.PRIESTPERILTEMPLEDOORR, new WorldPoint(3408, 3488, 0), @@ -248,13 +187,15 @@ public void setupSteps() goToTemple.addDialogSteps("I'll get going.", "Roald sent me to check on Drezel.", "Sure. I'm a helpful person!"); goDownToDog = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Go down the ladder north of the temple."); goDownToDog.addDialogStep("Yes."); - ((ObjectStep) (goDownToDog)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + goDownToDog.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); killTheDog = new NpcStep(this, NpcID.PRIESTPERIL_GUARDIAN_MODEL, new WorldPoint(3405, 9901, 0), "Kill the Temple Guardian (level 30). It is immune to magic so you will need to use either ranged or melee."); + killTheDog.addSubSteps(goDownToDog); climbUpAfterKillingDog = new ObjectStep(this, ObjectID.LADDER_FROM_CELLAR, new WorldPoint(3405, 9907, 0), "Climb back up the ladder and return to King Roald."); - returnToKingRoald = new NpcStep(this, NpcID.KING_ROALD_CUTSCENE, new WorldPoint(3222, 3473, 0), + returnToKingRoald = new NpcStep(this, NpcID.KING_ROALD, new WorldPoint(3222, 3473, 0), "Return to King Roald."); + returnToKingRoald.addDialogStep("About that job I'm doing..."); returnToKingRoald.addSubSteps(climbUpAfterKillingDog); returnToTemple = new ObjectStep(this, ObjectID.PRIESTPERILTEMPLEDOORR, new WorldPoint(3408, 3488, 0), @@ -270,13 +211,13 @@ public void setupSteps() fillBucket = new ObjectStep(this, ObjectID.PRIESTPERIL_WELL, new WorldPoint(3423, 9890, 0), "Use the bucket on the well in the central room.", bucketHighlighted); fillBucket.addIcon(ItemID.BUCKET_EMPTY); - useKeyForKey = new DetailedQuestStep(this, "Go to the central room, and study the monuments to find which has a key on it. Use the Golden Key on it.", goldenKeyHighlighted); + useKeyForKey = new DetailedQuestStep(this, new WorldPoint(3421, 9888, 0), "Go to the central room, and study the monuments to find which has a key on it. Use the Golden Key on it.", goldenKeyHighlighted); goDownToFloorOneTemple = new ObjectStep(this, ObjectID.LADDERTOP, new WorldPoint(3410, 3485, 2), "Go down to the underground of the temple.", bucket); - goDownToGroundFloorTemple = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 0), "Go down to the underground of the temple.", bucket); + goDownToGroundFloorTemple = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 1), "Go down to the underground of the temple.", bucket); enterUnderground = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Go down to the underground of the temple.", bucket); enterUnderground.addSubSteps(goDownToFloorOneTemple, goDownToGroundFloorTemple); - ((ObjectStep) (enterUnderground)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + enterUnderground.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); goUpWithWaterToSurface = new ObjectStep(this, ObjectID.LADDER_FROM_CELLAR, new WorldPoint(3405, 9907, 0), "Go back up to the top floor of the temple."); @@ -294,9 +235,9 @@ public void setupSteps() talkToDrezelAfterFreeing = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3418, 3489, 2), "Talk to Drezel again."); goDownToFloorOneAfterFreeing = new ObjectStep(this, ObjectID.LADDERTOP, new WorldPoint(3410, 3485, 2), "Go down to the underground of the temple.", lotsOfRuneEssence); - goDownToGroundFloorAfterFreeing = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 0), "Go down to the underground of the temple.", lotsOfRuneEssence); + goDownToGroundFloorAfterFreeing = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 1), "Go down to the underground of the temple.", lotsOfRuneEssence); enterUndergroundAfterFreeing = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Go down to the underground of the temple.", lotsOfRuneEssence); - ((ObjectStep) (enterUndergroundAfterFreeing)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + enterUndergroundAfterFreeing.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); talkToDrezelUnderground = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Talk to Drezel in the east of the underground temple area.", lotsOfRuneEssence); talkToDrezelUnderground.addSubSteps(goDownToFloorOneAfterFreeing, goDownToGroundFloorAfterFreeing, enterUndergroundAfterFreeing); @@ -304,28 +245,150 @@ public void setupSteps() } @Override - public List getItemRecommended() + public Map loadSteps() { - ArrayList reqs = new ArrayList<>(); - reqs.add(varrockTeleport); - reqs.add(runePouches); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToRoald); + steps.put(1, goToTemple); + + var goDownAndKillDog = new ConditionalStep(this, goDownToDog); + goDownAndKillDog.addStep(inUnderground, killTheDog); + + steps.put(2, goDownAndKillDog); - return reqs; + var reportKillingDog = new ConditionalStep(this, returnToKingRoald); + reportKillingDog.addStep(inUnderground, climbUpAfterKillingDog); + steps.put(3, reportKillingDog); + + var goTalkToDrezel = new ConditionalStep(this, returnToTemple); + goTalkToDrezel.addStep(and(hasGoldenOrIronKey, inTempleSecondFloor), talkToDrezel); + goTalkToDrezel.addStep(and(hasGoldenOrIronKey, inTempleFirstFloor), goUpToFloorTwoTemple); + goTalkToDrezel.addStep(and(hasGoldenOrIronKey, inTempleGroundFloor), goUpToFloorOneTemple); + goTalkToDrezel.addStep(inTemple, killMonk); + steps.put(4, goTalkToDrezel); + + var goGetKey = new ConditionalStep(this, returnToTemple); + goGetKey.addStep(and(ironKey, murkyWater, inTempleSecondFloor), openDoor); + goGetKey.addStep(and(ironKey, murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); + goGetKey.addStep(and(ironKey, murkyWater, inUnderground), goUpWithWaterToSurface); + goGetKey.addStep(and(ironKey, murkyWater), goUpWithWaterToFirstFloor); + goGetKey.addStep(and(ironKey, inUnderground), fillBucket); + goGetKey.addStep(and(hasGoldenOrIronKey, inUnderground), useKeyForKey); + goGetKey.addStep(and(hasGoldenOrIronKey, inTempleSecondFloor), goDownToFloorOneTemple); + goGetKey.addStep(and(hasGoldenOrIronKey, inTempleFirstFloor), goDownToGroundFloorTemple); + goGetKey.addStep(hasGoldenOrIronKey, enterUnderground); + goGetKey.addStep(inTemple, killMonk); + steps.put(5, goGetKey); + + var goGetWater = new ConditionalStep(this, enterUnderground); + goGetWater.addStep(and(blessedWaterHighlighted, inTempleSecondFloor), useBlessedWater); + goGetWater.addStep(and(murkyWater, inTempleSecondFloor), blessWater); + goGetWater.addStep(and(murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); + goGetWater.addStep(and(murkyWater, inUnderground), goUpWithWaterToSurface); + goGetWater.addStep(murkyWater, goUpWithWaterToFirstFloor); + goGetWater.addStep(inUnderground, fillBucket); + goGetWater.addStep(inTempleSecondFloor, goDownToFloorOneTemple); + goGetWater.addStep(inTempleFirstFloor, goDownToGroundFloorTemple); + steps.put(6, goGetWater); + + var goTalkToDrezelAfterFreeing = new ConditionalStep(this, goUpWithWaterToFirstFloor); + goTalkToDrezelAfterFreeing.addStep(inTempleSecondFloor, talkToDrezelAfterFreeing); + goTalkToDrezelAfterFreeing.addStep(inTempleFirstFloor, goUpWithWaterToSecondFloor); + steps.put(7, goTalkToDrezelAfterFreeing); + + var goDownToDrezel = new ConditionalStep(this, enterUndergroundAfterFreeing); + goDownToDrezel.addStep(inUnderground, talkToDrezelUnderground); + goDownToDrezel.addStep(inTempleFirstFloor, goDownToGroundFloorAfterFreeing); + goDownToDrezel.addStep(inTempleSecondFloor, goDownToFloorOneAfterFreeing); + steps.put(8, goDownToDrezel); + steps.put(9, goDownToDrezel); + + steps.put(10, bringDrezelEssence); + steps.put(11, bringDrezelEssence); + steps.put(12, bringDrezelEssence); + steps.put(13, bringDrezelEssence); + steps.put(14, bringDrezelEssence); + steps.put(15, bringDrezelEssence); + steps.put(16, bringDrezelEssence); + steps.put(17, bringDrezelEssence); + steps.put(18, bringDrezelEssence); + steps.put(19, bringDrezelEssence); + steps.put(20, bringDrezelEssence); + steps.put(21, bringDrezelEssence); + steps.put(22, bringDrezelEssence); + steps.put(23, bringDrezelEssence); + steps.put(24, bringDrezelEssence); + steps.put(25, bringDrezelEssence); + steps.put(26, bringDrezelEssence); + steps.put(27, bringDrezelEssence); + steps.put(28, bringDrezelEssence); + steps.put(29, bringDrezelEssence); + steps.put(30, bringDrezelEssence); + steps.put(31, bringDrezelEssence); + steps.put(32, bringDrezelEssence); + steps.put(33, bringDrezelEssence); + steps.put(34, bringDrezelEssence); + steps.put(35, bringDrezelEssence); + steps.put(36, bringDrezelEssence); + steps.put(37, bringDrezelEssence); + steps.put(38, bringDrezelEssence); + steps.put(39, bringDrezelEssence); + steps.put(40, bringDrezelEssence); + steps.put(41, bringDrezelEssence); + steps.put(42, bringDrezelEssence); + steps.put(43, bringDrezelEssence); + steps.put(44, bringDrezelEssence); + steps.put(45, bringDrezelEssence); + steps.put(46, bringDrezelEssence); + steps.put(47, bringDrezelEssence); + steps.put(48, bringDrezelEssence); + steps.put(49, bringDrezelEssence); + steps.put(50, bringDrezelEssence); + steps.put(51, bringDrezelEssence); + steps.put(52, bringDrezelEssence); + steps.put(53, bringDrezelEssence); + steps.put(54, bringDrezelEssence); + steps.put(55, bringDrezelEssence); + steps.put(56, bringDrezelEssence); + steps.put(57, bringDrezelEssence); + steps.put(58, bringDrezelEssence); + steps.put(59, bringDrezelEssence); + // There is a 60th step before the final 61, but the 'Quest Completed!' message pops up prior to it + + return steps; } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(runeEssence); - reqs.add(bucket); - return reqs; + return List.of( + runeEssence, + bucket + ); } + @Override + public List getItemRecommended() + { + return List.of( + weaponAndArmour, + varrockTeleport, + runePouches + ); + } + + @Override public List getCombatRequirements() { - return Arrays.asList("Temple Guardian (level 30). You cannot use Magic. Rings of recoil will not award the kill.", "Monk of Zamorak (level 30)"); + return List.of( + "Temple Guardian (level 30). You cannot use Magic. Rings of recoil will not award the kill.", + "Monk of Zamorak (level 30)" + ); } @Override @@ -337,31 +400,75 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.PRAYER, 1406)); + return List.of( + new ExperienceReward(Skill.PRAYER, 1406) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Wolfbane Dagger", ItemID.DAGGER_WOLFBANE, 1)); + return List.of( + new ItemReward("Wolfbane Dagger", ItemID.DAGGER_WOLFBANE, 1) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Access to Canifis and Morytania")); + return List.of( + new UnlockReward("Access to Canifis and Morytania") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Start the quest", Collections.singletonList(talkToRoald))); - allSteps.add(new PanelDetails("Go to the temple", Arrays.asList(goToTemple, killTheDog, returnToKingRoald), weaponAndArmour)); - allSteps.add(new PanelDetails("Return to the temple", Arrays.asList(returnToTemple, killMonk, talkToDrezel), weaponAndArmour, bucket, lotsOfRuneEssence)); - allSteps.add(new PanelDetails("Freeing Drezel", Arrays.asList(enterUnderground, useKeyForKey, fillBucket, goUpWithWaterToSecondFloor, openDoor, blessWater, useBlessedWater, talkToDrezelAfterFreeing), weaponAndArmour, bucket, lotsOfRuneEssence)); - allSteps.add(new PanelDetails("Curing the Salve", Arrays.asList(talkToDrezelUnderground, bringDrezelEssence), runeEssence)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Start the quest", List.of( + talkToRoald + ))); + + sections.add(new PanelDetails("Go to the temple", List.of( + goToTemple, + killTheDog, + returnToKingRoald + ), List.of( + weaponAndArmour + ))); + + sections.add(new PanelDetails("Return to the temple", List.of( + returnToTemple, + killMonk, + talkToDrezel + ), List.of( + weaponAndArmour, + bucket, + lotsOfRuneEssence + ))); + + sections.add(new PanelDetails("Freeing Drezel", List.of( + enterUnderground, + useKeyForKey, + fillBucket, + goUpWithWaterToSecondFloor, + openDoor, + blessWater, + useBlessedWater, + talkToDrezelAfterFreeing + ), List.of( + weaponAndArmour, + bucket, + lotsOfRuneEssence + ))); + + sections.add(new PanelDetails("Curing the Salve", List.of( + talkToDrezelUnderground, bringDrezelEssence + ), List.of( + runeEssence + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java index df394cbc6c9..3a8b00e831b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java @@ -30,7 +30,6 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -51,19 +50,18 @@ public class PrinceAliRescue extends BasicQuestHelper { //Items Required - ItemRequirement softClay, ballsOfWool3, yellowDye, redberries, ashes, bucketOfWater, potOfFlour, bronzeBar, pinkSkirt, beers3, rope, coins100, wig, dyedWig, paste, keyMould, key, + ItemRequirement softClay, ballsOfWool3, yellowDye, redberries, ashes, bucketOfWater, potOfFlour, bronzeBar, pinkSkirt, beers3, rope, coins100, wig, dyedWig, paste, keyPrint, key, ropeReqs, yellowDyeReqs, ropeHighlighted, keyHighlighted; //Items Recommended ItemRequirement glory; - Requirement hasOrGivenKeyMould, inCell, givenKeyMould, hasWigPasteAndKey; + Requirement hasOrUsedKeyPrint, inCell, hasWigPasteAndKey; + RuneliteRequirement madeKey; - RuneliteRequirement madeMould; + QuestStep talkToHassan, talkToOsman, talkToNed, talkToAggie, dyeWig, talkToKeli, makeKey, talkToLeela, reobtainKey, talkToJoe, useRopeOnKeli, useKeyOnDoor, talkToAli, returnToHassan; - QuestStep talkToHassan, talkToOsman, talkToNed, talkToAggie, dyeWig, talkToKeli, bringImprintToOsman, talkToLeela, talkToJoe, useRopeOnKeli, useKeyOnDoor, talkToAli, returnToHassan; - - ConditionalStep makeDyedWig, makePaste, makeKeyMould, getKey; + ConditionalStep makeDyedWig, makePaste, makeKeyPrint, getKey; //Zones Zone cell; @@ -86,39 +84,38 @@ public Map loadSteps() makePaste = new ConditionalStep(this, talkToAggie); makePaste.setLockingCondition(paste.alsoCheckBank()); - makeKeyMould = new ConditionalStep(this, talkToKeli); - makeKeyMould.setLockingCondition(hasOrGivenKeyMould); + makeKeyPrint = new ConditionalStep(this, talkToKeli); + makeKeyPrint.setLockingCondition(hasOrUsedKeyPrint); - getKey = new ConditionalStep(this, bringImprintToOsman); - getKey.setLockingCondition(givenKeyMould); + getKey = new ConditionalStep(this, makeKey); ConditionalStep prepareToSaveAli = new ConditionalStep(this, makeDyedWig); - prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), - new Conditions(LogicType.OR, madeMould, givenKeyMould)), talkToLeela); - prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), hasOrGivenKeyMould), getKey); - prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank()), makeKeyMould); + prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), madeKey), talkToLeela); + prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), hasOrUsedKeyPrint), getKey); + prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank()), makeKeyPrint); prepareToSaveAli.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(20, prepareToSaveAli); - ConditionalStep getJoeDrunk = new ConditionalStep(this, makeDyedWig); + ConditionalStep reprepareToSaveAli = new ConditionalStep(this, makeDyedWig); + reprepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank()), reobtainKey); + reprepareToSaveAli.addStep(dyedWig.alsoCheckBank(), makePaste); + + ConditionalStep getJoeDrunk = new ConditionalStep(this, reprepareToSaveAli); getJoeDrunk.addStep(hasWigPasteAndKey, talkToJoe); - getJoeDrunk.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(30, getJoeDrunk); steps.put(31, getJoeDrunk); steps.put(32, getJoeDrunk); steps.put(33, getJoeDrunk); - ConditionalStep tieUpKeli = new ConditionalStep(this, makeDyedWig); + ConditionalStep tieUpKeli = new ConditionalStep(this, reprepareToSaveAli); tieUpKeli.addStep(hasWigPasteAndKey, useRopeOnKeli); - tieUpKeli.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(40, tieUpKeli); - ConditionalStep freeAli = new ConditionalStep(this, makeDyedWig); + ConditionalStep freeAli = new ConditionalStep(this, reprepareToSaveAli); freeAli.addStep(new Conditions(hasWigPasteAndKey, inCell), talkToAli); freeAli.addStep(hasWigPasteAndKey, useKeyOnDoor); - freeAli.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(50, freeAli); steps.put(100, returnToHassan); @@ -150,7 +147,7 @@ protected void setupRequirements() wig.setHighlightInInventory(true); dyedWig = new ItemRequirement("Wig (dyed)", ItemID.BLONDWIG); paste = new ItemRequirement("Paste", ItemID.SKINPASTE); - keyMould = new ItemRequirement("Key print", ItemID.KEYPRINT); + keyPrint = new ItemRequirement("Key print", ItemID.KEYPRINT); key = new ItemRequirement("Bronze key", ItemID.PRINCESKEY); key.setTooltip("You can get another from Leela for 15 coins"); @@ -164,17 +161,15 @@ public void setupConditions() { inCell = new ZoneRequirement(cell); hasWigPasteAndKey = new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), key.alsoCheckBank()); - givenKeyMould = new Conditions(true, LogicType.OR, // TODO quest journal widget text outdated - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I have duplicated a key, I need to get it from"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I got a duplicated cell door key"), - new WidgetTextRequirement(11, 2, true, "You give Osman the imprint along with a bronze bar."), - new DialogRequirement("I'll use this to have a copy of the key made. I'll send it to Leela once it's ready."), - new DialogRequirement("I think I have everything needed."), + + var usedKeyPrint = new Conditions(true, LogicType.OR, + new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "made a copy of the key to his cell"), key.alsoCheckBank()); - madeMould = new RuneliteRequirement(getConfigManager(), "princealikeymouldhandedin", "true", givenKeyMould); - madeMould.initWithValue("false"); - hasOrGivenKeyMould = new Conditions(LogicType.OR, keyMould, givenKeyMould, key.alsoCheckBank()); + madeKey = new RuneliteRequirement(getConfigManager(), "princealikeymouldhandedin", "true", usedKeyPrint); + madeKey.initWithValue("false"); + + hasOrUsedKeyPrint = new Conditions(LogicType.OR, keyPrint, madeKey); } @Override @@ -197,15 +192,17 @@ public void setupSteps() talkToAggie = new NpcStep(this, NpcID.AGGIE_1OP, new WorldPoint(3086, 3257, 0), "Talk to Aggie in Draynor Village to get some paste.", redberries, ashes, potOfFlour, bucketOfWater); talkToAggie.addDialogStep("Can you make skin paste?"); talkToAggie.addDialogStep("Yes please. Mix me some skin paste."); - talkToKeli = new NpcStep(this, NpcID.LADY_KELI_VIS, new WorldPoint(3127, 3244, 0), "Talk to Keli in the jail east of Draynor Village. If you've already made the key mould, open the quest journal to re-sync.", softClay); + talkToKeli = new NpcStep(this, NpcID.LADY_KELI_VIS, new WorldPoint(3127, 3244, 0), "Talk to Keli in the jail east of Draynor Village. If you've already made the key print, open the quest journal to re-sync.", softClay); talkToKeli.addDialogStep("Heard of you? You're famous in Gielinor!"); talkToKeli.addDialogStep("What's your latest plan then?"); talkToKeli.addDialogStep("How do you know someone won't try to free him?"); talkToKeli.addDialogStep("Could I see the key please?"); talkToKeli.addDialogStep("Could I touch the key for a moment please?"); - bringImprintToOsman = new NpcStep(this, NpcID.OSMAN, new WorldPoint(3285, 3179, 0), "Bring the key print to Osman north of the Al Kharid Palace. If " + - "you already have, open the quest journal to re-sync.", keyMould, bronzeBar); + makeKey = new ObjectStep(this, ObjectID.FAI_FALADOR_FURNACE, new WorldPoint(3227, 3256, 0), "Use the key print on any furnace with a bronze bar in your inventory to make a key.", keyPrint.highlighted(), bronzeBar); talkToLeela = new NpcStep(this, NpcID.LEELA, new WorldPoint(3113, 3262, 0), "Talk to Leela east of Draynor Village.", beers3, dyedWig, paste, rope, pinkSkirt); + reobtainKey = new NpcStep(this, NpcID.LEELA, new WorldPoint(3113, 3262, 0), "Talk to Leela east of Draynor Village for another key. It'll cost 15gp.", coins100.quantity(15)); + talkToLeela.addSubSteps(reobtainKey); + talkToJoe = new NpcStep(this, NpcID.JOE_VIS, new WorldPoint(3124, 3245, 0), "Bring everything to the jail and give Joe there three beers.", beers3, key, dyedWig, paste, rope, pinkSkirt); talkToJoe.addDialogStep("I have some beer here. Fancy one?"); useRopeOnKeli = new NpcStep(this, NpcID.LADY_KELI_VIS, new WorldPoint(3127, 3244, 0), "Use rope on Keli.", ropeHighlighted); @@ -287,11 +284,11 @@ public List getPanels() makePastePanel.setLockingStep(makePaste); allSteps.add(makePastePanel); - PanelDetails makeKeyMouldPanel = new PanelDetails("Make a key mould", Collections.singletonList(talkToKeli), softClay); - makeKeyMouldPanel.setLockingStep(makeKeyMould); - allSteps.add(makeKeyMouldPanel); + PanelDetails makeKeyPrintPanel = new PanelDetails("Make a key print", Collections.singletonList(talkToKeli), softClay); + makeKeyPrintPanel.setLockingStep(makeKeyPrint); + allSteps.add(makeKeyPrintPanel); - PanelDetails getKeyPanel = new PanelDetails("Make the key", Collections.singletonList(bringImprintToOsman), bronzeBar, keyMould); + PanelDetails getKeyPanel = new PanelDetails("Make the key", Collections.singletonList(makeKey), bronzeBar, keyPrint); getKeyPanel.setLockingStep(getKey); allSteps.add(getKeyPanel); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java index c625f54b27a..6e21173da61 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java @@ -43,7 +43,18 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PortTaskStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.client.plugins.microbot.questhelper.steps.SailStep; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -51,10 +62,9 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class PryingTimes extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java index 544bf9cd527..ab58653f453 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java @@ -55,7 +55,11 @@ import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; import java.util.*; @@ -211,7 +215,7 @@ protected void setupRequirements() logs = new ItemRequirement("Logs", ItemID.LOGS); tinderbox = new ItemRequirement("Tinderbox", ItemID.TINDERBOX).isNotConsumed(); lightSource = new ItemRequirement("Light source", ItemCollections.LIGHT_SOURCES).isNotConsumed(); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).isNotConsumed(); dustyKey.canBeObtainedDuringQuest(); mirrorShield = new ItemRequirement("Mirror shield", ItemID.SLAYER_MIRROR_SHIELD).isNotConsumed(); mirrorShield.addAlternates(ItemID.VIKINGEXILE_V_SHIELD, ItemID.V_SHIELD); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java index 40a971a3ed7..72e8d43bac5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java index 6200b6aba18..9592e7bf523 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java @@ -144,7 +144,7 @@ protected void setupRequirements() asgoldianAle4 = new ItemRequirement("Asgoldian ale", ItemID.HUNDRED_DWARF_ASGARNIAN_ALE, 4); // Recommended - taverleyTeleport = new ItemRequirement("Teleport to taverley", ItemID.NZONE_TELETAB_TAVERLEY); + taverleyTeleport = new ItemRequirement("Teleport to Taverley", ItemID.NZONE_TELETAB_TAVERLEY); taverleyTeleport.addAlternates(ItemCollections.COMBAT_BRACELETS); teleportFalador = new ItemRequirement("Teleport to Falador", ItemID.POH_TABLET_FALADORTELEPORT); teleportLumbridge = new ItemRequirement("Teleport to Lumbridge", ItemID.POH_TABLET_LUMBRIDGETELEPORT); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java index af346440f17..eb088118a03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java @@ -61,7 +61,7 @@ public class RFDPiratePete extends BasicQuestHelper { ItemRequirement combatGear, pestleHighlighted, rawCodHighlighted, knifeHighlighted, breadHighlighted, divingAparatus, divingHelmet, fishBowl, bronzeWire3, needle, fishCake, fishCakeHighlighted, rocks5, mudskipperHide5, crabMeat, kelp, groundKelpHighlighted, groundCrabMeatHighlighted, kelpHighlighted, crabMeatHighlighted, - rawFishCake, groundCod, breadcrumbs; + rawFishCake, groundCod, breadcrumbs, emptySlotsX6; WeightRequirement canSwim; @@ -162,6 +162,7 @@ protected void setupRequirements() fishBowl = new ItemRequirement("Empty fishbowl", ItemID.FISHBOWL_EMPTY); bronzeWire3 = new ItemRequirement("Bronze wire", ItemID.BRONZECRAFTWIRE, 3); needle = new ItemRequirement("Needle", ItemID.NEEDLE).isNotConsumed(); + needle.setTooltip("Costume needle cannot be used as a substitute"); fishCake = new ItemRequirement("Cooked fishcake", ItemID.HUNDRED_PIRATE_FISHCAKE); fishCakeHighlighted = new ItemRequirement("Cooked fishcake", ItemID.HUNDRED_PIRATE_FISHCAKE); fishCakeHighlighted.setHighlightInInventory(true); @@ -185,6 +186,8 @@ protected void setupRequirements() groundCod = new ItemRequirement("Ground cod", ItemID.HUNDRED_PIRATE_GROUND_COD); groundCod.setTooltip("You can make this by use a pestle and mortar on a raw cod"); breadcrumbs = new ItemRequirement("Breadcrumbs", ItemID.HUNDRED_PIRATE_BREADCRUMBS); + emptySlotsX6 = new ItemRequirement("Empty inventory slots at minimum", -1, 6); + emptySlotsX6.setTooltip("Have an additional empty slot for each additional kelp beyond the minimum of 1"); combatGear = new ItemRequirement("Combat gear", -1, -1); combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); @@ -341,7 +344,7 @@ public List getPanels() { List allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Starting off", Arrays.asList(inspectPete, talkToCook, talkToMurphy, talkToMurphyAgain), fishBowl)); - allSteps.add(new PanelDetails("Get Crab and Kelp", Arrays.asList(goDiving, pickKelp, talkToNung, pickUpRocks, enterCave, killMudksippers5, returnToNung, giveNungWire, killCrab, climbAnchor), divingHelmet, divingAparatus, bronzeWire3, needle)); + allSteps.add(new PanelDetails("Get Crab and Kelp", Arrays.asList(goDiving, pickKelp, talkToNung, pickUpRocks, enterCave, killMudksippers5, returnToNung, giveNungWire, killCrab, climbAnchor), Arrays.asList(divingHelmet, divingAparatus, bronzeWire3, needle, emptySlotsX6, canSwim), Collections.singletonList(combatGear))); allSteps.add(new PanelDetails("Saving Pete", Arrays.asList(grindCrab, grindKelp, usePestleOnCod, useKnifeOnBread, talkToCookAgain, useCrabOnKelp, cookCake, useCakeOnPete), pestleHighlighted, knifeHighlighted, rawCodHighlighted, breadHighlighted, crabMeat, kelp)); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java index edfcb62abc9..74ec05479d6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java @@ -220,7 +220,7 @@ public void setupSteps() getToad.addSubSteps(fillUpBellows); getRock = new ObjectStep(this, ObjectID.SWAMP_ROCK1, new WorldPoint(2567, 2960, 0), "Mine a pile of rocks near the Feldip Hills Fairy Ring for a rock.", pickaxe); useBellowOnToadInInv = new DetailedQuestStep(this, "Use the bellows on your toad with a ball of wool in your inventory.", ogreBellowsFilled, toad, ballOfWool); - dropBalloonToad = new DetailedQuestStep(this, new WorldPoint(2593, 2964, 0), "Drop the balloon toad near a swamp and wait for a Jubbly to arrive.", toadReady, ogreBowAndArrows); + dropBalloonToad = new DetailedQuestStep(this, new WorldPoint(2635, 2965, 0), "Drop the balloon toad in the dark area south of Rantz's cave and wait for a Jubbly to arrive.", toadReady, ogreBowAndArrows); killJubbly = new NpcStep(this, NpcID._100_JUBBLY_BIRD, "Kill then pluck jubbly.", ogreBowAndArrows); pickUpRawJubbly = new ItemStep(this, "Pick up the raw jubbly.", rawJubbly); lootJubbly = new NpcStep(this, NpcID._100_JUBBLY_BIRD_DEAD, "Pluck the jubbly's carcass."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java index 5a8f81a6bf8..292f8e9a953 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java @@ -28,43 +28,25 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; import net.runelite.api.events.GameTick; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; -import java.awt.*; -import java.util.HashMap; -import java.util.Map; - public class DoorPuzzle extends QuestStep { + private final HashMap highlightButtons = new HashMap<>(); + private final HashMap distance = new HashMap<>(); private Character ENTRY_ONE; private Character ENTRY_TWO; private Character ENTRY_THREE; private Character ENTRY_FOUR; - private final int SLOT_ONE = 43; - private final int SLOT_TWO = 44; - private final int SLOT_THREE = 45; - private final int SLOT_FOUR = 46; - - private final int ARROW_ONE_LEFT = 47; - private final int ARROW_ONE_RIGHT = 48; - private final int ARROW_TWO_LEFT = 49; - private final int ARROW_TWO_RIGHT = 50; - private final int ARROW_THREE_LEFT = 51; - private final int ARROW_THREE_RIGHT = 52; - private final int ARROW_FOUR_LEFT = 53; - private final int ARROW_FOUR_RIGHT = 54; - - private final int COMPLETE = 56; - - private final HashMap highlightButtons = new HashMap<>(); - private final HashMap distance = new HashMap<>(); - public DoorPuzzle(QuestHelper questHelper, String word) { super(questHelper, "Click the highlighted arrows to move the slots to the solution."); @@ -73,10 +55,10 @@ public DoorPuzzle(QuestHelper questHelper, String word) ENTRY_THREE = word.charAt(2); ENTRY_FOUR = word.charAt(3); - highlightButtons.put(1, ARROW_ONE_RIGHT); - highlightButtons.put(2, ARROW_TWO_RIGHT); - highlightButtons.put(3, ARROW_THREE_RIGHT); - highlightButtons.put(4, ARROW_FOUR_RIGHT); + highlightButtons.put(1, InterfaceID.RdCombolock.RDA_RIGHT); + highlightButtons.put(2, InterfaceID.RdCombolock.RDB_RIGHT); + highlightButtons.put(3, InterfaceID.RdCombolock.RDC_RIGHT); + highlightButtons.put(4, InterfaceID.RdCombolock.RDD_RIGHT); distance.put(1, 0); distance.put(2, 0); @@ -84,13 +66,23 @@ public DoorPuzzle(QuestHelper questHelper, String word) distance.put(4, 0); } + @Override + public void startUp() + { + super.startUp(); + + // Recalculate once when the step starts up to ensure highlights aren't wrong for a tick + updateSolvedPositionState(); + } + public void updateWord(String word) { ENTRY_ONE = word.charAt(0); ENTRY_TWO = word.charAt(1); - ENTRY_THREE = word.charAt(2); - ENTRY_FOUR = word.charAt(3); + ENTRY_THREE = word.charAt(2); + ENTRY_FOUR = word.charAt(3); setText("Click the highlighted arrows to move the slots to the solution. The answer is " + word + "."); + updateSolvedPositionState(); } @Subscribe @@ -101,19 +93,20 @@ public void onGameTick(GameTick gameTick) private void updateSolvedPositionState() { - highlightButtons.replace(1, matchStateToSolution(SLOT_ONE, ENTRY_ONE, ARROW_ONE_RIGHT, ARROW_ONE_LEFT)); - highlightButtons.replace(2, matchStateToSolution(SLOT_TWO, ENTRY_TWO, ARROW_TWO_RIGHT, ARROW_TWO_LEFT)); - highlightButtons.replace(3, matchStateToSolution(SLOT_THREE, ENTRY_THREE, ARROW_THREE_RIGHT, ARROW_THREE_LEFT)); - highlightButtons.replace(4, matchStateToSolution(SLOT_FOUR, ENTRY_FOUR, ARROW_FOUR_RIGHT, ARROW_FOUR_LEFT)); - distance.replace(1, matchStateToDistance(SLOT_ONE, ENTRY_ONE)); - distance.replace(2, matchStateToDistance(SLOT_TWO, ENTRY_TWO)); - distance.replace(3, matchStateToDistance(SLOT_THREE, ENTRY_THREE)); - distance.replace(4, matchStateToDistance(SLOT_FOUR, ENTRY_FOUR)); + highlightButtons.replace(1, matchStateToSolution(InterfaceID.RdCombolock.RDA, ENTRY_ONE, InterfaceID.RdCombolock.RDA_RIGHT, InterfaceID.RdCombolock.RDA_LEFT)); + highlightButtons.replace(2, matchStateToSolution(InterfaceID.RdCombolock.RDB, ENTRY_TWO, InterfaceID.RdCombolock.RDB_RIGHT, InterfaceID.RdCombolock.RDB_LEFT)); + highlightButtons.replace(3, matchStateToSolution(InterfaceID.RdCombolock.RDC, ENTRY_THREE, InterfaceID.RdCombolock.RDC_RIGHT, InterfaceID.RdCombolock.RDC_LEFT)); + highlightButtons.replace(4, matchStateToSolution(InterfaceID.RdCombolock.RDD, ENTRY_FOUR, InterfaceID.RdCombolock.RDD_RIGHT, InterfaceID.RdCombolock.RDD_LEFT)); + + distance.replace(1, matchStateToDistance(InterfaceID.RdCombolock.RDA, ENTRY_ONE)); + distance.replace(2, matchStateToDistance(InterfaceID.RdCombolock.RDB, ENTRY_TWO)); + distance.replace(3, matchStateToDistance(InterfaceID.RdCombolock.RDC, ENTRY_THREE)); + distance.replace(4, matchStateToDistance(InterfaceID.RdCombolock.RDD, ENTRY_FOUR)); if (highlightButtons.get(1) + highlightButtons.get(2) + highlightButtons.get(3) + highlightButtons.get(4) == 0) { - highlightButtons.put(5, COMPLETE); + highlightButtons.put(5, InterfaceID.RdCombolock.RDENTER); } else { @@ -123,19 +116,28 @@ private void updateSolvedPositionState() private int matchStateToSolution(int slot, Character target, int arrowRightId, int arrowLeftId) { - Widget widget = client.getWidget(InterfaceID.RD_COMBOLOCK, slot); - if (widget == null) return 0; + Widget widget = client.getWidget(slot); + if (widget == null) + { + return 0; + } char current = widget.getText().charAt(0); int currentPos = (int) current - (int) 'A'; int id = Math.floorMod(currentPos - target, 26) < Math.floorMod(target - currentPos, 26) ? arrowRightId : arrowLeftId; - if (current != target) return id; + if (current != target) + { + return id; + } return 0; } private int matchStateToDistance(int slot, Character target) { - Widget widget = client.getWidget(InterfaceID.RD_COMBOLOCK, slot); - if (widget == null) return 0; + Widget widget = client.getWidget(slot); + if (widget == null) + { + return 0; + } char current = widget.getText().charAt(0); return Math.min(Math.floorMod(current - target, 26), Math.floorMod(target - current, 26)); } @@ -151,7 +153,7 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) continue; } - Widget widget = client.getWidget(InterfaceID.RD_COMBOLOCK, entry.getValue()); + Widget widget = client.getWidget(entry.getValue()); if (widget != null) { graphics.setColor(new Color(questHelper.getConfig().targetOverlayColor().getRed(), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java index 8f3713f1f6b..522c6f0fa33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java @@ -25,113 +25,70 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; -import com.google.inject.Inject; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.DetailedOwnerStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.Client; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.VarbitChanged; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class LadyTableStep extends DetailedOwnerStep +public class LadyTableStep extends ObjectStep { - @Inject - protected Client client; + private final Statue[] statues = new Statue[]{ + new Statue("Unknown", new WorldPoint(0, 0, 0)), + new Statue("Bronze Halberd", new WorldPoint(2452, 4976, 0)), + new Statue("Silver Halberd", new WorldPoint(2452, 4979, 0)), + new Statue("Gold Halberd", new WorldPoint(2452, 4982, 0)), - private Statue[] statues; + new Statue("Bronze 2H", new WorldPoint(2450, 4976, 0)), + new Statue("Silver 2H", new WorldPoint(2450, 4979, 0)), + new Statue("Gold 2H", new WorldPoint(2450, 4982, 0)), - private ObjectStep clickMissingStatue, leaveRoom; + new Statue("Gold Mace", new WorldPoint(2456, 4982, 0)), + new Statue("Silver Mace", new WorldPoint(2456, 4979, 0)), + new Statue("Bronze mace", new WorldPoint(2456, 4976, 0)), - VarbitRequirement finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM2_COMPLETE, 1); + new Statue("Bronze axe", new WorldPoint(2454, 4976, 0)), + new Statue("Silver axe", new WorldPoint(2454, 4979, 0)), + new Statue("Gold axe", new WorldPoint(2454, 4972, 0)) + }; public LadyTableStep(QuestHelper questHelper, Requirement... requirements) { - super(questHelper, requirements); + super(questHelper, ObjectID.RD_1G, new WorldPoint(0, 0, 0), "Click the missing statue.", requirements); + + addAlternateObjects(ObjectID.RD_1S, ObjectID.RD_1B, + ObjectID.RD_2G, ObjectID.RD_2S, ObjectID.RD_2B, ObjectID.RD_3G, + ObjectID.RD_3S, ObjectID.RD_3B, ObjectID.RD_4G, ObjectID.RD_4B); } @Override public void startUp() { super.startUp(); - Statue answerStatue = statues[client.getVarbitValue(VarbitID.RD_TEMPLOCK_2)]; - clickMissingStatue.setText("Click the " + answerStatue.text + " once it appears."); - clickMissingStatue.setWorldPoint(answerStatue.point); + + var answerIndex = client.getVarbitValue(VarbitID.RD_TEMPLOCK_2); + if (answerIndex < statues.length) + { + var answerStatue = statues[answerIndex]; + setText("Click the " + answerStatue.text + " once it appears."); + setWorldPoint(answerStatue.point); + } } @Override public void onVarbitChanged(VarbitChanged varbitChanged) { super.onVarbitChanged(varbitChanged); - Statue answerStatue = statues[client.getVarbitValue(VarbitID.RD_TEMPLOCK_2)]; - clickMissingStatue.setText("Click the " + answerStatue.text + " once it appears."); - clickMissingStatue.setWorldPoint(answerStatue.point); - } - @Override - public void setupSteps() - { - statues = new Statue[]{ - new Statue("Unknown", new WorldPoint(0, 0, 0)), - new Statue("Bronze Halberd", new WorldPoint(2452, 4976, 0)), - new Statue("Silver Halberd", new WorldPoint(2452, 4979, 0)), - new Statue("Gold Halberd", new WorldPoint(2452, 4982, 0)), - - new Statue("Bronze 2H", new WorldPoint(2450, 4976, 0)), - new Statue("Silver 2H", new WorldPoint(2450, 4979, 0)), - new Statue("Gold 2H", new WorldPoint(2450, 4982, 0)), - - new Statue("Gold Mace", new WorldPoint(2456, 4982, 0)), - new Statue("Silver Mace", new WorldPoint(2456, 4979, 0)), - new Statue("Bronze mace", new WorldPoint(2456, 4976, 0)), - - new Statue("Bronze axe", new WorldPoint(2454, 4976, 0)), - new Statue("Silver axe", new WorldPoint(2454, 4979, 0)), - new Statue("Gold axe", new WorldPoint(2454, 4972, 0)) - }; - - leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM2_EXITDOOR, "Leave through the door to enter the portal and continue."); - clickMissingStatue = new ObjectStep(questHelper, 0, statues[0].point, "CLick the missing statue."); - clickMissingStatue.addAlternateObjects(ObjectID.RD_1G, ObjectID.RD_1S, ObjectID.RD_1B, - ObjectID.RD_2G, ObjectID.RD_2S, ObjectID.RD_2B, ObjectID.RD_3G, - ObjectID.RD_3S, ObjectID.RD_3B, ObjectID.RD_4G, ObjectID.RD_4B); - } - - @Override - public Collection getSteps() - { - List step = new ArrayList<>(); - - step.add(clickMissingStatue); - step.add(leaveRoom); - return step; - } - - @Override - protected void updateSteps() - { - if (finishedRoom.check(client)) + if (varbitChanged.getVarbitId() == VarbitID.RD_TEMPLOCK_2) { - startUpStep(leaveRoom); + var answerIndex = varbitChanged.getValue(); + var answerStatue = statues[answerIndex]; + setText("Click the " + answerStatue.text + " once it appears."); + setWorldPoint(answerStatue.point); } - startUpStep(clickMissingStatue); - } - - public List getPanelSteps() - { - List steps = new ArrayList<>(); - steps.add(clickMissingStatue); - steps.add(leaveRoom); - - return steps; } static class Statue diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MissCheeversStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MissCheeversStep.java new file mode 100644 index 00000000000..1b76dbd7365 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MissCheeversStep.java @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2020, Patyfatycake + * 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 LIABI`LITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; + +import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.List; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; + +@SuppressWarnings("FieldCanBeLocal") +public class MissCheeversStep extends ConditionalStep +{ + // Requirements + ItemRequirement magnet; + ItemRequirement aceticAcid; + ItemRequirement vialOfLiquid; + ItemRequirement cupricSulfate; + ItemRequirement gypsum; + ItemRequirement sodiumChloride; + ItemRequirement bronzeWire; + ItemRequirement tin; + ItemRequirement shears; + ItemRequirement chisel; + ItemRequirement nitrousOxide; + ItemRequirement tinOrePowder; + ItemRequirement cupricOrePowder; + ItemRequirement knife; + ItemRequirement metalSpade; + ItemRequirement metalSpadeHead; + ItemRequirement ashes; + ItemRequirement gypsumTin; + ItemRequirement tinKeyPrint; + ItemRequirement tinWithCupricOre; + ItemRequirement tinWithTinOre; + ItemRequirement tinWithAllOre; + ItemRequirement bronzeKey; + + VarbitRequirement hasRetrievedThreeVials; + VarbitRequirement hasSpadeHeadOnDoor; + VarbitRequirement hasCupricSulfateOnDoor; + VarbitRequirement hasVialOfLiquidOnDoor; + VarbitRequirement hasFirstDoorOpen; + VarbitRequirement hasLiquidInTin; + + // Steps + ObjectStep getMagnet; + ObjectStep getTwoVials; + ObjectStep getCupricSulfate; + ObjectStep getGypsum; + ObjectStep getSodiumChloride; + ObjectStep getWire; + ObjectStep getTin; + ObjectStep getShears; + ObjectStep getChisel; + ObjectStep getNitrousOxide; + ObjectStep getTinOrePowder; + ObjectStep getCupricOrePowder; + ObjectStep getThreeVials; + ObjectStep getKnife; + ItemStep getMetalSpade; + + // Destroying first door steps + QuestStep useSpadeOnBunsenBurner; + QuestStep useSpadeHeadOnDoor; + QuestStep useCupricSulfateOnDoor; + QuestStep useVialOfLiquidOnDoor; + QuestStep openDoor; + // Creating second door key steps + QuestStep useVialOfLiquidOnCakeTin; + QuestStep useGypsumOnTin; + QuestStep useTinOnKey; + QuestStep useCupricOrePowderOnTin; + QuestStep useTinOrePowderOnTin; + QuestStep useTinOnBunsenBurner; + QuestStep useEquipmentOnTin; + + PuzzleWrapperStep pwGetMagnet; + PuzzleWrapperStep pwGetTwoVials; + PuzzleWrapperStep pwGetCupricSulfate; + PuzzleWrapperStep pwGetGypsum; + PuzzleWrapperStep pwGetSodiumChloride; + PuzzleWrapperStep pwGetWire; + PuzzleWrapperStep pwGetTin; + PuzzleWrapperStep pwGetShears; + PuzzleWrapperStep pwGetChisel; + PuzzleWrapperStep pwGetNitrousOxide; + PuzzleWrapperStep pwGetTinOrePowder; + PuzzleWrapperStep pwGetCupricOrePowder; + PuzzleWrapperStep pwGetThreeVials; + PuzzleWrapperStep pwGetKnife; + PuzzleWrapperStep pwGetMetalSpade; + PuzzleWrapperStep pwUseSpadeOnBunsenBurner; + PuzzleWrapperStep pwUseSpadeHeadOnDoor; + PuzzleWrapperStep pwUseCupricSulfateOnDoor; + PuzzleWrapperStep pwUseVialOfLiquidOnDoor; + PuzzleWrapperStep pwOpenDoor; + PuzzleWrapperStep pwUseVialOfLiquidOnCakeTin; + PuzzleWrapperStep pwUseGypsumOnTin; + PuzzleWrapperStep pwUseTinOnKey; + PuzzleWrapperStep pwUseCupricOrePowderOnTin; + PuzzleWrapperStep pwUseTinOrePowderOnTin; + PuzzleWrapperStep pwUseTinOnBunsenBurner; + PuzzleWrapperStep pwUseEquipmentOnTin; + + public MissCheeversStep(QuestHelper questHelper, Requirement... requirements) + { + // null safety - addSteps sets the null conditional step + super(questHelper, null, requirements); + + setupRequirements(); + setupSteps(); + addSteps(); + } + + public void setupRequirements() + { + magnet = new ItemRequirement("Magnet", ItemID.RD_MAGNET); + + aceticAcid = new ItemRequirement("Acetic Acid", ItemID.RD_ACETIC_ACID); + + vialOfLiquid = new ItemRequirement(true, "Vial of Liquid", ItemID.RD_DIHYDROGEN_MONOXIDE); + vialOfLiquid.setTooltip("Take from the shelf on the north side or the south side."); + + cupricSulfate = new ItemRequirement(true, "Cupric Sulfate", ItemID.RD_CUPRIC_SULPHATE); + cupricSulfate.setTooltip("Take from the shelves on the north side"); + + gypsum = new ItemRequirement(true, "Gypsum", ItemID.RD_GYPSUM); + + sodiumChloride = new ItemRequirement("Sodium Chloride", ItemID.RD_SODIUM_CHLORIDE); + + bronzeWire = new ItemRequirement(true, "Bronze Wire", ItemID.RD_WIRE); + + tin = new ItemRequirement(true, "Tin", ItemID.RD_TIN); + // TODO set tip + + shears = new ItemRequirement("Shears", ItemID.RD_SHEARS); + + chisel = new ItemRequirement(true, "Chisel", ItemID.RD_CHISEL); + + nitrousOxide = new ItemRequirement("Nitrous Oxide", ItemID.RD_NITORUS_OXIDE); + + tinOrePowder = new ItemRequirement(true, "Tin Ore Powder", ItemID.RD_TIN_ORE_POWDER); + + cupricOrePowder = new ItemRequirement(true, "Cupric Ore Powder", ItemID.RD_COPPER_ORE_POWDER); + + knife = new ItemRequirement(true, "Knife", ItemID.RD_KNIFE); + + metalSpade = new ItemRequirement(true, "Metal Spade", ItemID.RD_METAL_SPADE); + metalSpade.setTooltip("If you are missing this item pick another up off the table."); + + metalSpadeHead = new ItemRequirement(true, "Metal Spade", ItemID.RD_METAL_SPADE_NO_HANDLE); + metalSpadeHead.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); + ashes = new ItemRequirement(true, "Ashes", ItemID.ASHES); + ashes.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); + + gypsumTin = new ItemRequirement(true, "Tin", ItemID.RD_TINFULL); + + tinKeyPrint = new ItemRequirement(true, "Tin", ItemID.RD_KEYMOULD); + + tinWithCupricOre = new ItemRequirement(true, "Tin", ItemID.RD_FULL_KEYMOULD_COPPER); + + tinWithTinOre = new ItemRequirement(true, "Tin", ItemID.RD_FULL_KEYMOULD_UNHEATED); + + tinWithAllOre = new ItemRequirement(true, "Tin", ItemID.RD_FULL_KEYMOULD_COMPLETE); + + bronzeKey = new ItemRequirement("Bronze Key", ItemID.RD_PUZZLEROOM_KEY); + + hasRetrievedThreeVials = new VarbitRequirement(VarbitID.RD_SPARE_WATER, 3); + hasSpadeHeadOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 1); + hasCupricSulfateOnDoor = new VarbitRequirement(VarbitID.RD_REACT_ON_SPADE, 1); + hasVialOfLiquidOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 2); + hasFirstDoorOpen = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 3); + + hasLiquidInTin = new VarbitRequirement(VarbitID.RD_WATER_IN_TIN, 1); + } + + private void setupSteps() + { + getMagnet = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL, "Get the magnet from the old bookshelf."); + getTwoVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_1, "Get two vials from the shelves"); + getTwoVials.addDialogStep("Take both vials."); + getCupricSulfate = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_2, "Get Cupric Sulfate from the shelves."); + getCupricSulfate.addDialogStep("YES"); + getGypsum = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_3, "Get Gypsum from the shelves."); + getGypsum.addDialogStep("YES"); + getSodiumChloride = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_4, "Get Sodium Chloride from the shelves."); + getSodiumChloride.addDialogStep("YES"); + getWire = new ObjectStep(questHelper, ObjectID.RD_SMALL_CRATES, new WorldPoint(2475, 4943, 0), "Get Wire from the crate."); + getTin = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATE, new WorldPoint(2476, 4943, 0), "Get Tin from the crate."); + getShears = new ObjectStep(questHelper, ObjectID.RD_CHEST_CLOSED, "Get Shears from the chest."); + getShears.addAlternateObjects(ObjectID.RD_CHEST_OPEN); + getChisel = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATES, new WorldPoint(2476, 4937, 0), "Get a Chisel from the crate."); + getNitrousOxide = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_5, "Get Nitrous Oxide from the Shelves."); + getNitrousOxide.addDialogStep("YES"); + getTinOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_6, "Get Tin Ore Powder from the Shelves."); + getTinOrePowder.addDialogStep("YES"); + getCupricOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_7, "Get Cupric Ore Powder from the Shelves."); + getCupricOrePowder.addDialogStep("YES"); + getThreeVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_8, "Get Three Vials Of Liquid from the Shelves."); + getThreeVials.addDialogStep("Take all three vials"); + getKnife = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL3, "Get a Knife from the old bookshelf."); + getMetalSpade = new ItemStep(questHelper, "Get the metal spade off the table", metalSpade); + + useSpadeOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, "Use the spade in your inventory on the bunsen burner", metalSpade); + useSpadeOnBunsenBurner.addIcon(ItemID.RD_METAL_SPADE); + + useSpadeHeadOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use the spade in your inventory on the door.", metalSpadeHead); + useSpadeHeadOnDoor.addIcon(ItemID.RD_METAL_SPADE_NO_HANDLE); + + useCupricSulfateOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use Cupric Sulfate in your inventory on the door.", cupricSulfate); + useCupricSulfateOnDoor.addIcon(ItemID.RD_CUPRIC_SULPHATE); + + useVialOfLiquidOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use vial of liquid in your inventory on the door.", vialOfLiquid); + useVialOfLiquidOnDoor.addIcon(ItemID.RD_DIHYDROGEN_MONOXIDE); + + openDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Open the door."); + + useVialOfLiquidOnCakeTin = new DetailedQuestStep(questHelper, "Use a vial of liquid on the tin in your inventory.", tin, vialOfLiquid); + + useGypsumOnTin = new DetailedQuestStep(questHelper, "Use a vial of Gypsum on the tin in your inventory.", gypsum, tin); + + useTinOnKey = new ObjectStep(questHelper, ObjectID.RD_KEY_CHAINED, "Use tin full with Gypsum on the key on the ground.", gypsumTin); + useTinOnKey.addIcon(ItemID.RD_TINFULL); + + useCupricOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the cupric ore powder in your inventory.", tinKeyPrint, cupricOrePowder); + + useTinOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the tin ore powder in your inventory.", tinWithCupricOre, tinOrePowder); + + useTinOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, "Use your tin with the bunsen burner to create a bronze key.", tinWithTinOre); + useTinOnBunsenBurner.addIcon(ItemID.RD_FULL_KEYMOULD_UNHEATED); + + useEquipmentOnTin = new DetailedQuestStep(questHelper, "Use your chisel, knife or bronze wires on your tin in your inventory.", tinWithAllOre, chisel, knife, bronzeWire); + + pwGetMagnet = getMagnet.puzzleWrapStep(true); + pwGetTwoVials = getTwoVials.puzzleWrapStep(true); + pwGetCupricSulfate = getCupricSulfate.puzzleWrapStep(true); + pwGetGypsum = getGypsum.puzzleWrapStep(true); + pwGetSodiumChloride = getSodiumChloride.puzzleWrapStep(true); + pwGetWire = getWire.puzzleWrapStep(true); + pwGetTin = getTin.puzzleWrapStep(true); + pwGetShears = getShears.puzzleWrapStep(true); + pwGetChisel = getChisel.puzzleWrapStep(true); + pwGetNitrousOxide = getNitrousOxide.puzzleWrapStep(true); + pwGetTinOrePowder = getTinOrePowder.puzzleWrapStep(true); + pwGetCupricOrePowder = getCupricOrePowder.puzzleWrapStep(true); + pwGetThreeVials = getThreeVials.puzzleWrapStep(true); + pwGetKnife = getKnife.puzzleWrapStep(true); + pwGetMetalSpade = getMetalSpade.puzzleWrapStep(true); + pwUseSpadeOnBunsenBurner = useSpadeOnBunsenBurner.puzzleWrapStep(true); + pwUseSpadeHeadOnDoor = useSpadeHeadOnDoor.puzzleWrapStep(true); + pwUseCupricSulfateOnDoor = useCupricSulfateOnDoor.puzzleWrapStep(true); + pwUseVialOfLiquidOnDoor = useVialOfLiquidOnDoor.puzzleWrapStep(true); + pwOpenDoor = openDoor.puzzleWrapStep(true); + pwUseVialOfLiquidOnCakeTin = useVialOfLiquidOnCakeTin.puzzleWrapStep(true); + pwUseGypsumOnTin = useGypsumOnTin.puzzleWrapStep(true); + pwUseTinOnKey = useTinOnKey.puzzleWrapStep(true); + pwUseCupricOrePowderOnTin = useCupricOrePowderOnTin.puzzleWrapStep(true); + pwUseTinOrePowderOnTin = useTinOrePowderOnTin.puzzleWrapStep(true); + pwUseTinOnBunsenBurner = useTinOnBunsenBurner.puzzleWrapStep(true); + pwUseEquipmentOnTin = useEquipmentOnTin.puzzleWrapStep(true); + } + + private void addSteps() + { + this.addStep(null, pwGetMagnet); + setupSecondDoorKeyStep(); + destroyFirstDoorSteps(); + retrieveItemSteps(); + } + + /*** + * Steps and conditions required to create the key for the second door. + */ + private void setupSecondDoorKeyStep() + { + this.addStep(and(hasFirstDoorOpen, tinWithAllOre), pwUseEquipmentOnTin); + this.addStep(and(hasFirstDoorOpen, tinWithTinOre), pwUseTinOnBunsenBurner); + this.addStep(and(hasFirstDoorOpen, tinWithCupricOre), pwUseTinOrePowderOnTin); + this.addStep(and(hasFirstDoorOpen, tinKeyPrint), pwUseCupricOrePowderOnTin); + this.addStep(and(hasFirstDoorOpen, gypsumTin), pwUseTinOnKey); + this.addStep(and(hasFirstDoorOpen, hasLiquidInTin), pwUseGypsumOnTin); + this.addStep(hasFirstDoorOpen, pwUseVialOfLiquidOnCakeTin); + } + + /*** + * Steps and conditions required to destroy the first door. + */ + private void destroyFirstDoorSteps() + { + this.addStep(and(magnet, aceticAcid, vialOfLiquid, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, ashes, hasVialOfLiquidOnDoor), pwOpenDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, ashes, hasCupricSulfateOnDoor), pwUseVialOfLiquidOnDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, ashes, hasSpadeHeadOnDoor), pwUseCupricSulfateOnDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, metalSpadeHead, ashes), pwUseSpadeHeadOnDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, metalSpade), pwUseSpadeOnBunsenBurner); + } + + /** + * First stage to retrieve all required items to pass the room. + */ + private void retrieveItemSteps() + { + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife), pwGetMetalSpade); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials), pwGetKnife); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder), pwGetThreeVials); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder), pwGetCupricOrePowder); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide), pwGetTinOrePowder); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, chisel), pwGetNitrousOxide); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears), pwGetChisel); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin), pwGetShears); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire), pwGetTin); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride), pwGetWire); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum), pwGetSodiumChloride); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate), pwGetGypsum); + this.addStep(and(magnet, aceticAcid, vialOfLiquid), pwGetCupricSulfate); + this.addStep(magnet, pwGetTwoVials); + } + + public List getPanelSteps() + { + return List.of( + pwGetMagnet, + pwGetTwoVials, + pwGetCupricSulfate, + pwGetGypsum, + pwGetSodiumChloride, + pwGetWire, + pwGetTin, + pwGetShears, + pwGetChisel, + pwGetNitrousOxide, + pwGetTinOrePowder, + pwGetCupricOrePowder, + pwGetThreeVials, + pwGetKnife, + pwGetMetalSpade, + pwUseSpadeOnBunsenBurner, + pwUseSpadeHeadOnDoor, + pwUseCupricSulfateOnDoor, + pwUseVialOfLiquidOnDoor, + pwOpenDoor, + pwUseVialOfLiquidOnCakeTin, + pwUseGypsumOnTin, + pwUseTinOnKey, + pwUseCupricOrePowderOnTin, + pwUseTinOrePowderOnTin, + pwUseTinOnBunsenBurner, + pwUseEquipmentOnTin + ); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsCheevesSetup.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsCheevesSetup.java deleted file mode 100644 index b80ed3d2127..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsCheevesSetup.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2020, Patyfatycake - * 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 LIABI`LITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; - -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; -import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import lombok.Getter; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.ObjectID; -import net.runelite.api.gameval.VarbitID; - -import java.util.ArrayList; -import java.util.List; - -public class MsCheevesSetup -{ - private QuestHelper questHelper; - - @Getter - private ZoneRequirement isInMsCheeversRoom; - - @Getter - private ConditionalStep conditionalStep; - - private ObjectStep getMagnetStep, getTwoVials, getCupricSulfate, - getGypsum, getSodiumChloride, getWire, getTin, getShears, - getChisel, getNitrousOxide, getTinOrePowder, getCupricOrePowder, getThreeVials, - getKnife, leaveRoom; - private ItemStep getMetalSpade; - - // TODO: Clean up to just use ItemRequirement - private Requirement hasMagnet, hasAceticAcid, hasOneVialOfLiquid, - hasCupricSulfate, hasGypsum, hasSodiumChloride, hasWire, hasTin, - hasShears, hasChisel, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasKnife, hasMetalSpade, hasMetalSpadeHead, hasAshes, hasBronzeKey; - - private VarbitRequirement finishedRoom; - - // Destroying first door steps - private QuestStep useSpadeOnBunsenBurner, useSpadeHeadOnDoor, useCupricSulfateOnDoor, useVialOfLiquidOnDoor, openDoor; - private VarbitRequirement hasRetrievedThreeVials, hasSpadeHeadOnDoor, hasCupricSulfateOnDoor, hasVialOfLiquidOnDoor, hasFirstDoorOpen; - private ItemRequirement metalSpade, metalSpadeHead, ashes, cupricSulfate, vialOfLiquid; - - // Creating second door key steps - private QuestStep useVialOfLiquidOnCakeTin, useGypsumOnTin, useTinOnKey, useCupricOrePowderOnTin, useTinOrePowderOnTin, useTinOnBunsenBurner, useEquipmentOnTin; - private ItemRequirement tin, gypsumTin, gypsum, tinKeyPrint, cupricOrePowder, tinOrePowder, tinWithCupricOre, - tinWithTinOre, tinWithAllOre, bronzeKey, knife, chisel, bronzeWire; - private VarbitRequirement hasLiquidInTin; - ItemRequirement hasGypsumTin, hasTinKeyPrint, hasTinCupricOre, hasTinWithTinOre, hasTinWithAllOre; - - public MsCheevesSetup(QuestHelper questHelper) - { - this.questHelper = questHelper; - setupRequirements(); - setupZoneCondition(); - setupConditions(); - setupSteps(); - addSteps(); - } - - private void setupSteps() - { - getMagnetStep = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL, "Get the magnet from the old bookshelf."); - getTwoVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_1, "Get two vials from the shelves"); - getTwoVials.addDialogStep("Take both vials."); - getCupricSulfate = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_2, "Get Cupric Sulfate from the shelves."); - getCupricSulfate.addDialogStep("YES"); - getGypsum = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_3, "Get Gypsum from the shelves."); - getGypsum.addDialogStep("YES"); - getSodiumChloride = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_4, "Get Sodium Chloride from the shelves."); - getSodiumChloride.addDialogStep("YES"); - getWire = new ObjectStep(questHelper, ObjectID.RD_SMALL_CRATES, new WorldPoint(2475, 4943, 0), "Get Wire from the crate."); - getTin = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATE, new WorldPoint(2476, 4943, 0), "Get Tin from the crate."); - getShears = new ObjectStep(questHelper, ObjectID.RD_CHEST_CLOSED, "Get Shears from the chest."); - getShears.addAlternateObjects(ObjectID.RD_CHEST_OPEN); - getChisel = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATES, new WorldPoint(2476, 4937, 0), "Get a Chisel from the crate."); - getNitrousOxide = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_5, "Get Nitrous Oxide from the Shelves."); - getNitrousOxide.addDialogStep("YES"); - getTinOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_6, "Get Tin Ore Powder from the Shelves."); - getTinOrePowder.addDialogStep("YES"); - getCupricOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_7, "Get Curpic Ore Powder from the Shelves."); - getCupricOrePowder.addDialogStep("YES"); - getThreeVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_8, "Get Three Vials Of Liquid from the Shelves."); - getThreeVials.addDialogStep("Take all three vials"); - getKnife = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL3, "Get a Knife from the old bookshelf."); - getMetalSpade = new ItemStep(questHelper, "Get the metal spade off the table", metalSpade); - - useSpadeOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, "Use the spade in your inventory on the bunsen burner" - , metalSpade); - useSpadeOnBunsenBurner.addIcon(ItemID.RD_METAL_SPADE); - - useSpadeHeadOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use the spade in your inventory on the door.", - metalSpadeHead); - useSpadeHeadOnDoor.addIcon(ItemID.RD_METAL_SPADE_NO_HANDLE); - - useCupricSulfateOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use Cupric Sulfate in your inventory on the door.", - cupricSulfate); - useCupricSulfateOnDoor.addIcon(ItemID.RD_CUPRIC_SULPHATE); - - useVialOfLiquidOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use vial of liquid in your inventory on the door.", - vialOfLiquid); - useVialOfLiquidOnDoor.addIcon(ItemID.RD_DIHYDROGEN_MONOXIDE); - - openDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Open the door."); - - useVialOfLiquidOnCakeTin = new DetailedQuestStep(questHelper, "Use a vial of liquid on the tin in your inventory.", - tin, vialOfLiquid); - - useGypsumOnTin = new DetailedQuestStep(questHelper, "Use a vial of Gypsum on the tin in your inventory.", - gypsum, tin); - - useTinOnKey = new ObjectStep(questHelper, ObjectID.RD_KEY_CHAINED, "Use tin full with Gypsum on the key on the ground.", - gypsumTin); - useTinOnKey.addIcon(ItemID.RD_TINFULL); - - useCupricOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the cupric ore powder in your inventory.", - tinKeyPrint, cupricOrePowder); - - useTinOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the tin ore powder in your inventory.", - tinWithCupricOre, tinOrePowder); - - useTinOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, - "Use your tin with the bunsen burner to create a bronze key.", tinWithTinOre); - useTinOnBunsenBurner.addIcon(ItemID.RD_FULL_KEYMOULD_UNHEATED); - - useEquipmentOnTin = new DetailedQuestStep(questHelper, "Use your chisel, knife or bronze wires on your tin in your inventory.", - tinWithAllOre, chisel, knife, bronzeWire); - - leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM6_EXITDOOR, new WorldPoint(2478, 4940, 0), "Leave the room by the second door to enter the portal"); - } - - private void addSteps() - { - conditionalStep = new ConditionalStep(questHelper, getMagnetStep); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasBronzeKey, finishedRoom), leaveRoom); - setupSecondDoorKeyStep(); - destroyFirstDoorSteps(); - retrieveItemSteps(); - } - - public List GetPanelSteps() - { - List steps = new ArrayList<>(); - steps.add(getMagnetStep); - steps.add(getTwoVials); - steps.add(getCupricSulfate); - steps.add(getGypsum); - steps.add(getSodiumChloride); - steps.add(getWire); - steps.add(getTin); - steps.add(getShears); - steps.add(getChisel); - steps.add(getNitrousOxide); - steps.add(getTinOrePowder); - steps.add(getCupricOrePowder); - steps.add(getThreeVials); - steps.add(getKnife); - steps.add(getMetalSpade); - steps.add(useSpadeOnBunsenBurner); - steps.add(useSpadeHeadOnDoor); - steps.add(useCupricSulfateOnDoor); - steps.add(useVialOfLiquidOnDoor); - steps.add(openDoor); - steps.add(useVialOfLiquidOnCakeTin); - steps.add(useGypsumOnTin); - steps.add(useTinOnKey); - steps.add(useCupricOrePowderOnTin); - steps.add(useTinOrePowderOnTin); - steps.add(useTinOnBunsenBurner); - steps.add(useEquipmentOnTin); - steps.add(leaveRoom); - return steps; - } - - /*** - * Steps and conditions required to create the key for the second door. - */ - private void setupSecondDoorKeyStep() - { - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinWithAllOre), useEquipmentOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinWithTinOre), useTinOnBunsenBurner); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinCupricOre), useTinOrePowderOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinKeyPrint), useCupricOrePowderOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasGypsumTin), useTinOnKey); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasLiquidInTin), useGypsumOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen), useVialOfLiquidOnCakeTin); - } - - /*** - * Steps and conditions required to destroy the first door. - */ - private void destroyFirstDoorSteps() - { - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasAshes, hasVialOfLiquidOnDoor), openDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasAshes, hasCupricSulfateOnDoor), useVialOfLiquidOnDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasAshes, hasSpadeHeadOnDoor), useCupricSulfateOnDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasMetalSpadeHead, hasAshes), useSpadeHeadOnDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasMetalSpade), useSpadeOnBunsenBurner); - } - - /** - * First stage to retrieve all required items to pass the room. - */ - private void retrieveItemSteps() - { - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife), getMetalSpade); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials), getKnife); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder) - , getThreeVials); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder), getCupricOrePowder); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide), getTinOrePowder); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasChisel), getNitrousOxide); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears), getChisel); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin), getShears); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire), getTin); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride), getWire); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum), - getSodiumChloride); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate), getGypsum); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid), getCupricSulfate); - conditionalStep.addStep(hasMagnet, getTwoVials); - } - - private void setupZoneCondition() - { - Zone missCheevesZone = new Zone(new WorldPoint(2466, 4936, 0), - new WorldPoint(2480, 4947, 0)); - isInMsCheeversRoom = new ZoneRequirement(missCheevesZone); - } - - public void setupRequirements() - { - metalSpade = new ItemRequirement("Metal Spade", ItemID.RD_METAL_SPADE); - metalSpade.setTooltip("If you are missing this item pick another up off the table."); - metalSpade.setHighlightInInventory(true); - metalSpadeHead = new ItemRequirement("Metal Spade", ItemID.RD_METAL_SPADE_NO_HANDLE); - metalSpadeHead.setHighlightInInventory(true); - metalSpadeHead.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); - ashes = new ItemRequirement("Ashes", ItemID.ASHES); - ashes.setHighlightInInventory(true); - ashes.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); - cupricSulfate = new ItemRequirement("Cupric Sulfate", ItemID.RD_CUPRIC_SULPHATE); - cupricSulfate.setHighlightInInventory(true); - cupricSulfate.setTooltip("Take from the shelves on the north side"); - - vialOfLiquid = new ItemRequirement("Vial of Liquid", ItemID.RD_DIHYDROGEN_MONOXIDE); - vialOfLiquid.setHighlightInInventory(true); - vialOfLiquid.setTooltip("Take from the shelf on the north side or the south side."); - - tin = new ItemRequirement("Tin", ItemID.RD_TIN); - tin.setHighlightInInventory(true); - //TODO set tip - - gypsumTin = new ItemRequirement("Tin", ItemID.RD_TINFULL); - gypsumTin.setHighlightInInventory(true); - - gypsum = new ItemRequirement("Gypsum", ItemID.RD_GYPSUM); - gypsum.setHighlightInInventory(true); - - tinKeyPrint = new ItemRequirement("Tin", ItemID.RD_KEYMOULD); - tinKeyPrint.setHighlightInInventory(true); - - tinWithCupricOre = new ItemRequirement("Tin", ItemID.RD_FULL_KEYMOULD_COPPER); - tinWithCupricOre.setHighlightInInventory(true); - - cupricOrePowder = new ItemRequirement("Cupric Ore Powder", ItemID.RD_COPPER_ORE_POWDER); - cupricOrePowder.setHighlightInInventory(true); - - tinOrePowder = new ItemRequirement("Tin Ore Powder", ItemID.RD_TIN_ORE_POWDER); - tinOrePowder.setHighlightInInventory(true); - - tinWithTinOre = new ItemRequirement("Tin", ItemID.RD_FULL_KEYMOULD_UNHEATED); - tinWithTinOre.setHighlightInInventory(true); - // duplicateBronzeKey = new ItemRequirement("Duplicate bronze key", ItemID.PRINCESKEY); - - tinWithAllOre = new ItemRequirement("Tin", ItemID.RD_FULL_KEYMOULD_COMPLETE); - tinWithAllOre.setHighlightInInventory(true); - - chisel = new ItemRequirement("Chisel", ItemID.RD_CHISEL); - chisel.setHighlightInInventory(true); - - bronzeWire = new ItemRequirement("Bronze Wire", ItemID.RD_WIRE); - bronzeWire.setHighlightInInventory(true); - - knife = new ItemRequirement("Knife", ItemID.RD_KNIFE); - knife.setHighlightInInventory(true); - - bronzeKey = new ItemRequirement("Bronze Key", ItemID.RD_PUZZLEROOM_KEY); - } - - private void setupConditions() - { - hasMagnet = new ItemRequirements(new ItemRequirement("Magnet", ItemID.RD_MAGNET)); - hasAceticAcid = new ItemRequirements(new ItemRequirement("Acetic Acid", ItemID.RD_ACETIC_ACID)); - hasOneVialOfLiquid = vialOfLiquid; - hasCupricSulfate = cupricSulfate; - hasGypsum = gypsum; - hasSodiumChloride = new ItemRequirements(new ItemRequirement("Sodium Chloride", ItemID.RD_SODIUM_CHLORIDE)); - hasTin = tin; - hasWire = bronzeWire; - hasShears = new ItemRequirements(new ItemRequirement("Shears", ItemID.RD_SHEARS)); - hasChisel = chisel; - hasNitrousOxide = new ItemRequirements(new ItemRequirement("Nitrous Oxide", ItemID.RD_NITORUS_OXIDE)); - hasTinOrePowder = tinOrePowder; - hasCupricOrePowder = cupricOrePowder; - hasKnife = knife; - hasMetalSpade = metalSpade; - hasMetalSpadeHead = metalSpadeHead; - hasAshes = ashes; - - hasGypsumTin = gypsumTin; - hasTinKeyPrint = tinKeyPrint; - hasTinCupricOre = tinWithCupricOre; - hasTinWithTinOre = tinWithTinOre; - hasTinWithAllOre = tinWithAllOre; - - hasBronzeKey = bronzeKey; - - hasRetrievedThreeVials = new VarbitRequirement(VarbitID.RD_SPARE_WATER, 3); - hasSpadeHeadOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 1); - hasCupricSulfateOnDoor = new VarbitRequirement(VarbitID.RD_REACT_ON_SPADE, 1); - hasVialOfLiquidOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 2); - hasFirstDoorOpen = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 3); - finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM6_COMPLETE, 1); - - hasLiquidInTin = new VarbitRequirement(VarbitID.RD_WATER_IN_TIN, 1); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java index e9caf82dd3f..55e406002d5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java @@ -26,22 +26,13 @@ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; -import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.api.events.VarbitChanged; -import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.List; - -public class MsHynnAnswerDialogQuizStep extends ConditionalStep +public class MsHynnAnswerDialogQuizStep extends NpcStep { - private QuestStep leaveRoom, talkToMsHynnTerprett; - String[] answers = { "unknown", "10", @@ -51,56 +42,46 @@ public class MsHynnAnswerDialogQuizStep extends ConditionalStep "zero" }; - public MsHynnAnswerDialogQuizStep(QuestHelper questHelper, QuestStep step, Requirement... requirements) + public MsHynnAnswerDialogQuizStep(QuestHelper questHelper) { - super(questHelper, step, requirements); + super(questHelper, NpcID.RD_OBSERVER_ROOM_7, "Talk to Ms Hynn Terprett and answer the riddle."); - talkToMsHynnTerprett = step; - talkToMsHynnTerprett.addDialogSteps( + this.addDialogSteps( "The wolves.", "Bucket A (32 degrees)", "The number of false statements here is three.", - "Zero."); - addSteps(); + "Zero." + ); } - @Override - public void startUp() + private void updateAnswer(int answerID) { - super.startUp(); - int answerID = client.getVarbitValue(VarbitID.RD_TEMPLOCK_2); - if (answerID == 0) + if (answerID == 0 || answerID > answers.length) { + this.setText("Talk to Ms Hynn Terprett and answer the riddle."); return; } - String answer = "The answer is " + answers[answerID] + "."; - talkToMsHynnTerprett.setText("Talk to Ms Hynn Terprett and answer the riddle. " + answer); + var answer = "The answer is " + answers[answerID] + "."; + this.setText("Talk to Ms Hynn Terprett and answer the riddle. " + answer); } @Override - public void onVarbitChanged(VarbitChanged varbitChanged) + public void startUp() { - int answerID = client.getVarbitValue(VarbitID.RD_TEMPLOCK_2); - if (answerID == 0) - { - return; - } - String answer = "The answer is " + answers[answerID] + "."; - talkToMsHynnTerprett.setText("Talk to Ms Hynn Terprett and answer the riddle. " + answer); + super.startUp(); + this.updateAnswer(client.getVarbitValue(VarbitID.RD_TEMPLOCK_2)); } - private void addSteps() + @Override + public void onVarbitChanged(VarbitChanged event) { - VarbitRequirement finishedRoomCondition = new VarbitRequirement(VarbitID.RD_ROOM7_COMPLETE, 1); - leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM7_EXITDOOR, "Leave through the door to enter the portal and continue."); + super.onVarbitChanged(event); - addStep(finishedRoomCondition, leaveRoom); - } + if (event.getVarbitId() != VarbitID.RD_TEMPLOCK_2) + { + return; + } - public List getPanelSteps() - { - List steps = new ArrayList<>(); - steps.add(leaveRoom); - return steps; + this.updateAnswer(event.getValue()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java index 55e2025ffc5..d57589e75cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java @@ -27,13 +27,14 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.ConfigRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.NoItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.ItemSlots; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -42,7 +43,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -51,89 +61,120 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class RecruitmentDrive extends BasicQuestHelper { - private NoItemRequirement noItemRequirement; - private ZoneRequirement isFirstFloorCastle, isSecondFloorCastle, - isInSirTinleysRoom, isInMsHynnRoom, isInSirKuamsRoom, - isInSirSpishyusRoom, isInSirRenItchood, isInladyTableRoom; - - private ConditionalStep conditionalTalkToSirAmikVarze; - - private QuestStep talkToSirTiffy; - - //Sir Tinsley steps - QuestStep doNothingStep, talkToSirTinley, leaveSirTinleyRoom; + // Mid-quest requirements + NoItemRequirement noItemRequirement; + + // Zones + Zone firstFloorZone; + Zone secondFloorZone; + Zone missCheeversZone; + Zone sirTinleyRoomZone; + Zone msHynnRoomZone; + Zone sirKuamRoomZone; + Zone sirSphishyusZone; + Zone sirRenItchoodZone; + Zone ladyTableZone; + + // Miscellaneous requirements + ZoneRequirement isFirstFloorCastle; + ZoneRequirement isSecondFloorCastle; + ZoneRequirement isInMissCheeversRoom; + ZoneRequirement isInSirTinleysRoom; + ZoneRequirement isInMsHynnRoom; + ZoneRequirement isInSirKuamsRoom; + ZoneRequirement isInSirSpishyusRoom; + ZoneRequirement isInSirRenItchood; + ZoneRequirement isInladyTableRoom; + + // Steps + ConditionalStep cTalkToSirAmikVarze; + ObjectStep climbBottomSteps; + ObjectStep climbSecondSteps; + NpcStep talkToSirAmikVarze; + + ObjectStep climbDownSecondFloorStaircase; + ObjectStep climbDownfirstFloorStaircase; + QuestStep talkToSirTiffy; + + // Sir Tinley steps + PuzzleWrapperStep talkToSirTinley; + PuzzleWrapperStep doNothingStep; + ObjectStep leaveSirTinleyRoom; + ConditionalStep sirTinleyStep; // Sir Kuam Ferentse steps - QuestStep talkToSirKuam, killSirLeye, leaveSirKuamRoom; + NpcStep talkToSirKuam; + NpcStep killSirLeye; + PuzzleWrapperStep pwKillSirLeye; + ObjectStep leaveSirKuamRoom; + ConditionalStep sirKuamStep; // Sir Spishyus - QuestStep moveChickenOnRightToLeft, moveFoxOnRightToLeft, moveChickenOnLeftToRight, - moveGrainOnRightToLeft, moveChickenOnRightToLeftAgain, finishedSpishyusRoom; + QuestStep moveChickenOnRightToLeft; + QuestStep moveFoxOnRightToLeft; + QuestStep moveChickenOnLeftToRight; + QuestStep moveGrainOnRightToLeft; + QuestStep moveChickenOnRightToLeftAgain; + QuestStep leaveSirSpishyusRoom; + ConditionalStep sirSpishyusPuzzle; + ConditionalStep cSirSpishyus; + PuzzleWrapperStep pwSirSpishyusStep; // Sir Ren SirRenItchoodStep sirRenStep; // Lady Table LadyTableStep ladyTableStep; + PuzzleWrapperStep pwLadyTableStep; + ObjectStep leaveLadyTableRoom; + ConditionalStep cLadyTableStep; // Ms Hynn - private QuestStep talkToMsHynnTerprett; - private MsHynnAnswerDialogQuizStep msHynnDialogQuiz; - - // Ms Cheeves - private MsCheevesSetup msCheevesSetup; - - @Override - public Map loadSteps() - { - initializeRequirements(); - - return getSteps(); - } - - private Map getSteps() - { - Map steps = new HashMap<>(); - - steps.put(0, TalkToSirAmikVarze()); - steps.put(1, TalkToSirTiffyInFaladorPark()); + MsHynnAnswerDialogQuizStep msHynnDialogQuiz; + PuzzleWrapperStep pwMsHynnTerprett; + ObjectStep leaveMsHynnTerprettRoom; + ConditionalStep msHynnTerprettStep; - return steps; - } - - @Override - protected void setupRequirements() - { - noItemRequirement = new NoItemRequirement("No items or equipment carried", ItemSlots.ANY_EQUIPPED_AND_INVENTORY); - } + // Miss Cheevers + MissCheeversStep missCheeversStep; + PuzzleWrapperStep pwMissCheeversStep; + ObjectStep leaveMissCheeversRoom; + ConditionalStep cMissCheevers; @Override protected void setupZones() { - Zone firstFloorZone = new Zone(new WorldPoint(2954, 3335, 1), + firstFloorZone = new Zone(new WorldPoint(2954, 3335, 1), new WorldPoint(2966, 3343, 1)); - Zone secondFloorZone = new Zone(new WorldPoint(2955, 3334, 2), + secondFloorZone = new Zone(new WorldPoint(2955, 3334, 2), new WorldPoint(2964, 3342, 2)); - Zone sirTinleyRoomZone = new Zone(new WorldPoint(2471, 4954, 0), + missCheeversZone = new Zone(new WorldPoint(2466, 4936, 0), + new WorldPoint(2480, 4947, 0)); + sirTinleyRoomZone = new Zone(new WorldPoint(2471, 4954, 0), new WorldPoint(2481, 4960, 0)); - Zone msHynnRoomZone = new Zone(new WorldPoint(2446, 4934, 0), + msHynnRoomZone = new Zone(new WorldPoint(2446, 4934, 0), new WorldPoint(2457, 4946, 0)); - Zone sirKuamRoomZone = new Zone(new WorldPoint(2453, 4958, 0), + sirKuamRoomZone = new Zone(new WorldPoint(2453, 4958, 0), new WorldPoint(2466, 4970, 0)); - Zone sirSphishyusZone = new Zone(new WorldPoint(2469, 4968, 0), + sirSphishyusZone = new Zone(new WorldPoint(2469, 4968, 0), new WorldPoint(2492, 4980, 0)); - Zone sirRenItchoodZone = new Zone(new WorldPoint(2438, 4952, 0), + sirRenItchoodZone = new Zone(new WorldPoint(2438, 4952, 0), new WorldPoint(2448, 4962, 0)); - Zone ladyTableZone = new Zone(new WorldPoint(2445, 4974, 0), + ladyTableZone = new Zone(new WorldPoint(2445, 4974, 0), new WorldPoint(2461, 4987, 0)); + } + + @Override + protected void setupRequirements() + { + noItemRequirement = new NoItemRequirement("No items or equipment carried", ItemSlots.ANY_EQUIPPED_AND_INVENTORY); isFirstFloorCastle = new ZoneRequirement(firstFloorZone); isSecondFloorCastle = new ZoneRequirement(secondFloorZone); + isInMissCheeversRoom = new ZoneRequirement(missCheeversZone); isInSirTinleysRoom = new ZoneRequirement(sirTinleyRoomZone); isInMsHynnRoom = new ZoneRequirement(msHynnRoomZone); isInSirKuamsRoom = new ZoneRequirement(sirKuamRoomZone); @@ -142,222 +183,282 @@ protected void setupZones() isInladyTableRoom = new ZoneRequirement(ladyTableZone); } - private QuestStep TalkToSirTiffyInFaladorPark() + public void setupSteps() { - WorldPoint firstFloorStairsPosition = new WorldPoint(2955, 3338, 1); - WorldPoint secondFloorStairsPosition = new WorldPoint(2960, 3339, 2); + climbBottomSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, new WorldPoint(2955, 3339, 0), + "Climb up the stairs to the first floor on the Falador Castle."); - ObjectStep climbDownSecondFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, - secondFloorStairsPosition, "Climb down the stairs from the second floor."); - ObjectStep climbDownfirstFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, - firstFloorStairsPosition, "Climb down the stairs from the first floor."); + climbSecondSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, new WorldPoint(2961, 3339, 1), + "Climb up the stairs to talk to Sir Amik Varze."); + talkToSirAmikVarze = new NpcStep(this, NpcID.SIR_AMIK_VARZE, ""); + talkToSirAmikVarze.addDialogStep("Yes."); - talkToSirTiffy = new NpcStep(this, NpcID.RD_TELEPORTER_GUY, - "Talk to Sir Tiffy Cashien in Falador Park.", noItemRequirement); + climbDownSecondFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, new WorldPoint(2960, 3339, 2), "Climb down the stairs from the second floor."); + climbDownfirstFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, new WorldPoint(2955, 3338, 1), "Climb down the stairs from the first floor."); - ConditionalStep conditionalTalkToSirTiffy = new ConditionalStep(this, talkToSirTiffy); - conditionalTalkToSirTiffy.addStep(isSecondFloorCastle, climbDownSecondFloorStaircase); - conditionalTalkToSirTiffy.addStep(isFirstFloorCastle, climbDownfirstFloorStaircase); + talkToSirTiffy = new NpcStep(this, NpcID.RD_TELEPORTER_GUY, new WorldPoint(2997, 3373, 0), "Talk to Sir Tiffy Cashien in Falador Park.", noItemRequirement); talkToSirTiffy.addDialogStep("Yes, let's go!"); - talkToSirTiffy.addSubSteps(climbDownfirstFloorStaircase, - climbDownSecondFloorStaircase); - getMsCheeves(); + talkToSirTiffy.addSubSteps(climbDownfirstFloorStaircase, climbDownSecondFloorStaircase); - // Testing steps below - conditionalTalkToSirTiffy.addStep(isInSirTinleysRoom, getSirTinley()); - conditionalTalkToSirTiffy.addStep(isInMsHynnRoom, getMsHynnTerprett()); - conditionalTalkToSirTiffy.addStep(isInSirRenItchood, getSirRenItchood()); - conditionalTalkToSirTiffy.addStep(isInladyTableRoom, getLadyTableStep()); - conditionalTalkToSirTiffy.addStep(isInSirSpishyusRoom, getSirSpishyus()); - conditionalTalkToSirTiffy.addStep(isInSirKuamsRoom, getSirKuam()); - - conditionalTalkToSirTiffy.addStep(msCheevesSetup.getIsInMsCheeversRoom(), msCheevesSetup.getConditionalStep()); - return conditionalTalkToSirTiffy; - } + // Testing grounds + // Miss Cheevers + { + missCheeversStep = new MissCheeversStep(this); + pwMissCheeversStep = missCheeversStep.puzzleWrapStepWithDefaultText("Solve Miss Cheevers' puzzle."); + pwMissCheeversStep.conditionToHideInSidebar(new ConfigRequirement(this.getConfig()::solvePuzzles)); - private LadyTableStep getLadyTableStep() - { - this.ladyTableStep = new LadyTableStep(this); - return this.ladyTableStep; - } + leaveMissCheeversRoom = new ObjectStep(this, ObjectID.RD_ROOM6_EXITDOOR, new WorldPoint(2478, 4940, 0), "Leave the room by the second door to enter the portal."); - private QuestStep getSirKuam() - { - VarbitRequirement finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM3_COMPLETE, 1); + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM6_COMPLETE, 1); - talkToSirKuam = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_3, "Talk to Sir Kuam Ferentse to have him spawn Sir Leye."); - killSirLeye = new NpcStep(this, NpcID.RD_COMBAT_NPC_ROOM_3, - "Defeat Sir Leye to win this challenge. You must use the steel warhammer or your barehands to deal the final hit on him.", true); + cMissCheevers = new ConditionalStep(this, pwMissCheeversStep); + cMissCheevers.addStep(and(missCheeversStep.hasFirstDoorOpen, missCheeversStep.bronzeKey, finishedRoom), leaveMissCheeversRoom); + } + + // Sir Tinley + { + talkToSirTinley = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_4, "Talk to Sir Tinley. Once you have pressed continue do not do anything or you will fail.").puzzleWrapStepWithDefaultText("Talk to Sir Tinley and solve his puzzle."); + doNothingStep = new DetailedQuestStep(this, "Press Continue and do nothing. Sir Tinley will eventually talk to you and let you pass.").puzzleWrapStepWithDefaultText("Talk to Sir Tinley and solve his puzzle.").withNoHelpHiddenInSidebar(true); + leaveSirTinleyRoom = new ObjectStep(this, ObjectID.RD_ROOM4_EXITDOOR, "Leave through the portal to continue."); - leaveSirKuamRoom = new ObjectStep(this, ObjectID.RD_ROOM3_EXITDOOR, "Leave through the portal to continue."); - NpcCondition npcCondition = new NpcCondition(NpcID.RD_COMBAT_NPC_ROOM_3); + var waitForCondition = new VarbitRequirement(VarbitID.RD_TEMPLOCK_2, 1, Operation.GREATER_EQUAL); + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM4_COMPLETE, 1); - ConditionalStep sirKuamConditional = new ConditionalStep(this, talkToSirKuam); + talkToSirTinley.addSubSteps(doNothingStep); - sirKuamConditional.addStep(finishedRoom, leaveSirKuamRoom); - sirKuamConditional.addStep(npcCondition, killSirLeye); - return sirKuamConditional; - } + sirTinleyStep = new ConditionalStep(this, talkToSirTinley); + sirTinleyStep.addStep(finishedRoom, leaveSirTinleyRoom); + sirTinleyStep.addStep(waitForCondition, doNothingStep); + } - private void getMsCheeves() - { - msCheevesSetup = new MsCheevesSetup(this); - } + // Ms Hynn Terprett + { + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM7_COMPLETE, 1); - private QuestStep getSirSpishyus() - { - WorldPoint chickenOnLeftPoint = new WorldPoint(2473, 4970, 0); - WorldPoint chickenOnRightPoint = new WorldPoint(2487, 4974, 0); - WorldPoint foxOnRightPoint = new WorldPoint(2485, 4974, 0); - WorldPoint grainOnRightPoint = new WorldPoint(2486, 4974, 0); - - VarbitRequirement foxOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 0); - VarbitRequirement foxOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 1); - VarbitRequirement foxNotOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 1); - VarbitRequirement foxNotOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 0); - VarbitRequirement chickenOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 0); - VarbitRequirement chickenOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 1); - VarbitRequirement chickenNotOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 1); - VarbitRequirement chickenNotOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 0); - VarbitRequirement grainOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 0); - VarbitRequirement grainOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 1); - VarbitRequirement grainNotOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 1); - VarbitRequirement grainNotOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 0); - VarbitRequirement finishedSpishyus = new VarbitRequirement(VarbitID.RD_ROOM1_COMPLETE, 1); - - Conditions foxPickedUp = new Conditions(LogicType.AND, foxNotOnLeftSide, foxNotOnRightSide); - Conditions chickenPickedUp = new Conditions(LogicType.AND, chickenNotOnRightSide, chickenNotOnLeftSide); - Conditions grainPickedUp = new Conditions(LogicType.AND, grainNotOnLeftSide, grainNotOnRightSide); - - moveChickenOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, - getSpishyusPickupText("Chicken", true)); - finishedSpishyusRoom = new ObjectStep(this, ObjectID.RD_ROOM1_EXITDOOR, "Leave through the portal to continue."); - - moveFoxOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_FOX_MULTI, foxOnRightPoint, - getSpishyusPickupText("Fox", true)); - - DetailedQuestStep moveChickenToLeft = new DetailedQuestStep(this, getSpishyusMoveText("Chicken", false)); - moveChickenOnRightToLeft.addSubSteps(moveChickenToLeft); - - DetailedQuestStep moveFoxToLeft = new DetailedQuestStep(this, getSpishyusMoveText("Fox", false)); - moveFoxOnRightToLeft.addSubSteps(moveFoxToLeft); - - moveChickenOnLeftToRight = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI_RIGHT, chickenOnLeftPoint, - getSpishyusPickupText("Chicken", false)); - DetailedQuestStep moveChickenToRight = new DetailedQuestStep(this, getSpishyusMoveText("Chicken", true)); - moveChickenOnLeftToRight.addSubSteps(moveChickenToRight); - - moveGrainOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_GRAIN_MULTI, grainOnRightPoint, - getSpishyusPickupText("Grain", true)); - DetailedQuestStep moveGrainToLeft = new DetailedQuestStep(this, getSpishyusMoveText("Grain", false)); - moveGrainOnRightToLeft.addSubSteps(moveGrainToLeft); - - moveChickenOnRightToLeftAgain = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, - getSpishyusPickupText("Chicken", true)); - DetailedQuestStep moveChickenToLeftAgain = new DetailedQuestStep(this, getSpishyusMoveText("Chicken", false)); - moveChickenOnRightToLeftAgain.addSubSteps(moveChickenToLeftAgain); - - ConditionalStep sirSpishyus = new ConditionalStep(this, moveChickenOnRightToLeft); - sirSpishyus.addStep(finishedSpishyus, finishedSpishyusRoom); - - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnRightSide, grainOnRightSide), moveChickenOnRightToLeft); - sirSpishyus.addStep(new Conditions(chickenPickedUp, foxOnRightSide, grainOnRightSide), moveChickenToLeft); - sirSpishyus.addStep(new Conditions(chickenOnLeftSide, foxOnRightSide, grainOnRightSide), moveFoxOnRightToLeft); - sirSpishyus.addStep(new Conditions(chickenOnLeftSide, foxPickedUp, grainOnRightSide), moveFoxToLeft); - sirSpishyus.addStep(new Conditions(chickenOnLeftSide, foxOnLeftSide, grainOnRightSide), moveChickenOnLeftToRight); - sirSpishyus.addStep(new Conditions(chickenPickedUp, foxOnLeftSide, grainOnRightSide), moveChickenToRight); - - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnLeftSide, grainOnRightSide), moveGrainOnRightToLeft); - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnLeftSide, grainPickedUp), moveGrainToLeft); - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnLeftSide, grainOnLeftSide), moveChickenOnRightToLeftAgain); - sirSpishyus.addStep(new Conditions(chickenPickedUp, foxOnLeftSide, grainOnLeftSide), moveChickenToLeftAgain); - - return sirSpishyus; - } + msHynnDialogQuiz = new MsHynnAnswerDialogQuizStep(this); + pwMsHynnTerprett = msHynnDialogQuiz.puzzleWrapStepWithDefaultText("Talk to Ms Hynn Terprett and answer the riddle."); - private String getSpishyusPickupText(String itemName, boolean moveRightToLeft) - { - String firstSide = moveRightToLeft ? "east" : "west"; - String secondSide = moveRightToLeft ? "west" : "east"; - return "Pickup the " + itemName + " on the " + firstSide + " and move it to the " - + secondSide + " side by crossing the bridge"; - } + leaveMsHynnTerprettRoom = new ObjectStep(this, ObjectID.RD_ROOM7_EXITDOOR, "Leave through the door to enter the portal and continue."); - private String getSpishyusMoveText(String itemName, boolean rightSide) - { - String dropSide = rightSide ? "east" : "west"; - return "Cross the bridge to the " + dropSide + " and drop the " + itemName + " from your equipped items."; - } + msHynnTerprettStep = new ConditionalStep(this, pwMsHynnTerprett); + msHynnTerprettStep.addStep(finishedRoom, leaveMsHynnTerprettRoom); + } - private QuestStep getSirRenItchood() - { - NpcStep talkToSirRenItchood = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_5, "Talk to Sir Ren Itchood to receive the clue."); - talkToSirRenItchood.addDialogSteps("Can I have the clue for the door?"); + // Sir Ren Itchood + { + var talkToSirRenItchood = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_5, "Talk to Sir Ren Itchood to receive the clue."); + talkToSirRenItchood.addDialogSteps("Can I have the clue for the door?"); - sirRenStep = new SirRenItchoodStep(this, talkToSirRenItchood); - return sirRenStep; - } + sirRenStep = new SirRenItchoodStep(this, talkToSirRenItchood); + } - private QuestStep getSirTinley() - { - talkToSirTinley = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_4, - "Talk to Sir Tinley. \n Once you have pressed continue do not do anything or you will fail."); - doNothingStep = new DetailedQuestStep(this, - "Press Continue and do nothing. Sir Tinley will eventually talk to you and let you pass."); - leaveSirTinleyRoom = new ObjectStep(this, ObjectID.RD_ROOM4_EXITDOOR, "Leave through the portal to continue."); + // Lady Table + { + ladyTableStep = new LadyTableStep(this); + pwLadyTableStep = ladyTableStep.puzzleWrapStepWithDefaultText("Solve Lady Table's puzzle."); + + leaveLadyTableRoom = new ObjectStep(this, ObjectID.RD_ROOM2_EXITDOOR, "Leave through the door to enter the portal and continue."); + + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM2_COMPLETE, 1); + + cLadyTableStep = new ConditionalStep(this, pwLadyTableStep); + cLadyTableStep.addStep(finishedRoom, leaveLadyTableRoom); + } + + // Sir Spishyus + { + var chickenOnLeftPoint = new WorldPoint(2473, 4970, 0); + var chickenOnRightPoint = new WorldPoint(2487, 4974, 0); + var foxOnRightPoint = new WorldPoint(2485, 4974, 0); + var grainOnRightPoint = new WorldPoint(2486, 4974, 0); + + var foxOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 0); + var foxOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 1); + var foxNotOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 1); + var foxNotOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 0); + var chickenOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 0); + var chickenOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 1); + var chickenNotOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 1); + var chickenNotOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 0); + var grainOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 0); + var grainOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 1); + var grainNotOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 1); + var grainNotOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 0); + var finishedSpishyus = new VarbitRequirement(VarbitID.RD_ROOM1_COMPLETE, 1); + + var westSide = new Zone(new WorldPoint(2472, 4976, 0), new WorldPoint(2479, 4968, 0)); + var playerOnWestSide = new ZoneRequirement(westSide); + var playerOnEastSide = not(playerOnWestSide); + + var foxPickedUp = and(foxNotOnLeftSide, foxNotOnRightSide); + var chickenPickedUp = and(chickenNotOnRightSide, chickenNotOnLeftSide); + var grainPickedUp = and(grainNotOnLeftSide, grainNotOnRightSide); + + moveChickenOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, getSpishyusPickupText("Chicken", true)).puzzleWrapStep(true); + + moveFoxOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_FOX_MULTI, foxOnRightPoint, getSpishyusPickupText("Fox", true)).puzzleWrapStep(true); + + var moveChickenToLeft = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Chicken", false)); + moveChickenToLeft.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnRightToLeft).getSolvingStep().addSubSteps(moveChickenToLeft); + + var moveFoxToWest = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Fox", false)); + moveFoxToWest.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveFoxOnRightToLeft).getSolvingStep().addSubSteps(moveFoxToWest); + + moveChickenOnLeftToRight = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI_RIGHT, chickenOnLeftPoint, getSpishyusPickupText("Chicken", false)).puzzleWrapStep(true); + var moveChickenToRight = new ObjectStep(this, ObjectID.RD_BRIDGE_RIGHT, new WorldPoint(2477, 4972, 0), getSpishyusMoveText("Chicken", true)); + moveChickenToRight.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnLeftToRight).getSolvingStep().addSubSteps(moveChickenToRight); + + moveGrainOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_GRAIN_MULTI, grainOnRightPoint, getSpishyusPickupText("Grain", true)).puzzleWrapStep(true); + var moveGrainToLeft = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Grain", false)); + moveGrainToLeft.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveGrainOnRightToLeft).getSolvingStep().addSubSteps(moveGrainToLeft); + + moveChickenOnRightToLeftAgain = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, getSpishyusPickupText("Chicken", true)).puzzleWrapStep(true); + var moveChickenToLeftAgain = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Chicken", false)); + moveChickenToLeftAgain.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnRightToLeftAgain).getSolvingStep().addSubSteps(moveChickenToLeftAgain); + + sirSpishyusPuzzle = new ConditionalStep(this, moveChickenOnRightToLeft, "Solve Sir Spishyus' riddle."); - VarbitRequirement waitForCondition = new VarbitRequirement(VarbitID.RD_TEMPLOCK_2, 1, Operation.GREATER_EQUAL); - VarbitRequirement finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM4_COMPLETE, 1); + var dropChickenWest = new DetailedQuestStep(this, "Drop the Chicken on the west side from your equipped items."); + ((PuzzleWrapperStep) moveChickenOnRightToLeft).getSolvingStep().addSubSteps(dropChickenWest); + + // 1. Move Chicken from east to west + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnRightSide, grainOnRightSide), moveChickenOnRightToLeft); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnRightSide, grainOnRightSide, playerOnEastSide), moveChickenToLeft); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnRightSide, grainOnRightSide), dropChickenWest); - ConditionalStep sirTinleyStep = new ConditionalStep(this, talkToSirTinley); - sirTinleyStep.addStep(finishedRoom, leaveSirTinleyRoom); - sirTinleyStep.addStep(waitForCondition, doNothingStep); + var moveToEastSide1 = new ObjectStep(this, ObjectID.RD_BRIDGE_RIGHT, new WorldPoint(2477, 4972, 0), "Cross the bridge to the east side."); + moveToEastSide1.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveFoxOnRightToLeft).getSolvingStep().addSubSteps(moveToEastSide1); - return sirTinleyStep; + var dropFoxWest = new DetailedQuestStep(this, "Drop the Fox on the west side from your equipped items."); + ((PuzzleWrapperStep) moveFoxOnRightToLeft).getSolvingStep().addSubSteps(dropFoxWest); + + // 2. Return to east side, then move Fox from east to west + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxOnRightSide, grainOnRightSide, playerOnWestSide), moveToEastSide1); + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxOnRightSide, grainOnRightSide), moveFoxOnRightToLeft); + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxPickedUp, grainOnRightSide, playerOnEastSide), moveFoxToWest); + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxPickedUp, grainOnRightSide), dropFoxWest); + + var dropChickenEast = new DetailedQuestStep(this, "Drop the Chicken on the east side from your equipped items."); + ((PuzzleWrapperStep) moveChickenOnLeftToRight).getSolvingStep().addSubSteps(dropChickenEast); + + // 3. Move chicken from west to east + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxOnLeftSide, grainOnRightSide), moveChickenOnLeftToRight); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnRightSide, playerOnWestSide), moveChickenToRight); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnRightSide), dropChickenEast); + + var dropGrainWest = new DetailedQuestStep(this, "Drop the Grain on the west side from your equipped items."); + ((PuzzleWrapperStep) moveGrainOnRightToLeft).getSolvingStep().addSubSteps(dropGrainWest); + + // 4. Move grain from east to west + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainOnRightSide), moveGrainOnRightToLeft); + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainPickedUp, playerOnEastSide), moveGrainToLeft); + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainPickedUp), dropGrainWest); + + var moveToEastSide2 = new ObjectStep(this, ObjectID.RD_BRIDGE_RIGHT, new WorldPoint(2477, 4972, 0), "Cross the bridge to the east side."); + moveToEastSide2.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnRightToLeftAgain).getSolvingStep().addSubSteps(moveToEastSide2); + + var dropChickenWest2 = new DetailedQuestStep(this, "Drop the Chicken on the west side from your equipped items."); + ((PuzzleWrapperStep) moveChickenOnRightToLeftAgain).getSolvingStep().addSubSteps(dropChickenWest2); + + // 5. Cross the bridge to the east, then move the chicken from east to west + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainOnLeftSide, playerOnWestSide), moveToEastSide2); + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainOnLeftSide), moveChickenOnRightToLeftAgain); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnLeftSide, playerOnEastSide), moveChickenToLeftAgain); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnLeftSide), dropChickenWest2); + + pwSirSpishyusStep = sirSpishyusPuzzle.puzzleWrapStepWithDefaultText("Solve Sir Spishyus' riddle."); + pwSirSpishyusStep.conditionToHideInSidebar(new ConfigRequirement(this.getConfig()::solvePuzzles)); + + leaveSirSpishyusRoom = new ObjectStep(this, ObjectID.RD_ROOM1_EXITDOOR, "Leave through the portal to continue."); + + cSirSpishyus = new ConditionalStep(this, pwSirSpishyusStep); + cSirSpishyus.addStep(finishedSpishyus, leaveSirSpishyusRoom); + } + + // Sir Kuam + { + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM3_COMPLETE, 1); + + talkToSirKuam = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_3, "Talk to Sir Kuam Ferentse to have him spawn Sir Leye."); + killSirLeye = new NpcStep(this, NpcID.RD_COMBAT_NPC_ROOM_3, "Defeat Sir Leye to win this challenge. You must use the steel warhammer or your bare hands to deal the final hit on him.", true); + pwKillSirLeye = killSirLeye.puzzleWrapStepWithDefaultText("Defeat Sir Leye to win this challenge."); + + leaveSirKuamRoom = new ObjectStep(this, ObjectID.RD_ROOM3_EXITDOOR, "Leave through the portal to continue."); + var npcCondition = new NpcCondition(NpcID.RD_COMBAT_NPC_ROOM_3); + + sirKuamStep = new ConditionalStep(this, talkToSirKuam); + sirKuamStep.addStep(finishedRoom, leaveSirKuamRoom); + sirKuamStep.addStep(npcCondition, pwKillSirLeye); + } } - private QuestStep getMsHynnTerprett() + @Override + public Map loadSteps() { - talkToMsHynnTerprett = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_7, - "Talk to Ms Hynn Terprett and answer the riddle."); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + cTalkToSirAmikVarze = new ConditionalStep(this, climbBottomSteps, "Talk to Sir Amik Varze."); + cTalkToSirAmikVarze.addStep(isFirstFloorCastle, climbSecondSteps); + cTalkToSirAmikVarze.addStep(isSecondFloorCastle, talkToSirAmikVarze); + steps.put(0, cTalkToSirAmikVarze); + + var cTestingGrounds = new ConditionalStep(this, talkToSirTiffy); + cTestingGrounds.addStep(isSecondFloorCastle, climbDownSecondFloorStaircase); + cTestingGrounds.addStep(isFirstFloorCastle, climbDownfirstFloorStaircase); + + // Testing steps below + cTestingGrounds.addStep(isInMissCheeversRoom, cMissCheevers); + cTestingGrounds.addStep(isInSirTinleysRoom, sirTinleyStep); + cTestingGrounds.addStep(isInMsHynnRoom, msHynnTerprettStep); + cTestingGrounds.addStep(isInSirRenItchood, sirRenStep); + cTestingGrounds.addStep(isInladyTableRoom, cLadyTableStep); + cTestingGrounds.addStep(isInSirSpishyusRoom, cSirSpishyus); + cTestingGrounds.addStep(isInSirKuamsRoom, sirKuamStep); + + steps.put(1, cTestingGrounds); - msHynnDialogQuiz = new MsHynnAnswerDialogQuizStep(this, talkToMsHynnTerprett); - return msHynnDialogQuiz; + return steps; } - private QuestStep TalkToSirAmikVarze() + private String getSpishyusPickupText(String itemName, boolean moveRightToLeft) { - WorldPoint bottomStairsPosition = new WorldPoint(2955, 3339, 0); - WorldPoint secondStairsPosition = new WorldPoint(2961, 3339, 1); - ObjectStep climbBottomSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, bottomStairsPosition, - "Climb up the stairs to the first floor on the Falador Castle."); + String firstSide = moveRightToLeft ? "east" : "west"; + String secondSide = moveRightToLeft ? "west" : "east"; + return "Pick up the " + itemName + " on the " + firstSide + " and move it to the " + + secondSide + " side by crossing the bridge"; + } - ObjectStep climbSecondSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, secondStairsPosition, - "Climb up the stairs to talk to Sir Amik Vaze."); - NpcStep talkToSirAmikVarze = new NpcStep(this, NpcID.SIR_AMIK_VARZE, ""); - talkToSirAmikVarze.addDialogStep("Yes please"); - - conditionalTalkToSirAmikVarze = new ConditionalStep(this, climbBottomSteps, - "Talk to Sir Amik Varze."); - conditionalTalkToSirAmikVarze.addStep(isFirstFloorCastle, climbSecondSteps); - conditionalTalkToSirAmikVarze.addStep(isSecondFloorCastle, talkToSirAmikVarze); - conditionalTalkToSirAmikVarze.addSubSteps(climbSecondSteps, climbBottomSteps, talkToSirAmikVarze); - return conditionalTalkToSirAmikVarze; + private String getSpishyusMoveText(String itemName, boolean rightSide) + { + String dropSide = rightSide ? "east" : "west"; + return "Cross the bridge to the " + dropSide + " and drop the " + itemName + " from your equipped items."; } @Override - public List getCombatRequirements() + public List getGeneralRequirements() { - return Collections.singletonList("Sir Leye (level 20) with no items"); + return List.of( + new QuestRequirement(QuestHelperQuest.BLACK_KNIGHTS_FORTRESS, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED) + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(new QuestRequirement(QuestHelperQuest.BLACK_KNIGHTS_FORTRESS, QuestState.FINISHED)); - reqs.add(new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED)); - return reqs; + return List.of( + "Sir Leye (level 20) with no items" + ); } @Override @@ -369,69 +470,87 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Arrays.asList( - new ExperienceReward(Skill.PRAYER, 1000), - new ExperienceReward(Skill.AGILITY, 1000), - new ExperienceReward(Skill.HERBLORE, 1000)); + return List.of( + new ExperienceReward(Skill.PRAYER, 1000), + new ExperienceReward(Skill.AGILITY, 1000), + new ExperienceReward(Skill.HERBLORE, 1000) + ); } @Override public List getItemRewards() { - return Arrays.asList( - new ItemReward("Initiate Helm", ItemID.BASIC_TK_HELM, 1), - new ItemReward("Coins", ItemID.COINS, 3000)); + return List.of( + new ItemReward("Initiate Helm", ItemID.BASIC_TK_HELM, 1), + new ItemReward("Coins", ItemID.COINS, 3000) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Ability to respawn in Falador"), - new UnlockReward("Access to Initiate Armor")); + return List.of( + new UnlockReward("Ability to respawn in Falador"), + new UnlockReward("Access to Initiate Armor") + ); } @Override public List getPanels() { - List steps = new ArrayList<>(); - - PanelDetails startingPanel = new PanelDetails("Starting out", - new ArrayList<>(Collections.singletonList(conditionalTalkToSirAmikVarze))); - - PanelDetails testing = new PanelDetails("Start the testing", - Collections.singletonList(talkToSirTiffy), noItemRequirement); - - PanelDetails sirTinleysRoom = new PanelDetails("Sir Tinley", - Arrays.asList(talkToSirTinley, doNothingStep, leaveSirTinleyRoom)); - - List hynnSteps = new ArrayList<>(); - hynnSteps.add(talkToMsHynnTerprett); - hynnSteps.addAll(msHynnDialogQuiz.getPanelSteps()); - PanelDetails msHynnsRoom = new PanelDetails("Ms Hynn Terprett", hynnSteps); - - PanelDetails sirKuamRoom = new PanelDetails("Sir Kuam", - Arrays.asList(talkToSirKuam, killSirLeye, leaveSirKuamRoom)); - - PanelDetails sirSpishyusRoom = new PanelDetails("Sir Spishyus", - Arrays.asList(moveChickenOnRightToLeft, moveFoxOnRightToLeft, - moveChickenOnLeftToRight, moveGrainOnRightToLeft, moveChickenOnRightToLeftAgain)); - - PanelDetails sirRensRoom = new PanelDetails("Sir Ren Itchood", sirRenStep.getPanelSteps()); - - PanelDetails missCheeversRoom = new PanelDetails("Mis Cheevers", msCheevesSetup.GetPanelSteps()); - - PanelDetails ladyTable = new PanelDetails("Lady Table", ladyTableStep.getPanelSteps()); - - steps.add(startingPanel); - steps.add(testing); - steps.add(sirKuamRoom); - steps.add(sirSpishyusRoom); - steps.add(msHynnsRoom); - steps.add(sirTinleysRoom); - steps.add(sirRensRoom); - steps.add(missCheeversRoom); - steps.add(ladyTable); - return steps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting out", List.of( + cTalkToSirAmikVarze + ))); + + sections.add(new PanelDetails("Start the testing", List.of( + talkToSirTiffy + ), List.of( + noItemRequirement + ))); + + sections.add(new PanelDetails("Sir Tinley", List.of( + talkToSirTinley, + doNothingStep, + leaveSirTinleyRoom + ))); + + sections.add(new PanelDetails("Ms. Hynn Terprett", List.of( + pwMsHynnTerprett, + leaveMsHynnTerprettRoom + ))); + + sections.add(new PanelDetails("Sir Kuam Ferentse", List.of( + talkToSirKuam, + pwKillSirLeye, + leaveSirKuamRoom + ))); + + sections.add(new PanelDetails("Sir Spishyus", List.of( + pwSirSpishyusStep, + moveChickenOnRightToLeft, + moveFoxOnRightToLeft, + moveChickenOnLeftToRight, + moveGrainOnRightToLeft, + moveChickenOnRightToLeftAgain, + leaveSirSpishyusRoom + ))); + + sections.add(new PanelDetails("Sir Ren Itchood", + sirRenStep.getPanelSteps() + )); + + var missCheeversSection = new PanelDetails("Miss Cheevers", pwMissCheeversStep); + missCheeversSection.addSteps(missCheeversStep.getPanelSteps()); + missCheeversSection.addSteps(leaveMissCheeversRoom); + sections.add(missCheeversSection); + + sections.add(new PanelDetails("Lady Table", List.of( + pwLadyTableStep, + leaveLadyTableRoom + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java index b7c1e17cf30..1ef8b3219f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java @@ -27,31 +27,29 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.List; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.List; - public class SirRenItchoodStep extends ConditionalStep { - private String answer = null; - - private String[] answers = { + private final String[] answers = { "NULL", "TIME", "FISH", "RAIN", "BITE", "MEAT", "LAST" }; + private final QuestStep talkToRen; - private Requirement answerWidgetOpen; - private DoorPuzzle enterDoorcode; - private QuestStep talkToRen, openAnswerWidget, leaveRoom; - private VarbitRequirement finishedRoomCondition; + private DoorPuzzle enterDoorCode; + private PuzzleWrapperStep pwEnterDoorCode; + private QuestStep tryOpenDoor; + private QuestStep leaveRoom; public SirRenItchoodStep(QuestHelper questHelper, QuestStep step, Requirement... requirements) { @@ -71,42 +69,48 @@ public void startUp() return; } String answer = answers[answerID]; - enterDoorcode.updateWord(answer); + enterDoorCode.updateWord(answer); } @Override public void onVarbitChanged(VarbitChanged varbitChanged) { super.onVarbitChanged(varbitChanged); - int answerID = client.getVarbitValue(VarbitID.RD_TEMPLOCK_1); + + if (varbitChanged.getVarbitId() != VarbitID.RD_TEMPLOCK_1) + { + return; + } + var answerID = varbitChanged.getValue(); if (answerID == 0) { return; } - String answer = answers[answerID]; - enterDoorcode.updateWord(answer); + var answer = answers[answerID]; + enterDoorCode.updateWord(answer); } private void addRenSteps() { - finishedRoomCondition = new VarbitRequirement(VarbitID.RD_ROOM5_COMPLETE, 1); - openAnswerWidget = new ObjectStep(questHelper, ObjectID.RD_ROOM5_EXITDOOR, "Open the door to be prompted to enter a code."); - answerWidgetOpen = new WidgetTextRequirement(285, 55, "Combination Lock Door"); - enterDoorcode = new DoorPuzzle(questHelper, "NONE"); + var finishedRoomCondition = new VarbitRequirement(VarbitID.RD_ROOM5_COMPLETE, 1); + var answerWidgetOpen = new WidgetTextRequirement(InterfaceID.RdCombolock.RDCOMBOLOCK, "Combination Lock Door"); + tryOpenDoor = new ObjectStep(questHelper, ObjectID.RD_ROOM5_EXITDOOR, "Open the door to be prompted to enter a code."); + enterDoorCode = new DoorPuzzle(questHelper, "NONE"); + pwEnterDoorCode = enterDoorCode.puzzleWrapStepWithDefaultText("Solve the door combination lock using the hints from Sir Ren Itchood."); leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM5_EXITDOOR, "Leave through the door to enter the portal and continue."); addStep(finishedRoomCondition, leaveRoom); - addStep(new Conditions(answerWidgetOpen), enterDoorcode); - addStep(null, openAnswerWidget); + addStep(answerWidgetOpen, pwEnterDoorCode); + addStep(null, tryOpenDoor); } public List getPanelSteps() { - List steps = new ArrayList<>(); - steps.add(talkToRen); - steps.add(openAnswerWidget); - steps.add(enterDoorcode); - steps.add(leaveRoom); - return steps; + return List.of( + talkToRen, + tryOpenDoor, + pwEnterDoorCode, + leaveRoom + ); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java index 8ef44238f4f..a3429528a95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; @@ -34,17 +35,14 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; public class RomeoAndJuliet extends BasicQuestHelper { @@ -151,7 +149,7 @@ public Map loadSteps() steps.put(50, bringPotionToJuliet); var cFinishQuest = new ConditionalStep(this, finishQuest); - cFinishQuest.addStep(inJulietRoom, goDownstairsToFinishQuest); + giveLetterToRomeo.addStep(inJulietRoom, goDownstairsToFinishQuest); steps.put(60, cFinishQuest); return steps; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java index c09884adb5a..ec48d061e4b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java @@ -29,6 +29,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,19 +41,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class RuneMysteries extends BasicQuestHelper { // Recommended items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java index c9f9666182c..a72acc34f32 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java @@ -6,19 +6,27 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -26,71 +34,82 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class ScorpionCatcher extends BasicQuestHelper { - ItemRequirement dustyKey, jailKey, scorpionCageMissingTaverley, scorpionCageMissingMonastery, scorpionCageEmptyOrTaverley, scorpionCageTaverleyAndMonastery, scorpionCageFull, food, - antiDragonShield, antiPoison, teleRunesFalador, gamesNecklace, gloryOrCombatBracelet, camelotTeleport; - QuestRequirement fairyRingAccess; - Zone sorcerersTower3, sorcerersTower2, sorcerersTower1, taverleyDungeon, deepTaverleyDungeon1, deepTaverleyDungeon2, deepTaverleyDungeon3, deepTaverleyDungeon4, - jailCell, taverleyScorpionRoom, upstairsMonastery, barbarianOutpost; - Requirement has70Agility, has80Agility, inTaverleyDungeon, inDeepTaverleyDungeon, inJailCell, inSorcerersTower1, inSorcerersTower2, - inSorcerersTower3, inTaverleyScorpionRoom, inUpstairsMonastery, inBarbarianOutpost, jailKeyNearby; - QuestStep speakToThormac, speakToSeer1, enterTaverleyDungeon, goThroughPipe, goOverStrangeFloor, killJailerForKey, - getDustyFromAdventurer, enterDeeperTaverley, pickUpJailKey, - searchOldWall, catchTaverleyScorpion, sorcerersTowerLadder0, sorcerersTowerLadder1, sorcerersTowerLadder2, enterMonastery, catchMonasteryScorpion, - catchOutpostScorpion, enterOutpost, returnToThormac; - + // Required items + ItemRequirement dustyKey; + + // Recommended items + ItemRequirement antiDragonShield; + ItemRequirement antiPoison; + ItemRequirement food; + ItemRequirement teleRunesFalador; + ItemRequirement camelotTeleport; + ItemRequirement gamesNecklace; + ItemRequirement gloryOrCombatBracelet; + + // Mid-quest item requirements + ItemRequirement jailKey; + ItemRequirement scorpionCageMissingTaverley; + ItemRequirement scorpionCageMissingMonastery; + ItemRequirement scorpionCageEmptyOrTaverley; + ItemRequirement scorpionCageTaverleyAndMonastery; + ItemRequirement scorpionCageFull; + + // Zones + Zone sorcerersTower3; + Zone sorcerersTower2; + Zone sorcerersTower1; + Zone taverleyDungeon; + Zone deepTaverleyDungeon1; + Zone deepTaverleyDungeon2; + Zone deepTaverleyDungeon3; + Zone deepTaverleyDungeon4; + Zone jailCell; + Zone taverleyScorpionRoom; + Zone upstairsMonastery; + Zone barbarianOutpost; + + // Miscellaneous requirements + SkillRequirement has70Agility; + SkillRequirement has80Agility; + ZoneRequirement inTaverleyDungeon; + ZoneRequirement inDeepTaverleyDungeon; + ZoneRequirement inJailCell; + ZoneRequirement inSorcerersTower1; + ZoneRequirement inSorcerersTower2; + ZoneRequirement inSorcerersTower3; + ZoneRequirement inTaverleyScorpionRoom; + ZoneRequirement inUpstairsMonastery; + ZoneRequirement inBarbarianOutpost; + ItemOnTileRequirement jailKeyNearby; + + // Steps + ObjectStep sorcerersTowerLadder0; + ObjectStep sorcerersTowerLadder1; + ObjectStep sorcerersTowerLadder2; + ConditionalStep goToTopOfTower; + + ConditionalStep beginQuest; + NpcStep speakToThormac; + + NpcStep speakToSeer1; + QuestStep enterTaverleyDungeon; + ObjectStep goThroughPipe; + ObjectStep goOverStrangeFloor; + NpcStep killJailerForKey; + NpcStep getDustyFromAdventurer; + ObjectStep enterDeeperTaverley; + ItemStep pickUpJailKey; + ObjectStep searchOldWall; + NpcStep catchTaverleyScorpion; + ObjectStep enterMonastery; + NpcStep catchMonasteryScorpion; + NpcStep catchOutpostScorpion; + ObjectStep enterOutpost; + NpcStep returnToThormac; ConditionalStep finishQuest; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - - Map steps = new HashMap<>(); - - ConditionalStep goToTopOfTower = new ConditionalStep(this, sorcerersTowerLadder0); - goToTopOfTower.addStep(inSorcerersTower1, sorcerersTowerLadder1); - goToTopOfTower.addStep(inSorcerersTower2, sorcerersTowerLadder2); - - ConditionalStep beginQuest = new ConditionalStep(this, goToTopOfTower); - beginQuest.addStep(inSorcerersTower3, speakToThormac); - - finishQuest = new ConditionalStep(this, goToTopOfTower, - "Return to Thormac to finish the quest.", scorpionCageFull); - finishQuest.addStep(inSorcerersTower3, returnToThormac); - - ConditionalStep goGetTaverleyScorpion = new ConditionalStep(this, enterTaverleyDungeon); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyScorpionRoom), catchTaverleyScorpion); - goGetTaverleyScorpion.addStep(new Conditions(inDeepTaverleyDungeon), searchOldWall); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, has80Agility), goOverStrangeFloor); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, has70Agility), goThroughPipe); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, dustyKey), enterDeeperTaverley); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, new Conditions(LogicType.OR, inJailCell, jailKey)), getDustyFromAdventurer); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, jailKeyNearby), pickUpJailKey); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon), killJailerForKey); - - ConditionalStep scorpions = new ConditionalStep(this, finishQuest); - scorpions.addStep(scorpionCageMissingTaverley.alsoCheckBank(), goGetTaverleyScorpion); - - scorpions.addStep(new Conditions(scorpionCageMissingMonastery, inUpstairsMonastery), catchMonasteryScorpion); - scorpions.addStep(scorpionCageMissingMonastery.alsoCheckBank(), enterMonastery); - - scorpions.addStep(new Conditions(scorpionCageTaverleyAndMonastery, inBarbarianOutpost), catchOutpostScorpion); - scorpions.addStep(scorpionCageTaverleyAndMonastery.alsoCheckBank(), enterOutpost); - - steps.put(0, beginQuest); - steps.put(1, speakToSeer1); - steps.put(2, scorpions); - steps.put(3, scorpions); - - return steps; - } - @Override protected void setupZones() { @@ -114,8 +133,13 @@ protected void setupZones() @Override protected void setupRequirements() { - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + has70Agility = new SkillRequirement(Skill.AGILITY, 70, true); + has80Agility = new SkillRequirement(Skill.AGILITY, 80, true); + + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).isNotConsumed(); dustyKey.setTooltip("Not needed if you have level 70 Agility, can be obtained during the quest"); + dustyKey.setConditionToHide(has70Agility); + jailKey = new ItemRequirement("Jail Key", ItemID.JAIL_KEY); scorpionCageMissingTaverley = new ItemRequirement("Scorpion Cage", ItemID.SCORPIONCAGEEMPTY); @@ -143,15 +167,6 @@ protected void setupRequirements() gamesNecklace = new ItemRequirement("Games Necklace", ItemCollections.GAMES_NECKLACES); gloryOrCombatBracelet = new ItemRequirement("A charged glory or a combat bracelet", ItemCollections.AMULET_OF_GLORIES); gloryOrCombatBracelet.addAlternates(ItemCollections.COMBAT_BRACELETS); - fairyRingAccess = new QuestRequirement(QuestHelperQuest.FAIRYTALE_II__CURE_A_QUEEN, QuestState.IN_PROGRESS, "Fairy ring access"); - fairyRingAccess.setTooltip(QuestHelperQuest.FAIRYTALE_II__CURE_A_QUEEN.getName() + " is required to at least be started in order to use fairy rings"); - - } - - private void setupConditions() - { - has70Agility = new SkillRequirement(Skill.AGILITY, 70, true); - has80Agility = new SkillRequirement(Skill.AGILITY, 80, true); inSorcerersTower1 = new ZoneRequirement(sorcerersTower1); inSorcerersTower2 = new ZoneRequirement(sorcerersTower2); @@ -170,34 +185,26 @@ private void setupConditions() private void setupSteps() { - speakToThormac = new NpcStep(this, NpcID.THORMAC, new WorldPoint(2702, 3405, 3), "Speak to Thormac on the top floor of the Sorcerer's Tower south of Seer's Village."); + sorcerersTowerLadder0 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2701, 3408, 0), "Climb to the top of the Sorcerer's Tower south of Seers' Village."); + sorcerersTowerLadder1 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2704, 3403, 1), "Climb to the top of the Sorcerer's Tower south of Seers' Village."); + sorcerersTowerLadder2 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2699, 3405, 2), "Climb to the top of the Sorcerer's Tower south of Seers' Village."); + + goToTopOfTower = new ConditionalStep(this, sorcerersTowerLadder0); + goToTopOfTower.addStep(inSorcerersTower1, sorcerersTowerLadder1); + goToTopOfTower.addStep(inSorcerersTower2, sorcerersTowerLadder2); + + speakToThormac = new NpcStep(this, NpcID.THORMAC, new WorldPoint(2702, 3405, 3), ""); speakToThormac.addDialogStep("What do you need assistance with?"); - speakToThormac.addDialogStep("So how would I go about catching them then?"); - speakToThormac.addDialogStep("Ok, I will do it then"); - - sorcerersTowerLadder0 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2701, 3408, 0), - "Climb to the top of the Sorcerer's Tower south of Seers' Village."); - sorcerersTowerLadder1 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2704, 3403, 1), - "Climb to the top of the Sorcerer's Tower south of Seers' Village."); - sorcerersTowerLadder2 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2699, 3405, 2), - "Climb to the top of the Sorcerer's Tower south of Seers' Village."); - speakToThormac.addSubSteps(sorcerersTowerLadder0, sorcerersTowerLadder1, sorcerersTowerLadder2); - - speakToSeer1 = new NpcStep(this, NpcID.SEER, new WorldPoint(2710, 3484, 0), - "Speak to a seer in Seer's Village."); + speakToThormac.addDialogStep("Yes."); + + beginQuest = new ConditionalStep(this, goToTopOfTower, "Speak to Thormac on the top floor of the Sorcerer's Tower south of Seer's Village."); + beginQuest.addStep(inSorcerersTower3, speakToThormac); + + speakToSeer1 = new NpcStep(this, NpcID.SEER, new WorldPoint(2710, 3484, 0), "Speak to a seer in Seer's Village."); speakToSeer1.addDialogStep("I need to locate some scorpions."); speakToSeer1.addDialogStep("Your friend Thormac sent me to speak to you."); - if (client.getRealSkillLevel(Skill.AGILITY) >= 70) - { - enterTaverleyDungeon = new ObjectStep(this, ObjectID.LADDER_OUTSIDE_TO_UNDERGROUND, new WorldPoint(2884, 3397, 0), - "Go to Taverley Dungeon. As you're 70 Agility, you don't need a dusty key.", scorpionCageMissingTaverley); - } - else - { - enterTaverleyDungeon = new ObjectStep(this, ObjectID.LADDER_OUTSIDE_TO_UNDERGROUND, new WorldPoint(2884, 3397, 0), - "Go to Taverley Dungeon. Bring a dusty key if you have one, otherwise you can get one in the dungeon.", scorpionCageMissingTaverley, dustyKey); - } + enterTaverleyDungeon = new ObjectStep(this, ObjectID.LADDER_OUTSIDE_TO_UNDERGROUND, new WorldPoint(2884, 3397, 0), "Go to Taverley Dungeon.", scorpionCageMissingTaverley, dustyKey); goOverStrangeFloor = new ObjectStep(this, ObjectID.TAVERLY_DUNGEON_FLOOR_SPIKES_SC, new WorldPoint(2879, 9813, 0), "Go over the strange floor."); @@ -212,53 +219,99 @@ private void setupSteps() getDustyFromAdventurer.addDialogStep("Yes please!"); enterDeeperTaverley = new ObjectStep(this, ObjectID.DEEPDUNGEONDOOR, new WorldPoint(2924, 9803, 0), "Enter the gate to the deeper Taverley dungeon.", dustyKey); - enterTaverleyDungeon.addSubSteps(goThroughPipe, goOverStrangeFloor, killJailerForKey, getDustyFromAdventurer, enterDeeperTaverley); + enterTaverleyDungeon.addSubSteps(goThroughPipe, goOverStrangeFloor, killJailerForKey, pickUpJailKey, getDustyFromAdventurer, enterDeeperTaverley); searchOldWall = new ObjectStep(this, ObjectID.SCORPIONWALL, new WorldPoint(2875, 9799, 0), "Search the Old wall."); - // TODO: Highlight item - catchTaverleyScorpion = new NpcStep(this, NpcID.QUESTSCORPIONA, "Use the scorpion cage on the scorpion.", scorpionCageMissingTaverley); + catchTaverleyScorpion = new NpcStep(this, NpcID.QUESTSCORPIONA, "Use the scorpion cage on the scorpion.", scorpionCageMissingTaverley.highlighted()); catchTaverleyScorpion.addIcon(ItemID.SCORPIONCAGEEMPTY); - enterMonastery = new ObjectStep(this, ObjectID.MONASTERYLADDER, new WorldPoint(3057, 3483, 0), - "Enter the Edgeville Monastery."); - // TODO: Highlight item - catchMonasteryScorpion = new NpcStep(this, NpcID.QUESTSCORPIONC, "Use the scorpion cage on the scorpion.", - scorpionCageMissingMonastery); + enterMonastery = new ObjectStep(this, ObjectID.MONASTERYLADDER, new WorldPoint(3057, 3483, 0), "Enter the Edgeville Monastery."); + enterMonastery.addDialogStep("Well can I join your order?"); + catchMonasteryScorpion = new NpcStep(this, NpcID.QUESTSCORPIONC, "Use the scorpion cage on the scorpion.", scorpionCageMissingMonastery.highlighted()); catchMonasteryScorpion.addIcon(ItemID.SCORPIONCAGEEMPTY); - enterOutpost = new ObjectStep(this, ObjectID.BARBARIANGATEL, new WorldPoint(2545, 3570, 0), - "Enter the Barbarian Outpost."); - // TODO: Highlight item - catchOutpostScorpion = new NpcStep(this, NpcID.QUESTSCORPIONB, new WorldPoint(2553, 3570, 0), - "Use the scorpion cage on the scorpion.", scorpionCageTaverleyAndMonastery); + enterOutpost = new ObjectStep(this, ObjectID.BARBARIANGATEL, new WorldPoint(2545, 3570, 0), "Enter the Barbarian Outpost."); + catchOutpostScorpion = new NpcStep(this, NpcID.QUESTSCORPIONB, new WorldPoint(2553, 3570, 0), "Use the scorpion cage on the scorpion.", scorpionCageTaverleyAndMonastery.highlighted()); catchOutpostScorpion.addIcon(ItemID.SCORPIONCAGEEMPTY); - returnToThormac = new NpcStep(this, NpcID.THORMAC, - "", scorpionCageFull); + returnToThormac = new NpcStep(this, NpcID.THORMAC, "", scorpionCageFull); + + finishQuest = new ConditionalStep(this, goToTopOfTower, "Return to Thormac to finish the quest.", scorpionCageFull); + finishQuest.addStep(inSorcerersTower3, returnToThormac); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, beginQuest); + steps.put(1, speakToSeer1); + + var goGetTaverleyScorpion = new ConditionalStep(this, enterTaverleyDungeon); + goGetTaverleyScorpion.addStep(and(inTaverleyScorpionRoom), catchTaverleyScorpion); + goGetTaverleyScorpion.addStep(and(inDeepTaverleyDungeon), searchOldWall); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, has80Agility), goOverStrangeFloor); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, has70Agility), goThroughPipe); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, dustyKey), enterDeeperTaverley); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, or(inJailCell, jailKey)), getDustyFromAdventurer); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, jailKeyNearby), pickUpJailKey); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon), killJailerForKey); + + var scorpions = new ConditionalStep(this, finishQuest); + scorpions.addStep(scorpionCageMissingTaverley.alsoCheckBank(), goGetTaverleyScorpion); + + scorpions.addStep(and(scorpionCageMissingMonastery, inUpstairsMonastery), catchMonasteryScorpion); + scorpions.addStep(scorpionCageMissingMonastery.alsoCheckBank(), enterMonastery); + + scorpions.addStep(and(scorpionCageTaverleyAndMonastery, inBarbarianOutpost), catchOutpostScorpion); + scorpions.addStep(scorpionCageTaverleyAndMonastery.alsoCheckBank(), enterOutpost); + + steps.put(2, scorpions); + steps.put(3, scorpions); + + return steps; } @Override - public ArrayList getItemRequirements() + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - if (client.getRealSkillLevel(Skill.AGILITY) < 70) - { - reqs.add(dustyKey); - } + return List.of( + new QuestRequirement(QuestHelperQuest.ALFRED_GRIMHANDS_BARCRAWL, QuestState.FINISHED), + new SkillRequirement(Skill.PRAYER, 31) + ); + } - return reqs.isEmpty() ? null : reqs; + @Override + public List getItemRequirements() + { + return List.of( + dustyKey + ); } @Override - public ArrayList getItemRecommended() + public List getItemRecommended() { - return new ArrayList<>(Arrays.asList(antiDragonShield, antiPoison, food, teleRunesFalador, camelotTeleport, gamesNecklace, - gloryOrCombatBracelet)); + return List.of( + antiDragonShield, + antiPoison, + food, + teleRunesFalador, + camelotTeleport, + gamesNecklace, + gloryOrCombatBracelet + ); } @Override - public ArrayList getCombatRequirements() + public List getCombatRequirements() { - return new ArrayList<>(Collections.singletonList("The ability to run past level 172 black demons and level 64 poison spiders")); + return List.of( + "The ability to run past level 172 black demons and level 64 poison spiders" + ); } @Override @@ -270,36 +323,52 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.STRENGTH, 6625)); + return List.of( + new ExperienceReward(Skill.STRENGTH, 6625) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Ability to have Thormac turn a Battlestaff into a Mystic Staff for 40,000 Coins.")); + return List.of( + new UnlockReward("Ability to have Thormac turn a Battlestaff into a Mystic Staff for 40,000 Coins.") + ); } @Override - public ArrayList getPanels() + public List getPanels() { - ArrayList allSteps = new ArrayList<>(); - - allSteps.add(new PanelDetails("Talk to Thormac", new ArrayList<>(Collections.singletonList(speakToThormac)))); - allSteps.add(new PanelDetails("The first scorpion", new ArrayList<>(Arrays.asList(speakToSeer1, enterTaverleyDungeon, searchOldWall, catchTaverleyScorpion)))); - allSteps.add(new PanelDetails("The second scorpion", new ArrayList<>(Arrays.asList(enterMonastery, catchMonasteryScorpion)))); - allSteps.add(new PanelDetails("The third scorpion", new ArrayList<>(Arrays.asList(enterOutpost, catchOutpostScorpion)))); - allSteps.add(new PanelDetails("Finishing up", new ArrayList<>(Collections.singletonList(finishQuest)))); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Talk to Thormac", List.of( + beginQuest + ))); + + sections.add(new PanelDetails("The first scorpion", List.of( + speakToSeer1, + enterTaverleyDungeon, + searchOldWall, + catchTaverleyScorpion + ), List.of( + dustyKey + ))); + + sections.add(new PanelDetails("The second scorpion", List.of( + enterMonastery, + catchMonasteryScorpion + ))); + + sections.add(new PanelDetails("The third scorpion", List.of( + enterOutpost, + catchOutpostScorpion + ))); + + sections.add(new PanelDetails("Finishing up", List.of( + finishQuest + ))); + + return sections; } - @Override - public ArrayList getGeneralRequirements() - { - ArrayList reqs = new ArrayList<>(); - reqs.add(new QuestRequirement(QuestHelperQuest.ALFRED_GRIMHANDS_BARCRAWL, QuestState.FINISHED)); - reqs.add(new SkillRequirement(Skill.PRAYER, 31)); - - return reqs; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java index 0e7d7940a20..d69b6fa6d34 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java @@ -32,15 +32,14 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.awt.*; +import java.util.List; +import javax.annotation.Nullable; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.widgets.Widget; -import javax.annotation.Nullable; -import java.awt.*; -import java.util.List; - @Slf4j public class EggSolver extends DetailedOwnerStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java index 69ed9eef58e..cd2246d6566 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcHintArrowRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; @@ -43,10 +44,6 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.QuestState; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; import java.util.ArrayList; import java.util.HashMap; @@ -54,7 +51,17 @@ import java.util.Map; import java.util.regex.Pattern; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.QuestState; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.VarbitID; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; /** * The quest guide for the "Scrambled" OSRS quest diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java index 4804a8acf8c..63e4083bac6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java @@ -27,45 +27,151 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class SeaSlug extends BasicQuestHelper { - //Items Required - ItemRequirement swampPaste, glass, dampSticks, torch, litTorch, drySticks; + // Required items + ItemRequirement swampPaste; + + // Mid-quest requirements + ItemRequirement glass; + ItemRequirement dampSticks; + ItemRequirement torch; + ItemRequirement litTorch; + ItemRequirement drySticks; + + // Zones + Zone platformFirstFloor; + Zone platformGroundFloor; + Zone island; + + // Miscellaneous requirements + ZoneRequirement onPlatformGroundFloor; + ZoneRequirement onPlatformFirstFloor; + ZoneRequirement onPlatform; + ZoneRequirement onIsland; + + // Steps + NpcStep talkToCaroline; + NpcStep talkToHolgart; + NpcStep talkToHolgartWithSwampPaste; + NpcStep travelWithHolgart; + DetailedQuestStep pickupGlass; + DetailedQuestStep pickupDampSticks; + ObjectStep climbLadder; + NpcStep talkToKennith; + ObjectStep goDownLadder; + NpcStep goToIsland; + NpcStep goToIslandFromMainland; + NpcStep talkToKent; + NpcStep returnFromIsland; + NpcStep talkToBaileyForTorch; + DetailedQuestStep useGlassOnDampSticks; + DetailedQuestStep rubSticks; + ObjectStep goBackUpLadder; + NpcStep talkToKennithAgain; + ObjectStep kickWall; + NpcStep talkToKennithAfterKicking; + ObjectStep activateCrane; + ObjectStep goDownLadderAgain; + NpcStep returnWithHolgart; + NpcStep finishQuest; + NpcStep travelWithHolgartFreeingKennith; - Requirement onPlatformGroundFloor, onPlatformFirstFloor, onPlatform, onIsland; + @Override + protected void setupZones() + { + platformGroundFloor = new Zone(new WorldPoint(2760, 3271, 0), new WorldPoint(2795, 3293, 0)); + platformFirstFloor = new Zone(new WorldPoint(2760, 3271, 1), new WorldPoint(2795, 3293, 1)); + island = new Zone(new WorldPoint(2787, 3312, 0), new WorldPoint(2802, 3327, 0)); + } - QuestStep talkToCaroline, talkToHolgart, talkToHolgartWithSwampPaste, travelWithHolgart, pickupGlass, pickupDampSticks, - climbLadder, talkToKennith, goDownLadder, goToIsland, goToIslandFromMainland, talkToKent, returnFromIsland, talkToBaileyForTorch, useGlassOnDampSticks, - rubSticks, goBackUpLadder, talkToKennithAgain, kickWall, talkToKennithAfterKicking, activateCrane, goDownLadderAgain, - returnWithHolgart, finishQuest, travelWithHolgartFreeingKennith; + @Override + protected void setupRequirements() + { + swampPaste = new ItemRequirement("Swamp paste", ItemID.SWAMPPASTE); + dampSticks = new ItemRequirement("Damp sticks", ItemID.DAMP_STICKS); + dampSticks.setHighlightInInventory(true); + drySticks = new ItemRequirement("Dry sticks", ItemID.DRY_STICKS); + drySticks.setHighlightInInventory(true); + torch = new ItemRequirement("Unlit torch", ItemID.TORCH_UNLIT); + litTorch = new ItemRequirement("Lit torch", ItemID.TORCH_LIT); + glass = new ItemRequirement("Broken glass", ItemID.BROKEN_GLASS); + glass.setHighlightInInventory(true); - //Zones - Zone platformFirstFloor, platformGroundFloor, island; + onPlatformFirstFloor = new ZoneRequirement(platformFirstFloor); + onPlatformGroundFloor = new ZoneRequirement(platformGroundFloor); + onPlatform = new ZoneRequirement(platformFirstFloor, platformGroundFloor); + onIsland = new ZoneRequirement(island); + } + + public void setupSteps() + { + talkToCaroline = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline just north of Witchaven, east of East Ardougne."); + talkToCaroline.addDialogStep("Yes."); + talkToHolgart = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Talk to Holgart nearby and give him some swamp paste.", swampPaste); + talkToHolgartWithSwampPaste = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Give Holgart some swamp paste.", swampPaste); + talkToHolgart.addSubSteps(talkToHolgartWithSwampPaste); + travelWithHolgart = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart to the fishing platform."); + travelWithHolgart.addDialogStep("Will you take me there?"); + climbLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Climb the ladder in the north east corner of the platform."); + talkToKennith = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith from inside the cabin on the west side of the first floor."); + goDownLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); + goToIsland = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart to a nearby island."); + goToIslandFromMainland = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart north of Witchaven to find Kent."); + goToIsland.addSubSteps(goToIslandFromMainland); + + talkToKent = new NpcStep(this, NpcID.KENT, new WorldPoint(2794, 3322, 0), "Talk to Kent on the island."); + returnFromIsland = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2801, 3320, 0), "Return to the platform with Holgart."); + travelWithHolgartFreeingKennith = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2717, 3303, 0), + "Travel with Holgart to the fishing platform."); + returnFromIsland.addSubSteps(travelWithHolgartFreeingKennith); + + talkToBaileyForTorch = new NpcStep(this, NpcID.BAILEY, new WorldPoint(2764, 3275, 0), "Talk to Bailey for an unlit torch."); + pickupGlass = new DetailedQuestStep(this, "Pick up the broken glass in the room.", glass); + pickupDampSticks = new DetailedQuestStep(this, new WorldPoint(2784, 3289, 0), "Pick up the damp sticks in the north east corner of the platform.", dampSticks); + useGlassOnDampSticks = new DetailedQuestStep(this, "Use the broken glass on damp sticks to dry them.", glass, dampSticks); + rubSticks = new DetailedQuestStep(this, "Rub the dry sticks to light the unlit torch.", drySticks.highlighted()); + goBackUpLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Go up the ladder in the north east corner of the platform."); + talkToKennithAgain = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith to the west."); + kickWall = new ObjectStep(this, ObjectID.SLUG_BREAKABLE_PANEL, new WorldPoint(2768, 3289, 1), "Kick in the badly repaired wall east of Kennith."); + talkToKennithAfterKicking = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith again."); + activateCrane = new ObjectStep(this, ObjectID.SEASLUG_CRANE, new WorldPoint(2772, 3289, 1), "Rotate the crane east of Kennith's cabin."); + goDownLadderAgain = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); + returnWithHolgart = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart back to the mainland."); + finishQuest = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline to complete the quest."); + } @Override public Map loadSteps() { initializeRequirements(); - setupConditions(); setupSteps(); - Map steps = new HashMap<>(); + + var steps = new HashMap(); steps.put(0, talkToCaroline); @@ -73,57 +179,57 @@ public Map loadSteps() steps.put(2, talkToHolgartWithSwampPaste); - ConditionalStep investigateThePlatform = new ConditionalStep(this, travelWithHolgart); + var investigateThePlatform = new ConditionalStep(this, travelWithHolgart); investigateThePlatform.addStep(onPlatformFirstFloor, talkToKennith); investigateThePlatform.addStep(onPlatformGroundFloor, climbLadder); steps.put(3, investigateThePlatform); - ConditionalStep goFindKent = new ConditionalStep(this, travelWithHolgart); + var goFindKent = new ConditionalStep(this, travelWithHolgart); goFindKent.addStep(onPlatformGroundFloor, goToIsland); goFindKent.addStep(onPlatformFirstFloor, goDownLadder); steps.put(4, goFindKent); - ConditionalStep talkWithKent = new ConditionalStep(this, goToIslandFromMainland); + var talkWithKent = new ConditionalStep(this, goToIslandFromMainland); talkWithKent.addStep(onIsland, talkToKent); steps.put(5, talkWithKent); - ConditionalStep goToFirstFloor = new ConditionalStep(this, travelWithHolgartFreeingKennith); - goToFirstFloor.addStep(new Conditions(litTorch), goBackUpLadder); - goToFirstFloor.addStep(new Conditions(torch, drySticks), rubSticks); - goToFirstFloor.addStep(new Conditions(torch, glass, dampSticks), useGlassOnDampSticks); - goToFirstFloor.addStep(new Conditions(torch, glass), pickupDampSticks); - goToFirstFloor.addStep(new Conditions(torch), pickupGlass); + var goToFirstFloor = new ConditionalStep(this, travelWithHolgartFreeingKennith); + goToFirstFloor.addStep(litTorch, goBackUpLadder); + goToFirstFloor.addStep(and(torch, drySticks), rubSticks); + goToFirstFloor.addStep(and(torch, glass, dampSticks), useGlassOnDampSticks); + goToFirstFloor.addStep(and(torch, glass), pickupDampSticks); + goToFirstFloor.addStep(torch, pickupGlass); goToFirstFloor.addStep(onPlatform, talkToBaileyForTorch); - ConditionalStep lightTheTorch = new ConditionalStep(this, goToFirstFloor); + var lightTheTorch = new ConditionalStep(this, goToFirstFloor); lightTheTorch.addStep(onIsland, returnFromIsland); steps.put(6, lightTheTorch); - ConditionalStep freeKennith = new ConditionalStep(this, goToFirstFloor); + var freeKennith = new ConditionalStep(this, goToFirstFloor); freeKennith.addStep(onPlatformFirstFloor, talkToKennithAgain); steps.put(7, freeKennith); - ConditionalStep breakWall = new ConditionalStep(this, goToFirstFloor); + var breakWall = new ConditionalStep(this, goToFirstFloor); breakWall.addStep(onPlatformFirstFloor, kickWall); steps.put(8, breakWall); - ConditionalStep tellKennethYouBrokeWall = new ConditionalStep(this, goToFirstFloor); + var tellKennethYouBrokeWall = new ConditionalStep(this, goToFirstFloor); tellKennethYouBrokeWall.addStep(onPlatformFirstFloor, talkToKennithAfterKicking); steps.put(9, tellKennethYouBrokeWall); - ConditionalStep turnTheCrane = new ConditionalStep(this, goToFirstFloor); + var turnTheCrane = new ConditionalStep(this, goToFirstFloor); turnTheCrane.addStep(onPlatformFirstFloor, activateCrane); steps.put(10, turnTheCrane); - ConditionalStep finishUp = new ConditionalStep(this, finishQuest); + var finishUp = new ConditionalStep(this, finishQuest); finishUp.addStep(onPlatformGroundFloor, returnWithHolgart); finishUp.addStep(onPlatformFirstFloor, goDownLadderAgain); @@ -133,85 +239,27 @@ public Map loadSteps() } @Override - protected void setupRequirements() - { - swampPaste = new ItemRequirement("Swamp paste", ItemID.SWAMPPASTE); - dampSticks = new ItemRequirement("Damp sticks", ItemID.DAMP_STICKS); - dampSticks.setHighlightInInventory(true); - drySticks = new ItemRequirement("Dry sticks", ItemID.DRY_STICKS); - drySticks.setHighlightInInventory(true); - torch = new ItemRequirement("Unlit torch", ItemID.TORCH_UNLIT); - litTorch = new ItemRequirement("Lit torch", ItemID.TORCH_LIT); - glass = new ItemRequirement("Broken glass", ItemID.BROKEN_GLASS); - glass.setHighlightInInventory(true); - - } - - @Override - protected void setupZones() - { - platformGroundFloor = new Zone(new WorldPoint(2760, 3271, 0), new WorldPoint(2795, 3293, 0)); - platformFirstFloor = new Zone(new WorldPoint(2760, 3271, 1), new WorldPoint(2795, 3293, 1)); - island = new Zone(new WorldPoint(2787, 3312, 0), new WorldPoint(2802, 3327, 0)); - } - - public void setupConditions() - { - onPlatformFirstFloor = new ZoneRequirement(platformFirstFloor); - onPlatformGroundFloor = new ZoneRequirement(platformGroundFloor); - onPlatform = new ZoneRequirement(platformFirstFloor, platformGroundFloor); - onIsland = new ZoneRequirement(island); - } - - public void setupSteps() + public List getGeneralRequirements() { - talkToCaroline = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline just north of Witchaven, east of East Ardougne."); - talkToCaroline.addDialogStep("I suppose so, how do I get there?"); - talkToHolgart = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Talk to Holgart nearby and give him some swamp paste.", swampPaste); - talkToHolgartWithSwampPaste = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Give Holgart some swamp paste.", swampPaste); - talkToHolgart.addSubSteps(talkToHolgartWithSwampPaste); - travelWithHolgart = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart to the fishing platform."); - travelWithHolgart.addDialogStep("Will you take me there?"); - climbLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Climb the ladder in the north east corner of the platform."); - talkToKennith = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith from inside the cabin on the west side of the first floor."); - goDownLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); - goToIsland = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart to a nearby island."); - goToIslandFromMainland = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart north of Witchaven to find Kent."); - goToIsland.addSubSteps(goToIsland); - - talkToKent = new NpcStep(this, NpcID.KENT, new WorldPoint(2794, 3322, 0), "Talk to Kent on the island."); - returnFromIsland = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2801, 3320, 0), "Return to the platform with Holgart."); - travelWithHolgartFreeingKennith = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2717, 3303, 0), - "Travel with Holgart to the fishing platform."); - returnFromIsland.addSubSteps(travelWithHolgartFreeingKennith); - - talkToBaileyForTorch = new NpcStep(this, NpcID.BAILEY, new WorldPoint(2764, 3275, 0), "Talk to Bailey for an unlit torch."); - pickupGlass = new DetailedQuestStep(this, "Pick up the broken glass in the room.", glass); - pickupDampSticks = new DetailedQuestStep(this, new WorldPoint(2784, 3289, 0), "Pick up the damp sticks in the north east corner of the platform.", dampSticks); - useGlassOnDampSticks = new DetailedQuestStep(this, "Use the broken glass on damp sticks to dry them.", glass, dampSticks); - rubSticks = new DetailedQuestStep(this, "Rub the dry sticks to light the unlit torch."); - goBackUpLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Go up the ladder in the north east corner of the platform."); - talkToKennithAgain = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith to the west."); - kickWall = new ObjectStep(this, ObjectID.SLUG_BREAKABLE_PANEL, new WorldPoint(2768, 3289, 1), "Kick in the badly repaired wall east of Kennith."); - talkToKennithAfterKicking = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith again."); - activateCrane = new ObjectStep(this, ObjectID.SEASLUG_CRANE, new WorldPoint(2772, 3289, 1), "Rotate the crane east of Kennith's cabin."); - goDownLadderAgain = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); - returnWithHolgart = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart back to the mainland."); - finishQuest = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline to complete the quest."); + return List.of( + new SkillRequirement(Skill.FIREMAKING, 30, true) + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(swampPaste); - return reqs; + return List.of( + swampPaste + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - return Collections.singletonList(new SkillRequirement(Skill.FIREMAKING, 30, true)); + return List.of( + "You can complete an Ardougne Medium Diary task by fishing from the fishing platform using a fishing rod or small fishing net (these can be bought from the fishing shop near quest start in Witchaven)." + ); } @Override @@ -223,35 +271,68 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.FISHING, 7125)); + return List.of( + new ExperienceReward(Skill.FISHING, 7175) + ); } @Override - public List getUnlockRewards() + public List getItemRewards() { - return Collections.singletonList(new UnlockReward("Access to the Fishing Platform")); + return List.of( + new ItemReward("Oyster pearls", ItemID.BIGOYSTERPEARLS, 1) + ); } - + @Override - public List getPanels() + public List getUnlockRewards() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToCaroline), - swampPaste)); - allSteps.add(new PanelDetails("Investigation", Arrays.asList(talkToHolgart, travelWithHolgart, - climbLadder, talkToKennith, goDownLadder, goToIsland))); - allSteps.add(new PanelDetails("Talking with Kent", Arrays.asList(talkToKent, returnFromIsland))); - allSteps.add(new PanelDetails("Saving Kennith", - Arrays.asList(talkToBaileyForTorch, pickupGlass, pickupDampSticks, useGlassOnDampSticks, rubSticks, goBackUpLadder, - talkToKennithAgain, kickWall, talkToKennithAfterKicking, activateCrane, goDownLadderAgain, returnWithHolgart, - finishQuest))); - - return allSteps; + return List.of( + new UnlockReward("Access to the Fishing Platform") + ); } @Override - public List getNotes() + public List getPanels() { - return Collections.singletonList("You can complete an Ardougne Medium Diary task by fishing from the fishing platform using a fishing rod or small fishing net (these can be bought from the fishing shop near quest start in Witchaven)."); + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToCaroline + ), List.of( + swampPaste + ))); + + sections.add(new PanelDetails("Investigation", List.of( + talkToHolgart, + travelWithHolgart, + climbLadder, + talkToKennith, + goDownLadder, + goToIsland + ))); + + sections.add(new PanelDetails("Talking with Kent", List.of( + talkToKent, + returnFromIsland + ))); + + sections.add(new PanelDetails("Saving Kennith", List.of( + talkToBaileyForTorch, + pickupGlass, + pickupDampSticks, + useGlassOnDampSticks, + rubSticks, + goBackUpLadder, + talkToKennithAgain, + kickWall, + talkToKennithAfterKicking, + activateCrane, + goDownLadderAgain, + returnWithHolgart, + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java index d1813681982..5f98e763938 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java @@ -31,13 +31,10 @@ import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; -import java.util.Collections; - public class IncantationStep extends DetailedQuestStep { /** @@ -87,12 +84,9 @@ public class IncantationStep extends DetailedQuestStep private String[] incantationOrder; private int incantationPosition = 0; - public IncantationStep(QuestHelper questHelper, boolean reverse) + public IncantationStep(QuestHelper questHelper, boolean reverse, ItemRequirement sigilHighlighted) { - super(questHelper, "Click the demonic sigil and read the incantation."); - ItemRequirement sigilHighlighted = new ItemRequirement("Demonic sigil", ItemID.AGRITH_SIGIL); - sigilHighlighted.setHighlightInInventory(true); - this.addItemRequirements(Collections.singletonList(sigilHighlighted)); + super(questHelper, "Click the demonic sigil and read the incantation.", sigilHighlighted); this.reverse = reverse; } @@ -100,6 +94,7 @@ public IncantationStep(QuestHelper questHelper, boolean reverse) public void startUp() { super.startUp(); + incantationPosition = 0; updateHints(); } @@ -123,16 +118,17 @@ public void onMenuOptionClicked(MenuOptionClicked event) { var widget = event.getWidget(); - if (widget == null) { + if (widget == null) + { return; } - if (widget.getId() != InterfaceID.INVENTORY) + if (widget.getId() != InterfaceID.Inventory.ITEMS) { return; } - if ("Chant".equals(event.getMenuOption())) + if (event.getMenuOption().equals("Chant")) { incantationPosition = 0; } @@ -190,7 +186,8 @@ protected void updateHints() return; } - if (reverse) { + if (reverse) + { incantationOrder = new String[]{ WORDS[client.getVarbitValue(INCANTATION_WORD_5)], WORDS[client.getVarbitValue(INCANTATION_WORD_4)], @@ -198,7 +195,9 @@ protected void updateHints() WORDS[client.getVarbitValue(INCANTATION_WORD_2)], WORDS[client.getVarbitValue(INCANTATION_WORD_1)], }; - } else { + } + else + { incantationOrder = new String[]{ WORDS[client.getVarbitValue(INCANTATION_WORD_1)], WORDS[client.getVarbitValue(INCANTATION_WORD_2)], @@ -211,5 +210,6 @@ protected void updateHints() setText("Click the demonic sigil and read the incantation."); addText(incantString); + addText("If the highlight feels wrong, click the demonic sigil again."); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/SearchKilns.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/SearchKilns.java deleted file mode 100644 index 36faf859532..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/SearchKilns.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2020, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.helpers.quests.shadowofthestorm; - -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.steps.DetailedOwnerStep; -import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.ObjectID; -import net.runelite.api.gameval.VarbitID; -import net.runelite.client.eventbus.Subscribe; - -import java.util.Arrays; -import java.util.Collection; - -public class SearchKilns extends DetailedOwnerStep -{ - ObjectStep searchKiln1, searchKiln2, searchKiln3, searchKiln4; - - public SearchKilns(QuestHelper questHelper) - { - super(questHelper, "Search the kilns in Uzer until you find a book."); - } - - @Subscribe - public void onGameTick(GameTick event) - { - updateSteps(); - } - - @Override - protected void updateSteps() - { - int correctKiln = client.getVarbitValue(VarbitID.AGRITH_KILN); - if (correctKiln == 0) - { - startUpStep(searchKiln1); - } - else if (correctKiln == 1) - { - startUpStep(searchKiln2); - } - else if (correctKiln == 2) - { - startUpStep(searchKiln3); - } - else if (correctKiln == 3) - { - startUpStep(searchKiln4); - } - } - - @Override - protected void setupSteps() - { - searchKiln1 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_1, new WorldPoint(3468, 3124, 0), "Search the kilns in Uzer until you find a book."); - searchKiln2 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_2, new WorldPoint(3479, 3083, 0), "Search the kilns in Uzer until you find a book."); - searchKiln3 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_3, new WorldPoint(3473, 3093, 0), "Search the kilns in Uzer until you find a book."); - searchKiln4 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_4, new WorldPoint(3501, 3085, 0), "Search the kilns in Uzer until you find a book."); - } - - @Override - public Collection getSteps() - { - return Arrays.asList(searchKiln1, searchKiln2, searchKiln3, searchKiln4); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java index 8682b25778f..621b8dd6f57 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java @@ -30,18 +30,31 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.client.plugins.microbot.questhelper.steps.TileStep; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -50,118 +63,105 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class ShadowOfTheStorm extends BasicQuestHelper { - //Items Required - ItemRequirement darkItems, silverlight, strangeImplement, blackMushroomInk, pestle, vial, silverBar, silverlightHighlighted, blackMushroomHighlighted, - silverlightDyedEquipped, sigilMould, silverlightDyed, strangeImplementHighlighted, sigil, book, bookHighlighted, - sigilHighlighted, sigil2; - - //Items Recommended - ItemRequirement combatGear, coinsForCarpet, alKharidTeleport; - - Requirement inRuin, inThroneRoom,talkedToGolem, talkedToMatthew, inCircleSpot, sigilNearby, evilDaveMoved, baddenMoved, - reenMoved, golemMoved, golemRejected, golemReprogrammed, - inSecondCircleSpot; - - DetailedQuestStep talkToReen, talkToBadden, pickMushroom, dyeSilverlight, goIntoRuin, pickUpStrangeImplement, talkToEvilDave, enterPortal, - talkToDenath, talkToJennifer, talkToMatthew, smeltSigil, talkToGolem, readBook, enterRuinAfterBook, enterPortalAfterBook, - talkToMatthewAfterBook, standInCircle, pickUpSigil, leavePortal, tellDaveToReturn, pickUpImplementAfterRitual, - goUpToBadden, talkToBaddenAfterRitual, talkToReenAfterRitual, talkToTheGolemAfterRitual, useImplementOnGolem, pickUpSigil2, - talkToGolemAfterReprogramming, enterRuinAfterRecruiting, enterPortalAfterRecruiting, talkToMatthewToStartFight, killDemon, - standInCircleAgain, enterRuinNoDark, enterRuinForRitual, enterPortalForRitual, enterRuinForDave, enterPortalForFight, - enterRuinForFight, unequipDarklight; - - DetailedOwnerStep searchKiln; - - IncantationStep readIncantation, incantRitual; - - //Zones - Zone ruin, throneRoom, circleSpot, secondCircleSpot; - - @Override - public Map loadSteps() - { - Map steps = new HashMap<>(); - initializeRequirements(); - setupConditions(); - setupSteps(); - - steps.put(0, talkToReen); - steps.put(10, talkToBadden); - - ConditionalStep infiltrateCult = new ConditionalStep(this, pickMushroom); - infiltrateCult.addStep(new Conditions(silverlightDyed, strangeImplement, inRuin), talkToEvilDave); - infiltrateCult.addStep(new Conditions(silverlightDyed, inRuin), pickUpStrangeImplement); - infiltrateCult.addStep(silverlightDyed, goIntoRuin); - infiltrateCult.addStep(blackMushroomHighlighted, dyeSilverlight); - steps.put(20, infiltrateCult); - - ConditionalStep goTalkToDenath = new ConditionalStep(this, enterRuinNoDark); - goTalkToDenath.addStep(inThroneRoom, talkToDenath); - goTalkToDenath.addStep(inRuin, enterPortal); - steps.put(30, goTalkToDenath); - - ConditionalStep completeSubTasks = new ConditionalStep(this, enterRuinNoDark); - completeSubTasks.addStep(new Conditions(book, sigil, inThroneRoom), talkToMatthewAfterBook); - completeSubTasks.addStep(new Conditions(book, sigil, inRuin), enterPortalAfterBook); - completeSubTasks.addStep(new Conditions(book, sigil), enterRuinAfterBook); - completeSubTasks.addStep(new Conditions(talkedToGolem, sigil), searchKiln); - completeSubTasks.addStep(new Conditions(talkedToMatthew, sigil), talkToGolem); - completeSubTasks.addStep(new Conditions(talkedToMatthew, sigilMould), smeltSigil); - completeSubTasks.addStep(new Conditions(inThroneRoom, sigilMould), talkToMatthew); - completeSubTasks.addStep(inThroneRoom, talkToJennifer); - completeSubTasks.addStep(inRuin, enterPortal); - steps.put(40, completeSubTasks); - steps.put(50, completeSubTasks); - steps.put(60, completeSubTasks); - - ConditionalStep startRitual = new ConditionalStep(this, enterRuinForRitual); - startRitual.addStep(inThroneRoom, talkToMatthewAfterBook); - startRitual.addStep(inRuin, enterPortalForRitual); - steps.put(70, startRitual); - - ConditionalStep performRitual = new ConditionalStep(this, enterRuinForRitual); - performRitual.addStep(inCircleSpot, readIncantation); - performRitual.addStep(inThroneRoom, standInCircle); - performRitual.addStep(inRuin, enterPortalForRitual); - steps.put(80, performRitual); - - ConditionalStep prepareForSecondRitual = new ConditionalStep(this, enterRuinForDave); - prepareForSecondRitual.addStep(sigilNearby, pickUpSigil); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inThroneRoom), talkToMatthewToStartFight); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inRuin), enterPortalAfterRecruiting); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemMoved), enterRuinAfterRecruiting); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemReprogrammed), talkToGolemAfterReprogramming); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemRejected), useImplementOnGolem); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved), talkToTheGolemAfterRitual); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved), talkToReenAfterRitual); - prepareForSecondRitual.addStep(new Conditions(strangeImplement, evilDaveMoved, inRuin), goUpToBadden); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, inRuin), pickUpImplementAfterRitual); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved), talkToBaddenAfterRitual); - prepareForSecondRitual.addStep(inRuin, tellDaveToReturn); - prepareForSecondRitual.addStep(inThroneRoom, leavePortal); - - steps.put(90, prepareForSecondRitual); - steps.put(100, prepareForSecondRitual); - - ConditionalStep summonAgrith = new ConditionalStep(this, enterRuinAfterRecruiting); - summonAgrith.addStep(inSecondCircleSpot, incantRitual); - summonAgrith.addStep(inThroneRoom, standInCircleAgain); - summonAgrith.addStep(inRuin, enterPortalAfterRecruiting); - steps.put(110, summonAgrith); - - ConditionalStep defeatAgrith = new ConditionalStep(this, enterRuinForFight); - defeatAgrith.addStep(inThroneRoom, killDemon); - defeatAgrith.addStep(inRuin, enterPortalForFight); - steps.put(120, defeatAgrith); - - steps.put(124, unequipDarklight); - - return steps; - } + // Required items + ItemRequirement silverlight; + ItemRequirement darkItems; + ItemRequirement silverBar; + + // Recommended items + ItemRequirement combatGear; + ItemRequirement coinsForCarpet; + ItemRequirement alKharidTeleport; + + // Mid-quest item requirements + ItemRequirement strangeImplement; + ItemRequirement blackMushroomInk; + ItemRequirement pestle; + ItemRequirement vial; + ItemRequirement silverlightHighlighted; + ItemRequirement blackMushroomHighlighted; + ItemRequirement silverlightDyedEquipped; + ItemRequirement sigilMould; + ItemRequirement silverlightDyed; + ItemRequirement strangeImplementHighlighted; + ItemRequirement sigil; + ItemRequirement book; + ItemRequirement bookHighlighted; + ItemRequirement sigilHighlighted; + ItemRequirement sigil2; + + // Zones + Zone ruin; + Zone throneRoom; + Zone circleSpot; + Zone secondCircleSpot; + + // Miscellaneous requirements + ZoneRequirement inRuin; + ZoneRequirement inThroneRoom; + VarbitRequirement talkedToGolem; + VarbitRequirement talkedToMatthew; + ZoneRequirement inCircleSpot; + ItemOnTileRequirement sigilNearby; + VarbitRequirement evilDaveMoved; + VarbitRequirement baddenMoved; + VarbitRequirement reenMoved; + VarbitRequirement golemMoved; + VarbitRequirement golemRejected; + VarbitRequirement golemReprogrammed; + ZoneRequirement inSecondCircleSpot; + FreeInventorySlotRequirement freeSlot1; + + // Steps + NpcStep talkToReen; + NpcStep talkToBadden; + ObjectStep pickMushroom; + DetailedQuestStep dyeSilverlight; + ObjectStep goIntoRuin; + DetailedQuestStep pickUpStrangeImplement; + NpcStep talkToEvilDave; + ObjectStep enterPortal; + NpcStep talkToDenath; + NpcStep talkToJennifer; + NpcStep talkToMatthew; + DetailedQuestStep smeltSigil; + NpcStep talkToGolem; + DetailedQuestStep readBook; + ObjectStep enterRuinAfterBook; + ObjectStep enterPortalAfterBook; + NpcStep talkToMatthewAfterBook; + TileStep standInCircle; + ItemStep pickUpSigil; + ObjectStep leavePortal; + NpcStep tellDaveToReturn; + DetailedQuestStep pickUpImplementAfterRitual; + ObjectStep goUpToBadden; + NpcStep talkToBaddenAfterRitual; + NpcStep talkToReenAfterRitual; + NpcStep talkToTheGolemAfterRitual; + NpcStep useImplementOnGolem; + ItemStep pickUpSigil2; + NpcStep talkToGolemAfterReprogramming; + ObjectStep enterRuinAfterRecruiting; + ObjectStep enterPortalAfterRecruiting; + NpcStep talkToMatthewToStartFight; + NpcStep killDemon; + TileStep standInCircleAgain; + ObjectStep enterRuinNoDark; + ObjectStep enterRuinForRitual; + ObjectStep enterPortalForRitual; + ObjectStep enterRuinForDave; + ObjectStep enterPortalForFight; + ObjectStep enterRuinForFight; + DetailedQuestStep unequipDarklight; + ConditionalStep searchKilns; + PuzzleWrapperStep pwSearchKilns; + IncantationStep readIncantation; + PuzzleWrapperStep pwReadIncantation; + IncantationStep incantRitual; + PuzzleWrapperStep pwIncantRitual; @Override protected void setupZones() @@ -215,10 +215,6 @@ protected void setupRequirements() // Recommended alKharidTeleport = new ItemRequirement("Al Kharid Teleport", ItemCollections.AMULET_OF_GLORIES); alKharidTeleport.addAlternates(ItemCollections.RING_OF_DUELINGS); - } - - private void setupConditions() - { inRuin = new ZoneRequirement(ruin); inThroneRoom = new ZoneRequirement(throneRoom); inCircleSpot = new ZoneRequirement(circleSpot); @@ -233,6 +229,8 @@ private void setupConditions() golemRejected = new VarbitRequirement(VarbitID.AGRITH_CONVINCED_GOLEM, 1, Operation.GREATER_EQUAL); golemReprogrammed = new VarbitRequirement(VarbitID.AGRITH_CONVINCED_GOLEM, 2, Operation.GREATER_EQUAL); golemMoved = new VarbitRequirement(VarbitID.AGRITH_CONVINCED_GOLEM, 3, Operation.GREATER_EQUAL); + + freeSlot1 = new FreeInventorySlotRequirement(1); } private void setupSteps() @@ -254,7 +252,7 @@ private void setupSteps() talkToDenath = new NpcStep(this, NpcID.AGRITH_DENATH, new WorldPoint(2720, 4912, 2), "Talk to Denath next to the throne."); talkToDenath.addDialogStep("What do I have to do?"); talkToDenath.addSubSteps(enterRuinNoDark, enterPortal); - talkToJennifer = new NpcStep(this, NpcID.AGRITH_JENNIFER, new WorldPoint(2723, 4901, 2), "Talk to Jennifer."); + talkToJennifer = new NpcStep(this, NpcID.AGRITH_JENNIFER, new WorldPoint(2723, 4901, 2), "Talk to Jennifer.", freeSlot1); talkToJennifer.addDialogStep("Do you have the demonic sigil mould?"); talkToMatthew = new NpcStep(this, NpcID.AGRITH_MATTHEW, new WorldPoint(2727, 4897, 2), "Talk to Matthew."); talkToMatthew.addDialogStep("Do you know what happened to Josef?"); @@ -263,7 +261,20 @@ private void setupSteps() talkToGolem = new NpcStep(this, NpcID.GOLEM_FIXED_GOLEM, new WorldPoint(3485, 3088, 0), "Talk to the Golem in Uzer.", silverlightDyed, sigil, combatGear); talkToGolem.addDialogStep("Uzer"); talkToGolem.addDialogStep("Did you see anything happen last night?"); - searchKiln = new SearchKilns(this); + + var searchKiln1 = new ObjectStep(this, ObjectID.AGRITH_KILN_1, new WorldPoint(3468, 3124, 0), ""); + var searchKiln2 = new ObjectStep(this, ObjectID.AGRITH_KILN_2, new WorldPoint(3479, 3083, 0), ""); + var searchKiln3 = new ObjectStep(this, ObjectID.AGRITH_KILN_3, new WorldPoint(3473, 3093, 0), ""); + var searchKiln4 = new ObjectStep(this, ObjectID.AGRITH_KILN_4, new WorldPoint(3501, 3085, 0), ""); + + var kilnBuilder = new VarbitBuilder(VarbitID.AGRITH_KILN); + searchKilns = new ConditionalStep(this, searchKiln1, "Search the kilns in Uzer until you find a book."); + searchKilns.addStep(kilnBuilder.eq(1), searchKiln2); + searchKilns.addStep(kilnBuilder.eq(2), searchKiln3); + searchKilns.addStep(kilnBuilder.eq(3), searchKiln4); + + pwSearchKilns = searchKilns.puzzleWrapStep("Search Uzer for a book."); + readBook = new DetailedQuestStep(this, "Read the book.", bookHighlighted); enterRuinAfterBook = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Enter the Uzer ruins.", silverlightDyed, book, sigil); enterPortalAfterBook = new ObjectStep(this, ObjectID.GOLEM_PORTAL, new WorldPoint(2722, 4913, 0), "Enter the portal.", book, sigil); @@ -274,21 +285,23 @@ private void setupSteps() enterRuinForRitual = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Enter the Uzer ruins.", sigil, silverlightDyed, combatGear); enterPortalForRitual = new ObjectStep(this, ObjectID.GOLEM_PORTAL, new WorldPoint(2722, 4913, 0), "Enter the portal."); - standInCircle = new DetailedQuestStep(this, new WorldPoint(2718, 4902, 2), "Stand in the correct spot in the circle.", sigil); - readIncantation = new IncantationStep(this, true); - pickUpSigil = new ItemStep(this, "Pick up the sigil.", sigil); + standInCircle = new TileStep(this, new WorldPoint(2718, 4902, 2), "Stand in the correct spot in the circle.", sigil); + standInCircle.addSubSteps(enterRuinForRitual, enterPortalForRitual); + readIncantation = new IncantationStep(this, true, sigilHighlighted); + pwReadIncantation = readIncantation.puzzleWrapStepWithDefaultText("Click the demonic sigil and read the incantation."); + pickUpSigil = new ItemStep(this, "Pick up the demonic sigil from the circle.", sigil); leavePortal = new ObjectStep(this, ObjectID.AGRITH_PORTAL_CLOSING, new WorldPoint(2720, 4883, 2), "Leave the throne room."); enterRuinForDave = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Talk to Evil Dave in the Uzer ruins."); - tellDaveToReturn = new NpcStep(this, NpcID.AGRITH_DAVE, new WorldPoint(2721, 4900, 0), "Talk to Evil Dave."); + tellDaveToReturn = new NpcStep(this, NpcID.AGRITH_DAVE, new WorldPoint(2721, 4900, 0), "Talk to Evil Dave.", freeSlot1); tellDaveToReturn.addDialogStep("You've got to get back to the throne room!"); tellDaveToReturn.addSubSteps(enterRuinForDave); pickUpImplementAfterRitual = new DetailedQuestStep(this, new WorldPoint(2713, 4913, 0), "Pick up the strange implement in the north west corner of the ruin.", strangeImplement); - pickUpSigil2 = new ItemStep(this, "Pick up the sigil Tanya dropped.", sigil); + pickUpSigil2 = new ItemStep(this, "Pick up the demonic sigil Tanya dropped.", sigil); goUpToBadden = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_BASE, new WorldPoint(2722, 4885, 0), "Leave the ruins."); talkToBaddenAfterRitual = new NpcStep(this, NpcID.AGRITH_BADDEN, new WorldPoint(3490, 3090, 0), "Talk to Father Badden in Uzer.", sigil2); - talkToBaddenAfterRitual.addSubSteps(goUpToBadden); + talkToBaddenAfterRitual.addSubSteps(goUpToBadden, pickUpImplementAfterRitual); talkToReenAfterRitual = new NpcStep(this, NpcID.AGRITH_REEN, new WorldPoint(3490, 3090, 0), "Talk to Father Reen in Uzer.", sigil2); talkToReenAfterRitual.addDialogStep("Oh, don't be so simple-minded!"); @@ -303,8 +316,9 @@ private void setupSteps() talkToMatthewToStartFight = new NpcStep(this, NpcID.AGRITH_MATTHEW, new WorldPoint(2727, 4897, 2), "Talk to Matthew in the throne room.", silverlightDyed, sigil, combatGear); talkToMatthewToStartFight.addSubSteps(enterRuinAfterRecruiting, enterPortalAfterRecruiting); talkToMatthewToStartFight.addDialogStep("Yes."); - standInCircleAgain = new DetailedQuestStep(this, new WorldPoint(2720, 4903, 2), "Stand in the correct spot in the circle.", sigil); - incantRitual = new IncantationStep(this, false); + standInCircleAgain = new TileStep(this, new WorldPoint(2720, 4903, 2), "Stand in the correct spot in the circle.", sigil); + incantRitual = new IncantationStep(this, false, sigilHighlighted); + pwIncantRitual = incantRitual.puzzleWrapStepWithDefaultText("Click the demonic sigil and read the incantation."); enterRuinForFight = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Enter the Uzer ruins to finish fighting Agrith-Naar.", silverlightDyed, combatGear); enterPortalForFight = new ObjectStep(this, ObjectID.GOLEM_PORTAL, new WorldPoint(2722, 4913, 0), "Enter the portal to finish fighting Agrith-Naar.", silverlightDyed, combatGear); killDemon = new NpcStep(this, NpcID.AGRITH_NAAR, "Kill Agrith-Naar. You can hurt him with any weapon, BUT YOU MUST DEAL THE FINAL BLOW WITH SILVERLIGHT.", silverlightDyedEquipped, combatGear); @@ -314,39 +328,142 @@ private void setupSteps() } @Override - public List getNotes() + public Map loadSteps() { - return Arrays.asList("You will need 3 black items for a part of the quest. Potential items would be:", - "- Desert shirt/robe dyed with black mushroom ink", "- Black armour", "- Priest gown top/bottom", "- Black wizard hat", - "- Dark mystic", "- Ghostly robes", "- Shade robes", "- Black dragonhide", "- Black cape", "- One of the various black holiday event items", "- Graceful outfit (dyed black)"); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToReen); + steps.put(10, talkToBadden); + + var infiltrateCult = new ConditionalStep(this, pickMushroom); + infiltrateCult.addStep(and(silverlightDyed, strangeImplement, inRuin), talkToEvilDave); + infiltrateCult.addStep(and(silverlightDyed, inRuin), pickUpStrangeImplement); + infiltrateCult.addStep(silverlightDyed, goIntoRuin); + infiltrateCult.addStep(blackMushroomHighlighted, dyeSilverlight); + steps.put(20, infiltrateCult); + + var goTalkToDenath = new ConditionalStep(this, enterRuinNoDark); + goTalkToDenath.addStep(inThroneRoom, talkToDenath); + goTalkToDenath.addStep(inRuin, enterPortal); + steps.put(30, goTalkToDenath); + + var completeSubTasks = new ConditionalStep(this, enterRuinNoDark); + completeSubTasks.addStep(and(book, sigil, inThroneRoom), talkToMatthewAfterBook); + completeSubTasks.addStep(and(book, sigil, inRuin), enterPortalAfterBook); + completeSubTasks.addStep(and(book, sigil), enterRuinAfterBook); + completeSubTasks.addStep(and(talkedToGolem, sigil), pwSearchKilns); + completeSubTasks.addStep(and(talkedToMatthew, sigil), talkToGolem); + completeSubTasks.addStep(and(talkedToMatthew, sigilMould), smeltSigil); + completeSubTasks.addStep(and(inThroneRoom, sigilMould), talkToMatthew); + completeSubTasks.addStep(inThroneRoom, talkToJennifer); + completeSubTasks.addStep(inRuin, enterPortal); + steps.put(40, completeSubTasks); + steps.put(50, completeSubTasks); + steps.put(60, completeSubTasks); + + var startRitual = new ConditionalStep(this, enterRuinForRitual); + startRitual.addStep(inThroneRoom, talkToMatthewAfterBook); + startRitual.addStep(inRuin, enterPortalForRitual); + steps.put(70, startRitual); + + var performRitual = new ConditionalStep(this, enterRuinForRitual); + performRitual.addStep(inCircleSpot, pwReadIncantation); + performRitual.addStep(inThroneRoom, standInCircle); + performRitual.addStep(inRuin, enterPortalForRitual); + steps.put(80, performRitual); + + var prepareForSecondRitual = new ConditionalStep(this, enterRuinForDave); + prepareForSecondRitual.addStep(sigilNearby, pickUpSigil); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inThroneRoom), talkToMatthewToStartFight); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inRuin), enterPortalAfterRecruiting); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemMoved), enterRuinAfterRecruiting); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemReprogrammed), talkToGolemAfterReprogramming); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemRejected), useImplementOnGolem); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved), talkToTheGolemAfterRitual); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved), talkToReenAfterRitual); + prepareForSecondRitual.addStep(and(strangeImplement, evilDaveMoved, inRuin), goUpToBadden); + prepareForSecondRitual.addStep(and(evilDaveMoved, inRuin), pickUpImplementAfterRitual); + prepareForSecondRitual.addStep(and(evilDaveMoved), talkToBaddenAfterRitual); + prepareForSecondRitual.addStep(inRuin, tellDaveToReturn); + prepareForSecondRitual.addStep(inThroneRoom, leavePortal); + + steps.put(90, prepareForSecondRitual); + steps.put(100, prepareForSecondRitual); + + var summonAgrith = new ConditionalStep(this, enterRuinAfterRecruiting); + summonAgrith.addStep(inSecondCircleSpot, pwIncantRitual); + summonAgrith.addStep(inThroneRoom, standInCircleAgain); + summonAgrith.addStep(inRuin, enterPortalAfterRecruiting); + steps.put(110, summonAgrith); + + var defeatAgrith = new ConditionalStep(this, enterRuinForFight); + defeatAgrith.addStep(inThroneRoom, killDemon); + defeatAgrith.addStep(inRuin, enterPortalForFight); + steps.put(120, defeatAgrith); + + steps.put(124, unequipDarklight); + + return steps; } @Override - public List getCombatRequirements() + public List getGeneralRequirements() { - return Collections.singletonList("Agrith-Naar (level 100)"); + return List.of( + new QuestRequirement(QuestHelperQuest.THE_GOLEM, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.DEMON_SLAYER, QuestState.FINISHED), + new SkillRequirement(Skill.CRAFTING, 30, true) + ); } @Override public List getItemRequirements() { - return Arrays.asList(silverlight, darkItems, silverBar); + return List.of( + silverlight, + darkItems, + silverBar + ); } @Override public List getItemRecommended() { - return Arrays.asList(combatGear, coinsForCarpet, alKharidTeleport); + return List.of( + combatGear, + coinsForCarpet, + alKharidTeleport + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() + { + return List.of( + "Agrith-Naar (level 100)" + ); + } + + @Override + public List getNotes() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.THE_GOLEM, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.DEMON_SLAYER, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.CRAFTING, 30, true)); - return req; + return List.of( + "You will need 3 black items for a part of the quest. Potential items would be:", + "- Desert shirt/robe dyed with black mushroom ink", + "- Black armour", + "- Priest gown top/bottom", + "- Black wizard hat", + "- Dark mystic", + "- Ghostly robes", + "- Shade robes", + "- Black dragonhide", + "- Black cape", + "- One of the various black holiday event items", + "- Graceful outfit (dyed black)" + ); } @Override @@ -358,21 +475,70 @@ public QuestPointReward getQuestPointReward() @Override public List getItemRewards() { - return Arrays.asList( - new ItemReward("10,000 Experience Lamp (Any combat skill except Prayer)", ItemID.THOSF_REWARD_LAMP, 1), //4447 is placeholder for filter - new ItemReward("Darklight", ItemID.DARKLIGHT, 1)); + return List.of( + new ItemReward("10,000 Experience Lamp (Any combat skill except Prayer)", ItemID.THOSF_REWARD_LAMP, 1), //4447 is placeholder for filter + new ItemReward("Darklight", ItemID.DARKLIGHT, 1) + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToReen))); - allSteps.add(new PanelDetails("Infiltrate the cult", Arrays.asList(talkToBadden, pickMushroom, dyeSilverlight, goIntoRuin, pickUpStrangeImplement, talkToEvilDave, talkToDenath, talkToJennifer, talkToMatthew), silverlight, darkItems)); - allSteps.add(new PanelDetails("Uncovering the truth", Arrays.asList(smeltSigil, talkToGolem, searchKiln, readBook, talkToMatthewAfterBook, standInCircle, readIncantation), silverBar, silverlightDyed, combatGear)); - allSteps.add(new PanelDetails("Defeating Agrith-Naar", Arrays.asList(pickUpSigil, leavePortal, pickUpSigil2, tellDaveToReturn, talkToBaddenAfterRitual, talkToReenAfterRitual, talkToTheGolemAfterRitual, useImplementOnGolem, talkToGolemAfterReprogramming, - talkToMatthewToStartFight, standInCircleAgain, incantRitual, killDemon, unequipDarklight), silverlightDyed, combatGear)); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToReen + ))); + + sections.add(new PanelDetails("Infiltrate the cult", List.of( + talkToBadden, + pickMushroom, + dyeSilverlight, + goIntoRuin, + pickUpStrangeImplement, + talkToEvilDave, + talkToDenath, + talkToJennifer, + talkToMatthew + ), List.of( + silverlight, + darkItems + ))); + + sections.add(new PanelDetails("Uncovering the truth", List.of( + smeltSigil, + talkToGolem, + pwSearchKilns, + readBook, + talkToMatthewAfterBook, + standInCircle, + pwReadIncantation + ), List.of( + silverBar, + silverlightDyed, + combatGear + ))); + + sections.add(new PanelDetails("Defeating Agrith-Naar", List.of( + pickUpSigil, + leavePortal, + pickUpSigil2, + tellDaveToReturn, + talkToBaddenAfterRitual, + talkToReenAfterRitual, + talkToTheGolemAfterRitual, + useImplementOnGolem, + talkToGolemAfterReprogramming, + talkToMatthewToStartFight, + standInCircleAgain, + pwIncantRitual, + killDemon, + unequipDarklight + ), List.of( + silverlightDyed, + combatGear + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java index 6ab1fd4999d..e2ed47fd491 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java @@ -36,6 +36,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -43,7 +44,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -52,13 +61,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; - /** * The quest guide for the "Shadows of Custodia" OSRS quest */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java index 8530d771fc4..9e1e565c219 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java @@ -30,28 +30,30 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.tools.QuestTile; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class SheepHerder extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java index 1c57e982283..3f35bb58810 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java @@ -29,27 +29,35 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.ManualRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ItemContainerChanged; -import net.runelite.api.gameval.*; -import net.runelite.client.eventbus.Subscribe; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.IntStream; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.gameval.InventoryID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; +import net.runelite.client.eventbus.Subscribe; public class SheepShearer extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java index 8065d58655a..afda63320e1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java @@ -41,7 +41,11 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java index df86791175b..c7ce80886c2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java @@ -39,6 +39,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; @@ -49,109 +50,125 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - -import java.util.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; public class ShiloVillage extends BasicQuestHelper { - // Required - ItemRequirement spade, torchOrCandle, rope, bronzeWire, chisel, bones3; - - // Recommended - ItemRequirement combatGear, food, staminas, antipoison, prayerPotions, quickTeleport, papyrus, charcoal, - crumbleUndead; - - ItemRequirement belt, stonePlaque, tatteredScroll, crumpledScroll, zadimusCorpse, boneShard, beads, pommel, - beadsOfTheDead, boneKey, rashCorpse; - - Requirement emptySlot3, moundNearby, inCavern1, inCavern2, inCavern3, inCavern4, shownStone, shownCorpse, - hasReadTattered, hasReadCrumpled, revealedDoor, searchedDoor, doorOpened, nazNearby, corpseNearby; - - QuestStep talkToMosol, useBeltOnTrufitus, useSpadeOnGround, useTorchOnFissure, useRopeOnFissure, - lookAtMound, searchFissure, useChiselOnStone, enterDeeperCave, searchForTatteredScroll, searchForCrumpledScroll, - searchForCorpse, useCorpseOnTrufitus, useStonePlaqueOnTrufitus, readTattered, readCrumpled, buryCorpse; - - QuestStep searchRocksOnCairn, searchDolmen, useChiselOnPommel, useWireOnBeads; - - QuestStep searchPalms, searchDoors, makeKey, useKeyOnDoor, enterDoor, useBonesOnDoor, searchDolmenForFight, killNazastarool, - pickupCorpse; - - QuestStep enterCairnAgain, useCorpseOnDolmen; - - Zone cavern1, cavern2, cavern3, cavern4; + // Required items + ItemRequirement spade; + ItemRequirement torchOrCandle; + ItemRequirement rope; + ItemRequirement bronzeWire; + ItemRequirement chisel; + ItemRequirement bones3; + + // Recommended items + ItemRequirement combatGear; + ItemRequirement food; + ItemRequirement staminas; + ItemRequirement antipoison; + ItemRequirement prayerPotions; + ItemRequirement quickTeleport; + ItemRequirement papyrus; + ItemRequirement charcoal; + ItemRequirement crumbleUndead; + + // Mid-quest item requirements + ItemRequirement belt; + ItemRequirement stonePlaque; + ItemRequirement tatteredScroll; + ItemRequirement crumpledScroll; + ItemRequirement zadimusCorpse; + ItemRequirement boneShard; + ItemRequirement beads; + ItemRequirement pommel; + ItemRequirement beadsOfTheDead; + ItemRequirement boneKey; + ItemRequirement rashCorpse; + + // Zones + Zone cavern1; + Zone cavern2; + Zone cavern3; + Zone cavern4; + + // Miscellaneous requirements + FreeInventorySlotRequirement freeInvSlot1; + FreeInventorySlotRequirement freeInvSlot2; + ObjectCondition moundNearby; + ZoneRequirement inCavern1; + ZoneRequirement inCavern2; + ZoneRequirement inCavern3; + ZoneRequirement inCavern4; + Conditions shownStone; + Conditions shownCorpse; + Conditions hasReadTattered; + Conditions hasReadCrumpled; + VarbitRequirement revealedDoor; + Conditions searchedDoor; + VarbitRequirement doorOpened; + NpcInteractingRequirement nazNearby; + ItemOnTileRequirement corpseNearby; + + // Steps + NpcStep talkToMosol; + NpcStep showBeltToTrufitus; + ObjectStep useSpadeOnGround; + ObjectStep useTorchOnFissure; + ObjectStep useRopeOnFissure; + ObjectStep lookAtMound; + ObjectStep searchFissure; + ObjectStep useChiselOnStone; + ObjectStep enterDeeperCave; + ObjectStep searchForTatteredScroll; + ObjectStep searchForCrumpledScroll; + ObjectStep searchForCorpse; + NpcStep useCorpseOnTrufitus; + NpcStep useStonePlaqueOnTrufitus; + DetailedQuestStep readTattered; + DetailedQuestStep readCrumpled; + DetailedQuestStep buryCorpse; + ObjectStep searchRocksOnCairn; + ObjectStep searchDolmen; + DetailedQuestStep useChiselOnPommel; + DetailedQuestStep useWireOnBeads; + ObjectStep searchPalms; + ObjectStep searchDoors; + DetailedQuestStep makeKey; + ObjectStep useKeyOnDoor; + ObjectStep enterDoor; + ObjectStep useBonesOnDoor; + ObjectStep searchDolmenForFight; + NpcStep killNazastarool; + ItemStep pickupCorpse; + ObjectStep enterCairnAgain; + ObjectStep useCorpseOnDolmen; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - ConditionalStep goStartQuest = new ConditionalStep(this, talkToMosol); - goStartQuest.addStep(belt.alsoCheckBank(), useBeltOnTrufitus); - steps.put(0, goStartQuest); - - steps.put(1, useSpadeOnGround); - steps.put(2, useSpadeOnGround); - steps.put(3, useSpadeOnGround); - - ConditionalStep lightUpFissure = new ConditionalStep(this, useTorchOnFissure); - lightUpFissure.addStep(moundNearby, lookAtMound); - steps.put(4, lightUpFissure); - - ConditionalStep goUseRope = new ConditionalStep(this, useRopeOnFissure); - goUseRope.addStep(moundNearby, lookAtMound); - steps.put(5, goUseRope); - - ConditionalStep goGetItems = new ConditionalStep(this, searchFissure); - goGetItems.addStep(new Conditions(beadsOfTheDead, boneKey), useKeyOnDoor); - goGetItems.addStep(new Conditions(beadsOfTheDead, searchedDoor), makeKey); - goGetItems.addStep(new Conditions(beadsOfTheDead, revealedDoor), searchDoors); - goGetItems.addStep(new Conditions(beadsOfTheDead), searchPalms); - goGetItems.addStep(new Conditions(beads), useWireOnBeads); - goGetItems.addStep(new Conditions(pommel), useChiselOnPommel); - goGetItems.addStep(new Conditions(inCavern3), searchDolmen); - // Stone-plaque may be useless? - // Don't need to show Trufitus bone shard - // Reading tattered unlocks access to the island cavern - // Reading crumpled lets you use bronze wire on beads - goGetItems.addStep(new Conditions(stonePlaque, hasReadTattered, hasReadCrumpled, boneShard), searchRocksOnCairn); - goGetItems.addStep(new Conditions(stonePlaque, hasReadTattered, crumpledScroll, boneShard), readCrumpled); - goGetItems.addStep(new Conditions(stonePlaque, tatteredScroll, crumpledScroll, boneShard), readTattered); - goGetItems.addStep(new Conditions(stonePlaque, tatteredScroll, crumpledScroll, zadimusCorpse), buryCorpse); - goGetItems.addStep(new Conditions(inCavern2, stonePlaque, tatteredScroll, crumpledScroll), searchForCorpse); - goGetItems.addStep(new Conditions(inCavern2, stonePlaque, tatteredScroll), searchForCrumpledScroll); - goGetItems.addStep(new Conditions(inCavern2, stonePlaque), searchForTatteredScroll); - goGetItems.addStep(new Conditions(inCavern1, stonePlaque), enterDeeperCave); - goGetItems.addStep(inCavern1, useChiselOnStone); - goGetItems.addStep(moundNearby, lookAtMound); - steps.put(6, goGetItems); - steps.put(7, goGetItems); - steps.put(8, goGetItems); - steps.put(9, goGetItems); - - ConditionalStep goToDolem = new ConditionalStep(this, enterDoor); - goToDolem.addStep(inCavern4, useBonesOnDoor); - steps.put(10, goToDolem); - steps.put(11, goToDolem); - - ConditionalStep goDoFight = new ConditionalStep(this, enterDoor); - goDoFight.addStep(new Conditions(rashCorpse, inCavern3), useCorpseOnDolmen); - goDoFight.addStep(rashCorpse, enterCairnAgain); - goDoFight.addStep(corpseNearby, pickupCorpse); - goDoFight.addStep(nazNearby, killNazastarool); - goDoFight.addStep(inCavern4, searchDolmenForFight); - steps.put(12, goDoFight); - steps.put(13, goDoFight); - steps.put(14, goDoFight); - - return steps; + cavern1 = new Zone(new WorldPoint(2870, 9330, 0), new WorldPoint(2950, 9407, 0)); + cavern2 = new Zone(new WorldPoint(2878, 9282, 0), new WorldPoint(2942, 9333, 0)); + cavern3 = new Zone(new WorldPoint(2751, 9353, 0), new WorldPoint(2770, 9397, 0)); + cavern4 = new Zone(new WorldPoint(2833, 9463, 0), new WorldPoint(2943, 9533, 0)); } @Override @@ -177,7 +194,8 @@ protected void setupRequirements() charcoal = new ItemRequirement("Charcoal", ItemID.CHARCOAL); crumbleUndead = new ItemRequirement("Crumble undead spell for final boss", -1, -1); - emptySlot3 = new FreeInventorySlotRequirement(3); + freeInvSlot1 = new FreeInventorySlotRequirement(1); + freeInvSlot2 = new FreeInventorySlotRequirement(2); belt = new ItemRequirement("Wampum belt", ItemID.MOSOL_WAMPUM_BELT); stonePlaque = new ItemRequirement("Stone-plaque", ItemID.ZQPLAQUE); @@ -192,20 +210,8 @@ protected void setupRequirements() pommel = new ItemRequirement("Sword pommel", ItemID.ZQBEVSWORD); beads = new ItemRequirement("Bone beads", ItemID.ZQBONEBEADS); beadsOfTheDead = new ItemRequirement("Beads of the dead", ItemID.ZQDEADBEADS); - rashCorpse = new ItemRequirement("Rashiliya corpse", ItemID.ZQCORPSE); - } - - @Override - protected void setupZones() - { - cavern1 = new Zone(new WorldPoint(2870, 9330, 0), new WorldPoint(2950, 9407, 0)); - cavern2 = new Zone(new WorldPoint(2878, 9282, 0), new WorldPoint(2942, 9333, 0)); - cavern3 = new Zone(new WorldPoint(2751, 9353, 0), new WorldPoint(2770, 9397, 0)); - cavern4 = new Zone(new WorldPoint(2833, 9463, 0), new WorldPoint(2943, 9533, 0)); - } + rashCorpse = new ItemRequirement("Rashiliyia corpse", ItemID.ZQCORPSE); - public void setupConditions() - { moundNearby = new ObjectCondition(ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0)); inCavern1 = new ZoneRequirement(cavern1); inCavern2 = new ZoneRequirement(cavern2); @@ -218,25 +224,25 @@ public void setupConditions() ); shownStone = new Conditions(true, LogicType.OR, - new DialogRequirement("If you have found anything else that you need " + - "help with, please just let me know."), + new DialogRequirement("If you have found anything else that you need help with, please just let me know."), new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Trufitus identified the plaque") ); hasReadTattered = new Conditions(true, LogicType.OR, - new WidgetTextRequirement(220, 3, "Bervirius, son of King Danthalas"), + new WidgetTextRequirement(InterfaceID.Messagescroll.MESSCROLL3, "Bervirius, son of King Danthalas"), new VarplayerRequirement(VarPlayerID.ZOMBIEQUEEN, 9, Operation.GREATER_EQUAL) ); hasReadCrumpled = new Conditions(true, LogicType.OR, - new WidgetTextRequirement(222, 3, "Rashiliyia's rage went unchecked."), + new WidgetTextRequirement(InterfaceID.MessagescrollHandwriting.MESSAGESCROLL3_HW, "Rashiliyia's rage went unchecked."), beadsOfTheDead ); revealedDoor = new VarbitRequirement(VarbitID.ZQDOOR_MULTI, 1, Operation.GREATER_EQUAL); doorOpened = new VarbitRequirement(VarbitID.ZQDOOR_MULTI, 2, Operation.GREATER_EQUAL); searchedDoor = new Conditions(true, LogicType.OR, - new WidgetTextRequirement(229, 1, "Examining the door,") + // TODO: This might be able to use varbit ZQDOOR_MULTI == 1 + WidgetTextRequirement.messageBox("Examining the door,") ); nazNearby = new NpcInteractingRequirement(NpcID.ZQ_MAINZOMBIE1, NpcID.ZQ_MAINZOMBIE2, NpcID.ZQ_MAINZOMBIE3); @@ -246,56 +252,44 @@ public void setupConditions() public void setupSteps() { - talkToMosol = new NpcStep(this, NpcID.MOSOL_REI, new WorldPoint(2884, 2951, 0), - "Talk to Mosol Rei east of Shilo Village in south Karamja."); - talkToMosol.addDialogSteps("Why do I need to run?", "Rashiliyia? Who is she?", - "I'll go to see the Shaman.", "Yes, I'm sure and I'll take the Wampum belt to Trufitus."); + talkToMosol = new NpcStep(this, NpcID.MOSOL_REI, new WorldPoint(2884, 2951, 0), "Talk to Mosol Rei east of Shilo Village in south Karamja to receive a wampum belt.", freeInvSlot1); + talkToMosol.addDialogSteps("Why do I need to run?", "Rashiliyia? Who is she?", "I'll go to see the Shaman.", "Yes, I'm sure and I'll take the Wampum belt to Trufitus."); talkToMosol.addDialogStep(1, "What can we do?"); - useBeltOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), - "Use the belt on to Trufitus.", belt.highlighted()); - useBeltOnTrufitus.addIcon(ItemID.MOSOL_WAMPUM_BELT); - useBeltOnTrufitus.addDialogSteps("Mosol Rei said something about a legend?", "Why was it called Ah Za Rhoon?", - "Tell me more.", "I am going to search for Ah Za Rhoon!", - "Yes, I will seriously look for Ah Za Rhoon and I'd appreciate your help.", "Yes."); - useSpadeOnGround = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), - "Use a spade on the ground in south east Karamja.", spade.highlighted()); + + showBeltToTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), "Show the wampum belt to Trufitus in Tai Bwo Wannai village.", belt.highlighted()); + showBeltToTrufitus.addDialogStep("Mosol gave me something to show you."); + showBeltToTrufitus.addDialogStep("Mosol Rei said something about a legend?"); + showBeltToTrufitus.addDialogStep("Why was it called Ah Za Rhoon?"); + showBeltToTrufitus.addDialogStep("I am going to search for Ah Za Rhoon!"); + showBeltToTrufitus.addDialogStep("Yes."); + + useSpadeOnGround = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), "Use a spade on the ground in south east Karamja.", spade.highlighted()); useSpadeOnGround.addIcon(ItemID.SPADE); - lookAtMound = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), - "Look at the mound of earth in south east Karamja."); - useTorchOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), - "Use a lit torch or candle on the fissure.", torchOrCandle.highlighted()); + lookAtMound = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), "Look at the mound of earth in south east Karamja."); + useTorchOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), "Use a lit torch or candle on the fissure.", torchOrCandle.highlighted()); useTorchOnFissure.addDialogStep("Yes"); useTorchOnFissure.addIcon(ItemID.LIT_CANDLE); useTorchOnFissure.addSubSteps(lookAtMound); - useRopeOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), - "Use a rope on the fissure.", rope.highlighted()); + useRopeOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), "Use a rope on the fissure.", rope.highlighted()); useRopeOnFissure.addIcon(ItemID.ROPE); - searchFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE_WITHROPE, new WorldPoint(2922, 3000, 0), - "Right-click search the fissure."); + searchFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE_WITHROPE, new WorldPoint(2922, 3000, 0), "Right-click search the fissure."); searchFissure.addDialogStep("Yes, I'll give it a go!"); - useChiselOnStone = new ObjectStep(this, ObjectID.ZQSECRETSTONE, new WorldPoint(2901, 9379, 0), - "Use a chisel on the strange looking stone to the south.", chisel.highlighted()); + useChiselOnStone = new ObjectStep(this, ObjectID.ZQSECRETSTONE, new WorldPoint(2901, 9379, 0), "Use a chisel on the strange looking stone to the south.", chisel.highlighted()); useChiselOnStone.addIcon(ItemID.CHISEL); - enterDeeperCave = new ObjectStep(this, ObjectID.SECRETRUBBLE, new WorldPoint(2888, 9373, 0), - "Search the cave in to go deeper in the caverns."); + enterDeeperCave = new ObjectStep(this, ObjectID.SECRETRUBBLE, new WorldPoint(2888, 9373, 0), "Search the nearby cave-in to go deeper in the caverns."); enterDeeperCave.addDialogStep("Yes, I'll wriggle through."); - searchForTatteredScroll = new ObjectStep(this, ObjectID.SECRETRUBBLEBOOK, new WorldPoint(2885, 9318, 0), - "Search the loose rocks to the north for a tattered scroll."); + searchForTatteredScroll = new ObjectStep(this, ObjectID.SECRETRUBBLEBOOK, new WorldPoint(2885, 9318, 0), "Search the loose rocks to the north for a tattered scroll."); searchForTatteredScroll.addDialogStep("Yes, I'll carefully move the rocks to see what's behind them."); - searchForCrumpledScroll = new ObjectStep(this, ObjectID.ZQSACKS, new WorldPoint(2939, 9285, 0), - "Search the old sacks to the east for a crumpled scroll."); - searchForCorpse = new ObjectStep(this, ObjectID.ZQGALLOWS, new WorldPoint(2935, 9326, 0), - "Right-click search the gallows in the north east corner for a corpse."); + searchForCrumpledScroll = new ObjectStep(this, ObjectID.ZQSACKS, new WorldPoint(2939, 9285, 0), "Search the old sacks to the east for a crumpled scroll."); + searchForCorpse = new ObjectStep(this, ObjectID.ZQGALLOWS, new WorldPoint(2935, 9326, 0), "Right-click search the gallows in the north east corner for a corpse."); searchForCorpse.addDialogStep("Yes, I may find something else on the corpse."); - useCorpseOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), - "Use Zadimus's corpse on Trufitus.", zadimusCorpse.highlighted()); + useCorpseOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), "Use Zadimus's corpse on Trufitus.", zadimusCorpse.highlighted()); useCorpseOnTrufitus.addDialogStep("Is there any sacred ground around here?"); useCorpseOnTrufitus.addIcon(ItemID.ZQZADIMUSBONES); - useStonePlaqueOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), - "Use the stone-plaque on Trufitus.", stonePlaque.highlighted()); + useStonePlaqueOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), "Use the stone-plaque on Trufitus.", stonePlaque.highlighted()); useStonePlaqueOnTrufitus.addIcon(ItemID.ZQPLAQUE); readTattered = new DetailedQuestStep(this, "Read the tattered scroll.", tatteredScroll.highlighted()); @@ -304,86 +298,152 @@ public void setupSteps() readCrumpled = new DetailedQuestStep(this, "Read the crumpled scroll.", crumpledScroll.highlighted()); readCrumpled.addDialogSteps("Yes please."); - buryCorpse = new DetailedQuestStep(this, new WorldPoint(2795, 3089, 0), - "Bury Zadimus's corpse in the middle of Tai Bwo Wannai.", zadimusCorpse.highlighted()); + buryCorpse = new DetailedQuestStep(this, new WorldPoint(2795, 3089, 0), "Bury Zadimus's corpse in the middle of Tai Bwo Wannai.", zadimusCorpse.highlighted()); buryCorpse.addIcon(ItemID.ZQZADIMUSBONES); - searchRocksOnCairn = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), - "Right-click search the rocks on Cairn Isle."); + searchRocksOnCairn = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), "Right-click search the rocks on Cairn Isle."); searchRocksOnCairn.addDialogSteps("Yes please, I can think of nothing nicer!"); - searchDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), - "Right-click search the dolmen to the south."); - useChiselOnPommel = new DetailedQuestStep(this, "Use a chisel on the pommel.", chisel.highlighted(), - pommel.highlighted()); - useWireOnBeads = new DetailedQuestStep(this, "Use bronze wire on the beads.", bronzeWire.highlighted(), - beads.highlighted()); + searchDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), "Right-click search the tomb dolmen to the south."); + useChiselOnPommel = new DetailedQuestStep(this, "Use a chisel on the pommel.", chisel.highlighted(), pommel.highlighted()); + useWireOnBeads = new DetailedQuestStep(this, "Use bronze wire on the beads.", bronzeWire.highlighted(), beads.highlighted()); - searchPalms = new ObjectStep(this, ObjectID.ZQQUEST_HIDYTREE, new WorldPoint(2916, 3093, 0), - "Search the palm trees in the north east of Karamja. Come equipped for a boss fight.", - List.of(beadsOfTheDead.equipped(), boneShard, chisel, bones3, - combatGear), List.of(crumbleUndead, food)); + searchPalms = new ObjectStep(this, ObjectID.ZQQUEST_HIDYTREE, new WorldPoint(2916, 3093, 0), "Search the palm trees in the north east of Karamja. Come equipped for a boss fight.", List.of(beadsOfTheDead.equipped(), boneShard, chisel, bones3, combatGear), List.of(crumbleUndead, food)); - searchDoors = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), - "Right-click search the doors behind the palm trees.", combatGear); + searchDoors = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), "Right-click search the carved doors behind the palm trees.", combatGear); // 8180 opened? makeKey = new DetailedQuestStep(this, "Use a chisel on the bone shard.", chisel.highlighted(), boneShard.highlighted()); - useKeyOnDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), - "Use the bone key on the doors behind the palm trees.", boneKey.highlighted()); + useKeyOnDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), "Use the bone key on the doors behind the palm trees.", boneKey.highlighted()); useKeyOnDoor.addIcon(ItemID.ZQBONEKEY); - enterDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), - "Enter the doors behind the palm trees.", beadsOfTheDead.equipped(), bones3, - combatGear); - useBonesOnDoor = new ObjectStep(this, ObjectID.THZQ_TOMBROOML1, new WorldPoint(2892, 9480, 0), - "Equip the beads of the dead, then make your way through the gate, down the rocks, then to the south west" + - " corner. Use bones on the door there.", - beadsOfTheDead.equipped(), bones3.highlighted()); + enterDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), "Enter the doors behind the palm trees.", beadsOfTheDead.equipped(), bones3, combatGear); + useBonesOnDoor = new ObjectStep(this, ObjectID.THZQ_TOMBROOML1, new WorldPoint(2892, 9480, 0), "Equip the beads of the dead, then make your way through the gate, down the rocks, then to the south west corner. Use bones on the door there.", beadsOfTheDead.equipped(), bones3.highlighted()); useBonesOnDoor.addIcon(ItemID.BONES); - searchDolmenForFight = new ObjectStep(this, ObjectID.ZQRASHDOLMEN, new WorldPoint(2893, 9488, 0), - "Search the dolmen, ready to fight."); - - killNazastarool = new NpcStep(this, NpcID.ZQ_MAINZOMBIE1, new WorldPoint(2892, 9488, 0), - "Defeat Nazastarool's 3 forms. You can safe spot them over the dolmen, and the Crumble Undead spell is very" + - " strong against them."); - ((NpcStep) killNazastarool).addAlternateNpcs(NpcID.ZQ_MAINZOMBIE2, NpcID.ZQ_MAINZOMBIE3); - ((NpcStep)killNazastarool).addSafeSpots(new WorldPoint(2894, 9486, 0), new WorldPoint(2891, 9486, 0)); + searchDolmenForFight = new ObjectStep(this, ObjectID.ZQRASHDOLMEN, new WorldPoint(2893, 9488, 0), "Search the tomb dolmen, ready to fight."); + + killNazastarool = new NpcStep(this, NpcID.ZQ_MAINZOMBIE1, new WorldPoint(2892, 9488, 0), "Defeat Nazastarool's 3 forms. You can safe spot them over the tomb dolmen. The Crumble Undead spell is very strong against them."); + killNazastarool.addAlternateNpcs(NpcID.ZQ_MAINZOMBIE2, NpcID.ZQ_MAINZOMBIE3); + killNazastarool.addSafeSpots(new WorldPoint(2894, 9486, 0), new WorldPoint(2891, 9486, 0)); pickupCorpse = new ItemStep(this, "Pickup Rashiliyia's corpse.", rashCorpse); - enterCairnAgain = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), - "Right-click search the rocks on Cairn Isle to enter the caverns again.", rashCorpse); + enterCairnAgain = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), "Right-click search the rocks on Cairn Isle to enter the caverns again.", rashCorpse); enterCairnAgain.addDialogSteps("Yes please, I can think of nothing nicer!"); - useCorpseOnDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), - "Use Rashiliyia's corpse on the dolmen to the south.", rashCorpse.highlighted()); + useCorpseOnDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), "Use Rashiliyia's corpse on the dolmen to the south.", rashCorpse.highlighted()); useCorpseOnDolmen.addIcon(ItemID.ZQCORPSE); } @Override - public List getItemRequirements() + public Map loadSteps() { - return Arrays.asList(spade, torchOrCandle, rope, bronzeWire, chisel, bones3); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + var goStartQuest = new ConditionalStep(this, talkToMosol); + goStartQuest.addStep(belt.alsoCheckBank(), showBeltToTrufitus); + steps.put(0, goStartQuest); + + steps.put(1, useSpadeOnGround); + steps.put(2, useSpadeOnGround); + steps.put(3, useSpadeOnGround); + + var lightUpFissure = new ConditionalStep(this, useTorchOnFissure); + lightUpFissure.addStep(moundNearby, lookAtMound); + steps.put(4, lightUpFissure); + + var goUseRope = new ConditionalStep(this, useRopeOnFissure); + goUseRope.addStep(moundNearby, lookAtMound); + steps.put(5, goUseRope); + + var goGetItems = new ConditionalStep(this, searchFissure); + goGetItems.addStep(and(beadsOfTheDead, boneKey), useKeyOnDoor); + goGetItems.addStep(and(beadsOfTheDead, searchedDoor), makeKey); + goGetItems.addStep(and(beadsOfTheDead, revealedDoor), searchDoors); + goGetItems.addStep(and(beadsOfTheDead), searchPalms); + goGetItems.addStep(beads, useWireOnBeads); + goGetItems.addStep(pommel, useChiselOnPommel); + goGetItems.addStep(inCavern3, searchDolmen); + // Stone-plaque may be useless? + // Don't need to show Trufitus bone shard + // Reading tattered unlocks access to the island cavern + // Reading crumpled lets you use bronze wire on beads + goGetItems.addStep(and(stonePlaque, hasReadTattered, hasReadCrumpled, boneShard), searchRocksOnCairn); + goGetItems.addStep(and(stonePlaque, hasReadTattered, crumpledScroll, boneShard), readCrumpled); + goGetItems.addStep(and(stonePlaque, tatteredScroll, crumpledScroll, boneShard), readTattered); + goGetItems.addStep(and(stonePlaque, tatteredScroll, crumpledScroll, zadimusCorpse), buryCorpse); + goGetItems.addStep(and(inCavern2, stonePlaque, tatteredScroll, crumpledScroll), searchForCorpse); + goGetItems.addStep(and(inCavern2, stonePlaque, tatteredScroll), searchForCrumpledScroll); + goGetItems.addStep(and(inCavern2, stonePlaque), searchForTatteredScroll); + goGetItems.addStep(and(inCavern1, stonePlaque), enterDeeperCave); + goGetItems.addStep(inCavern1, useChiselOnStone); + goGetItems.addStep(moundNearby, lookAtMound); + steps.put(6, goGetItems); + steps.put(7, goGetItems); + steps.put(8, goGetItems); + steps.put(9, goGetItems); + + var goToDolem = new ConditionalStep(this, enterDoor); + goToDolem.addStep(inCavern4, useBonesOnDoor); + steps.put(10, goToDolem); + steps.put(11, goToDolem); + + var goDoFight = new ConditionalStep(this, enterDoor); + goDoFight.addStep(and(rashCorpse, inCavern3), useCorpseOnDolmen); + goDoFight.addStep(rashCorpse, enterCairnAgain); + goDoFight.addStep(corpseNearby, pickupCorpse); + goDoFight.addStep(nazNearby, killNazastarool); + goDoFight.addStep(inCavern4, searchDolmenForFight); + steps.put(12, goDoFight); + steps.put(13, goDoFight); + steps.put(14, goDoFight); + + return steps; } @Override - public List getItemRecommended() + public List getGeneralRequirements() { - return Arrays.asList(combatGear, food, staminas, antipoison, prayerPotions, quickTeleport, - papyrus, charcoal, crumbleUndead); + return List.of( + new QuestRequirement(QuestHelperQuest.JUNGLE_POTION, QuestState.FINISHED), + new SkillRequirement(Skill.CRAFTING, 20), + new SkillRequirement(Skill.AGILITY, 32) + ); } + @Override + public List getItemRequirements() + { + return List.of( + spade, + torchOrCandle, + rope, + bronzeWire, + chisel, + bones3 + ); + } @Override - public List getCombatRequirements() + public List getItemRecommended() { - return Collections.singletonList("Nazastarool 3 times (levels 68, 91, 93) (safespottable)"); + return List.of( + combatGear, + food, + staminas, + antipoison, + prayerPotions, + quickTeleport, + papyrus, + charcoal, + crumbleUndead + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.JUNGLE_POTION, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.CRAFTING, 20)); - req.add(new SkillRequirement(Skill.AGILITY, 32)); - return req; + return List.of( + "Nazastarool 3 times (levels 68, 91, 93) (safespottable)" + ); } @Override @@ -395,33 +455,77 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.CRAFTING, 3875)); + return List.of( + new ExperienceReward(Skill.CRAFTING, 3875) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to Shilo Village"), - new UnlockReward("Ability to mine gem rocks in Shilo Village")); + return List.of( + new UnlockReward("Access to Shilo Village"), + new UnlockReward("Ability to mine gem rocks in Shilo Village") + ); } - @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Exploring", - Arrays.asList(talkToMosol, useBeltOnTrufitus, useSpadeOnGround, useTorchOnFissure, useRopeOnFissure, - searchFissure, useChiselOnStone, enterDeeperCave, searchForTatteredScroll, searchForCrumpledScroll, - searchForCorpse, buryCorpse, readTattered, readCrumpled), spade, torchOrCandle, rope, chisel)); - - allSteps.add(new PanelDetails("Free Raiysha", - Arrays.asList(searchRocksOnCairn, searchDolmen, useChiselOnPommel, useWireOnBeads, searchPalms, - searchDoors, makeKey, useKeyOnDoor, enterDoor, useBonesOnDoor, searchDolmenForFight, killNazastarool, - pickupCorpse, enterCairnAgain, useCorpseOnDolmen), List.of(chisel, bronzeWire, bones3), - List.of(combatGear, food, crumbleUndead, prayerPotions))); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Exploring", List.of( + talkToMosol, + showBeltToTrufitus, + useSpadeOnGround, + useTorchOnFissure, + useRopeOnFissure, + searchFissure, + useChiselOnStone, + enterDeeperCave, + searchForTatteredScroll, + searchForCrumpledScroll, + searchForCorpse, + buryCorpse, + readTattered, + readCrumpled + ), List.of( + spade, + torchOrCandle, + rope, + chisel + ), List.of( + freeInvSlot1 + ))); + + sections.add(new PanelDetails("Free Rashiliyia", List.of( + searchRocksOnCairn, + searchDolmen, + useChiselOnPommel, + useWireOnBeads, + searchPalms, + searchDoors, + makeKey, + useKeyOnDoor, + enterDoor, + useBonesOnDoor, + searchDolmenForFight, + killNazastarool, + pickupCorpse, + enterCairnAgain, + useCorpseOnDolmen + ), List.of( + chisel, + bronzeWire, + bones3 + ), List.of( + combatGear, + food, + crumbleUndead, + prayerPotions, + freeInvSlot2 + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java index 5072ce38e90..8bf650269ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java @@ -40,9 +40,9 @@ import javax.inject.Inject; import java.awt.*; -import java.util.*; import java.util.List; import java.util.Queue; +import java.util.*; @Slf4j public class DoorPuzzleStep extends DetailedQuestStep @@ -60,7 +60,7 @@ public class DoorPuzzleStep extends DetailedQuestStep private boolean solving = false; - static class PuzzleLine + public static class PuzzleLine { public int[] cells; @@ -96,7 +96,11 @@ public DoorPuzzleStep(BasicQuestHelper questHelper) super(questHelper, "Solve the puzzle by marking the highlighted squares."); } - private PuzzleLine[] solve() + /** + * Entry point used in-game – reads the sums from the puzzle widgets + * and solves the Kakurasu grid. + */ + public PuzzleLine[] solve() { int[] rowSums = new int[SIZE]; int[] colSums = new int[SIZE]; @@ -114,32 +118,81 @@ private PuzzleLine[] solve() } PuzzleState solved = newSolveState(rowSums, colSums); - return solveGrid(solved); + return solveGrid(solved, rowSums, colSums); + } + + /** + * Intended for testing purposes, so we can easily feed in our own puzzles + */ + static PuzzleLine[] solveForSums(int[] rowSums, int[] colSums) + { + DoorPuzzleStep step = new DoorPuzzleStep(null); + PuzzleState solved = step.newSolveState(rowSums, colSums); + return step.solveGrid(solved, rowSums, colSums); + } + + private boolean gridSatisfiesSums(PuzzleLine[] grid, int[] rowSums, int[] colSums) + { + for (int r = 0; r < SIZE; r++) + { + int rowSum = 0; + for (int c = 0; c < SIZE; c++) + { + if (grid[r].cells[c] == FILLED) + { + rowSum += (c + 1); + } + } + if (rowSum != rowSums[r]) + { + return false; + } + } + for (int c = 0; c < SIZE; c++) + { + int colSum = 0; + for (int r = 0; r < SIZE; r++) + { + if (grid[r].cells[c] == FILLED) + { + colSum += (r + 1); + } + } + if (colSum != colSums[c]) + { + return false; + } + } + + return true; } - private PuzzleLine[] solveGrid(PuzzleState puzzleState) + private PuzzleLine[] solveGrid(PuzzleState puzzleState, int[] rowSums, int[] colSums) { int iterations = 0; Queue puzzleStates = new LinkedList<>(); puzzleStates.add(puzzleState); int MAX_ITERATIONS = 20; - while (iterations < MAX_ITERATIONS) + while (iterations < MAX_ITERATIONS && !puzzleStates.isEmpty()) { PuzzleState solution = checkSolutionOverlaps(puzzleStates.remove()); - if (solution == null && puzzleStates.isEmpty()) + if (solution == null) { - return null; + continue; } - else if (solution != null && solution.numberOfGray == 0) - { // If solved - return solution.grid; - } - /* If unable to find answer, assume a square if filled or empty and then try solving again */ - if (solution != null) + if (solution.numberOfGray == 0) { - puzzleStates.add(setFirstUnknownTo(solution, FILLED)); - puzzleStates.add(setFirstUnknownTo(solution, EMPTY)); + if (gridSatisfiesSums(solution.grid, rowSums, colSums)) + { + return solution.grid; + } + + iterations++; + continue; } + /* If unable to find answer, assume a square is filled or empty and then try solving again */ + puzzleStates.add(setFirstUnknownTo(solution, FILLED)); + puzzleStates.add(setFirstUnknownTo(solution, EMPTY)); iterations++; } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java index bc9e2f210bb..c81693fed28 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java @@ -31,7 +31,11 @@ import net.runelite.api.ItemContainer; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InventoryID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java index 381941bd11f..d9594b25c11 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java @@ -589,7 +589,7 @@ public ArrayList getPanels() smallFishingNet, pestleAndMortar, spear, agilityPotion4, rangedOrMagic, tinderbox, slicedBananaOrKnife, logsForFire)); allSteps.add(new PanelDetails("Gathering quest materials", Arrays.asList(fishKarambwaji, goToLubufu, getMoreVessel, fillVessel, getRum, sliceBanana, makeBananaRum), smallFishingNet, slicedBananaOrKnife)); - allSteps.add(new PanelDetails("Helping Tiadechel", talkToTiadeche1, giveVessel, askAboutResearch)); + allSteps.add(new PanelDetails("Helping Tiadeche", talkToTiadeche1, giveVessel, askAboutResearch)); allSteps.add(new PanelDetails("Collecting final items", Arrays.asList(pickupSeaweed, getJogreBones, burnBones, pickupBurntBones, makeKarambwanjiPaste, usePasteOnBones, getPoisonKarambwan, cookBones, cookKarambwan, usePestleOnKarambwan, usePasteOnSpear), tinderbox, karambwanji, pestleAndMortar)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java index 60ac9eb2ff8..04178d1a780 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java @@ -56,13 +56,13 @@ public class TempleOfIkov extends BasicQuestHelper { //Items Required - ItemRequirement pendantOfLucien, bootsOfLightness, limpwurt20, yewOrBetterBow, knife, lightSource, lever, iceArrows20, iceArrows, shinyKey, + ItemRequirement pendantOfLucien, bootsOfLightness, limpwurt20, yewOrBetterBow, throwableWeapon, yewOrBetterBowOrThrowableWeapon, knife, lightSource, lever, iceArrows20, iceArrowsWithThrowableWeapon, enoughArrows, iceArrows, shinyKey, armadylPendant, staffOfArmadyl, pendantOfLucienEquipped, bootsOfLightnessEquipped, iceArrowsEquipped; Requirement emptyInventorySpot; Requirement belowMinus1Weight, below4Weight, inEntryRoom, inNorthRoom, inBootsRoom, dontHaveBoots, inMainOrNorthRoom, - leverNearby, pulledLever, inArrowRoom, hasEnoughArrows, lesNearby, inLesRoom, inWitchRoom, inDemonArea, + leverNearby, pulledLever, inArrowRoom, hasArrowsWithThrowableWeapon, hasEnoughArrows, lesNearby, inLesRoom, inWitchRoom, inDemonArea, inArmaRoom; QuestStep talkToLucien, prepare, prepareBelow0, enterDungeonForBoots, enterDungeon, goDownToBoots, getBoots, goUpFromBoots, pickUpLever, @@ -181,12 +181,18 @@ protected void setupRequirements() yewOrBetterBow = new ItemRequirement("Yew, magic, or dark bow", ItemID.YEW_SHORTBOW).isNotConsumed(); yewOrBetterBow.addAlternates(ItemID.YEW_LONGBOW, ItemID.TRAIL_COMPOSITE_BOW_YEW, ItemID.MAGIC_SHORTBOW, ItemID.MAGIC_SHORTBOW_I, ItemID.MAGIC_LONGBOW, ItemID.DARKBOW); + throwableWeapon = new ItemRequirement("Throwable Weapon", ItemCollections.THROWING_KNIVES); + throwableWeapon.addAlternates(ItemCollections.DARTS); + throwableWeapon.addAlternates(ItemCollections.THROWING_AXES); + yewOrBetterBowOrThrowableWeapon = new ItemRequirements(LogicType.OR, "Yew, magic, dark bow, or thrown ranged weapons (darts, knives, thrownaxes)", yewOrBetterBow, throwableWeapon); knife = new ItemRequirement("Knife to get the boots of lightness", ItemID.KNIFE).isNotConsumed(); lightSource = new ItemRequirement("A light source to get the boots of lightness", ItemCollections.LIGHT_SOURCES).isNotConsumed(); iceArrows20 = new ItemRequirement("Ice arrows", ItemID.ICE_ARROW, 20); iceArrows = new ItemRequirement("Ice arrows", ItemID.ICE_ARROW); + iceArrowsWithThrowableWeapon = new ItemRequirements(LogicType.AND, "Ice Arrow with Throwable Weapon", iceArrows, throwableWeapon); + enoughArrows = new ItemRequirements(LogicType.OR, "Sufficient Arrows", iceArrows20, iceArrowsWithThrowableWeapon); iceArrowsEquipped = new ItemRequirement("Ice arrows", ItemID.ICE_ARROW, 1, true); lever = new ItemRequirement("Lever", ItemID.IKOV_LEVER); lever.setHighlightInInventory(true); @@ -236,10 +242,11 @@ public void setupConditions() inBootsRoom = new ZoneRequirement(bootsRoom); inMainOrNorthRoom = new Conditions(LogicType.OR, inEntryRoom, inNorthRoom, inLesRoom); - pulledLever = new Conditions(true, LogicType.OR, new WidgetTextRequirement(229, 1, "You hear the clunking of some hidden machinery.")); + pulledLever = new Conditions(true, LogicType.OR, new WidgetTextRequirement(229, 3, "You hear the clunking of some hidden machinery.")); leverNearby = new ObjectCondition(ObjectID.IKOV_MENDEDLEVER, new WorldPoint(2671, 9804, 0)); inArrowRoom = new ZoneRequirement(arrowRoom1, arrowRoom2, arrowRoom3); - hasEnoughArrows = new Conditions(true, LogicType.OR, iceArrows20); + hasArrowsWithThrowableWeapon = new Conditions(true, LogicType.AND, iceArrows, throwableWeapon); + hasEnoughArrows = new Conditions(true, LogicType.OR, iceArrows20, hasArrowsWithThrowableWeapon); lesNearby = new NpcCondition(NpcID.IKOV_FIREWARRIOR); inWitchRoom = new ZoneRequirement(witchRoom); @@ -256,20 +263,20 @@ public void setupSteps() talkToLucien.addDialogSteps("I'm a mighty hero!", "That sounds like a laugh!"); prepare = new DetailedQuestStep(this, "Get your weight below 0kg. You can get boots of lightness from the Temple of Ikov north of East Ardougne for -4.5kg.", - pendantOfLucienEquipped, limpwurt20, yewOrBetterBow); + pendantOfLucienEquipped, limpwurt20, yewOrBetterBowOrThrowableWeapon); prepareBelow0 = new DetailedQuestStep(this, "Get your weight below 0kg.", - pendantOfLucienEquipped, limpwurt20, yewOrBetterBow); + pendantOfLucienEquipped, limpwurt20, yewOrBetterBowOrThrowableWeapon); prepare.addSubSteps(prepareBelow0); enterDungeonForBoots = new ObjectStep(this, ObjectID.LADDER_CELLAR, new WorldPoint(2677, 3405, 0), "Enter the Temple of Ikov. You can get Boots of Lightness inside to get -4.5kg.", - pendantOfLucienEquipped, knife, lightSource, limpwurt20, yewOrBetterBow); + pendantOfLucienEquipped, knife, lightSource, limpwurt20, yewOrBetterBowOrThrowableWeapon); enterDungeon = new ObjectStep(this, ObjectID.LADDER_CELLAR, new WorldPoint(2677, 3405, 0), - "Enter the Temple of Ikov north of East Ardougne.", pendantOfLucienEquipped, yewOrBetterBow, limpwurt20); + "Enter the Temple of Ikov north of East Ardougne.", pendantOfLucienEquipped, yewOrBetterBowOrThrowableWeapon, limpwurt20); enterDungeon.addSubSteps(enterDungeonForBoots); @@ -285,7 +292,7 @@ public void setupSteps() pullLever = new ObjectStep(this, ObjectID.IKOV_MENDEDLEVER, new WorldPoint(2671, 9804, 0), "Pull the lever."); enterArrowRoom = new ObjectStep(this, ObjectID.IKOV_MENDEDLEVERDOORL, new WorldPoint(2662, 9803, 0), "Enter the south gate."); - collectArrows = new ObjectStep(this, ObjectID.IKOV_CHESTCLOSED, "Search the chests in the ice area of this room until you have at least 20 Ice Arrows or more to be safe. A random chest has the arrows each time.", iceArrows20); + collectArrows = new ObjectStep(this, ObjectID.IKOV_CHESTCLOSED, "Search the chests in the ice area of this room until you have at least 20 Ice Arrows or more to be safe. If using a throwable weapon (darts, knives) a single Ice Arrow is sufficient. A random chest has the arrows each time.", enoughArrows); collectArrows.setHideWorldArrow(true); collectArrows.addAlternateObjects(ObjectID.IKOV_CHESTOPEN); @@ -300,10 +307,10 @@ public void setupSteps() goSearchThievingLever.addSubSteps(goPullThievingLever); tryToEnterWitchRoom = new ObjectStep(this, ObjectID.IKOV_FIREWARRIORDOOR, new WorldPoint(2646, 9870, 0), - "Try to enter the far north door. Be prepared to fight Lesarkus, who can only be hurt by ice arrows.", yewOrBetterBow, iceArrowsEquipped); + "Try to enter the far north door. Be prepared to fight Lesarkus, who can only be hurt by ice arrows.", yewOrBetterBowOrThrowableWeapon, iceArrowsEquipped); fightLes = new NpcStep(this, NpcID.IKOV_FIREWARRIOR, new WorldPoint(2646, 9866, 0), - "Kill the Fire Warrior of Lesarkus. He can only be hurt by the ice arrows.", yewOrBetterBow, iceArrowsEquipped); + "Kill the Fire Warrior of Lesarkus. He can only be hurt by the ice arrows.", yewOrBetterBowOrThrowableWeapon, iceArrowsEquipped); enterDungeonKilledLes = new ObjectStep(this, ObjectID.LADDER_CELLAR, new WorldPoint(2677, 3405, 0), "Enter the Temple of Ikov north of East Ardougne.", pendantOfLucienEquipped, limpwurt20); @@ -351,7 +358,7 @@ public void setupSteps() public List getItemRequirements() { ArrayList reqs = new ArrayList<>(); - reqs.add(yewOrBetterBow); + reqs.add(yewOrBetterBowOrThrowableWeapon); reqs.add(limpwurt20); reqs.add(knife); reqs.add(lightSource); @@ -405,7 +412,7 @@ public List getPanels() allSteps.add(new PanelDetails("Defeat Lesarkus", Arrays.asList(prepare, enterDungeon, goDownToBoots, getBoots, goUpFromBoots, pickUpLever, useLeverOnHole, pullLever, enterArrowRoom, collectArrows, returnToMainRoom, goSearchThievingLever, - tryToEnterWitchRoom, fightLes), pendantOfLucien, yewOrBetterBow, knife, lightSource, limpwurt20)); + tryToEnterWitchRoom, fightLes), pendantOfLucien, yewOrBetterBowOrThrowableWeapon, knife, lightSource, limpwurt20)); allSteps.add(new PanelDetails("Explore deeper", Arrays.asList(enterLesDoor, giveWineldaLimps, pickUpKey, pushWall, makeChoice, returnToLucien))); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java index 2d193ec06a9..072b4eceb67 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java @@ -50,6 +50,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.QuestState; import net.runelite.api.Skill; +import net.runelite.api.annotations.Varbit; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java index 5bfbab6f2ac..efe8d25fee5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Zoinkwiz + * Copyright (c) 2026, pajlada * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +33,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; @@ -43,145 +47,188 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestSyncStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - -import java.util.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; public class TheDigSite extends BasicQuestHelper { - //Items Required - ItemRequirement pestleAndMortar, vialHighlighted, tinderbox, tea, ropes2, rope, opal, charcoal, specimenBrush, specimenJar, panningTray, - panningTrayFull, trowel, varrock2, digsiteTeleports, sealedLetter, specialCup, teddybear, skull, nitro, nitrate, chemicalCompound, groundCharcoal, invitation, talisman, - mixedChemicals, mixedChemicals2, arcenia, powder, liquid, tablet, key, unstampedLetter, trowelHighlighted, tinderboxHighlighted, chemicalCompoundHighlighted; - - Requirement talkedToFemaleStudent, talkedToOrangeStudent, talkedToGreenStudent, talkedToGuide, letterStamped, hasTeddy, hasSkull, hasSpecialCup, - femaleStudentQ1Learnt, orangeStudentQ1Learnt, greenStudentQ1Learnt, femaleStudentQ2Learnt, orangeStudentQ2Learnt, greenStudentQ2Learnt, femaleStudentQ3Learnt, - femaleExtorting, orangeStudentQ3Learnt, greenStudentQ3Learnt, syncedUp, syncedUp2, syncedUp3, givenTalismanIn, rope1Added, rope2Added, - inUndergroundTemple1, inDougRoom,openedBarrel, searchedBricks, hasKeyOrPowderOrMixtures, openPowderChestNearby, inUndergroundTemple2, - knowStateAsJustStartedQuest, knowStateAsJustCompletedFirstExam, knowStateAsJustCompletedSecondExam; - - QuestStep talkToExaminer, talkToHaig, talkToExaminer2, searchBush, takeTray, talkToGuide, panWater, pickpocketWorkmen, talkToFemaleStudent, talkToFemaleStudent2, - talkToOrangeStudent, talkToOrangeStudent2, talkToGreenStudent, talkToGreenStudent2, takeTest1, talkToFemaleStudent3, talkToOrangeStudent3, talkToGreenStudent3, - takeTest2, talkToFemaleStudent4, takeTest3, getJar, getBrush, digForTalisman, talkToExpert, useInvitationOnWorkman, useRopeOnWinch, goDownWinch, pickUpRoot, - searchBricks, goUpRope, goDownToDoug, talkToDoug, goUpFromDoug, unlockChest, searchChest, useTrowelOnBarrel, useVialOnBarrel, usePowderOnExpert, useLiquidOnExpert, - mixNitroWithNitrate, grindCharcoal, addCharcoal, addRoot, goDownToExplode, useCompound, useTinderbox, takeTablet, useTabletOnExpert, syncStep, talkToFemaleStudent5, - talkToOrangeStudent4, talkToGreenStudent4, useRopeOnWinch2, goDownToExplode2, goDownForTablet, goUpWithTablet, searchPanningTray; - - //Zones - Zone undergroundTemple1, dougRoom, undergroundTemple2; + // Required items + ItemRequirement pestleAndMortar; + ItemRequirement vial; + ItemRequirement tinderbox; + ItemRequirement tea; + ItemRequirement ropes2; + ItemRequirement rope; + ItemRequirement opal; + ItemRequirement charcoal; + + // Recommended items + ItemRequirement varrock2; + ItemRequirement digsiteTeleports; + + // Mid-quest item requirements + ItemRequirement specimenBrush; + ItemRequirement specimenJar; + ItemRequirement panningTray; + ItemRequirement panningTrayFull; + ItemRequirement trowel; + ItemRequirement sealedLetter; + ItemRequirement specialCup; + ItemRequirement teddybear; + ItemRequirement skull; + ItemRequirement nitro; + ItemRequirement nitrate; + ItemRequirement chemicalCompound; + ItemRequirement groundCharcoal; + ItemRequirement invitation; + ItemRequirement talisman; + ItemRequirement mixedChemicals; + ItemRequirement mixedChemicals2; + ItemRequirement arcenia; + + ItemRequirement powder; + ItemRequirement liquid; + ItemRequirement tablet; + ItemRequirement key; + ItemRequirement unstampedLetter; + ItemRequirement trowelHighlighted; + ItemRequirement chemicalCompoundHighlighted; + + // Zones + Zone undergroundTemple1; + Zone undergroundTemple2; + Zone dougRoom; + + // Miscellaneous requirements + Conditions talkedToFemaleStudent; + Conditions talkedToOrangeStudent; + Conditions talkedToGreenStudent; + VarbitRequirement talkedToGuide; + VarbitRequirement letterStamped; + Conditions hasTeddy; + Conditions hasSkull; + Conditions hasSpecialCup; + Conditions femaleStudentQ1Learnt; + Conditions orangeStudentQ1Learnt; + Conditions greenStudentQ1Learnt; + Conditions femaleStudentQ2Learnt; + Conditions orangeStudentQ2Learnt; + Conditions greenStudentQ2Learnt; + Conditions femaleStudentQ3Learnt; + Conditions femaleExtorting; + Conditions orangeStudentQ3Learnt; + Conditions greenStudentQ3Learnt; + Conditions syncedUp; + Conditions syncedUp2; + Conditions syncedUp3; + VarbitRequirement givenTalismanIn; + VarbitRequirement rope1Added; + VarbitRequirement rope2Added; + ZoneRequirement inUndergroundTemple1; + ZoneRequirement inDougRoom; + VarbitRequirement openedBarrel; + VarbitRequirement searchedBricks; + Conditions hasKeyOrPowderOrMixtures; + ObjectCondition openPowderChestNearby; + ZoneRequirement inUndergroundTemple2; + Conditions knowStateAsJustStartedQuest; + Conditions knowStateAsJustCompletedFirstExam; + Conditions knowStateAsJustCompletedSecondExam; + + // Steps + NpcStep talkToExaminer; + NpcStep talkToHaig; + NpcStep talkToExaminer2; + + ObjectStep searchBush; + DetailedQuestStep takeTray; + NpcStep talkToGuide; + ObjectStep panWater; + DetailedQuestStep searchPanningTray; + + NpcStep pickpocketWorkmen; + NpcStep talkToFemaleStudent; + NpcStep talkToOrangeStudent; + NpcStep talkToGreenStudent; + NpcStep talkToFemaleStudent2; + NpcStep talkToOrangeStudent2; + NpcStep talkToGreenStudent2; + NpcStep takeTest1; + + NpcStep talkToFemaleStudent3; + NpcStep talkToOrangeStudent3; + NpcStep talkToGreenStudent3; + NpcStep takeTest2; + + NpcStep talkToFemaleStudent5; + NpcStep talkToOrangeStudent4; + NpcStep talkToGreenStudent4; + NpcStep talkToFemaleStudent4; + NpcStep takeTest3; + + ObjectStep getJar; + NpcStep getBrush; + ObjectStep digForTalisman; + NpcStep talkToExpert; + + NpcStep useInvitationOnWorkman; + ObjectStep useRopeOnWinch; + ObjectStep goDownWinch; + ItemStep pickUpRoot; + ObjectStep searchBricks; + + ObjectStep goUpRope; + ObjectStep useRopeOnWinch2; + ObjectStep goDownToDoug; + NpcStep talkToDoug; + ObjectStep goUpFromDoug; + ObjectStep unlockChest; + ObjectStep searchChest; + ObjectStep useTrowelOnBarrel; + ObjectStep useVialOnBarrel; + NpcStep usePowderOnExpert; + NpcStep useLiquidOnExpert; + DetailedQuestStep mixNitroWithNitrate; + DetailedQuestStep grindCharcoal; + DetailedQuestStep addCharcoal; + DetailedQuestStep addRoot; + ObjectStep goDownToExplode; + ObjectStep goDownToExplode2; + ObjectStep useCompound; + + ObjectStep useTinderbox; + DetailedQuestStep waitForBricksToBlowUp; + ObjectStep takeTablet; + ObjectStep goDownForTablet; + + ObjectStep goUpWithTablet; + NpcStep useTabletOnExpert; + + QuestSyncStep syncStep; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToExaminer); - - ConditionalStep returnWithLetter = new ConditionalStep(this, talkToHaig); - // This is used to set knowStateAsJustStartedQuest to true - returnWithLetter.addStep(new Conditions(LogicType.NOR, knowStateAsJustStartedQuest), talkToExaminer); - returnWithLetter.addStep(letterStamped, talkToExaminer2); - steps.put(1, returnWithLetter); - - ConditionalStep goTakeTest1 = new ConditionalStep(this, syncStep); - // Sets the state of knowStateAsJustCompleted to true for ConditionalStep after this - goTakeTest1.addStep(new Conditions(LogicType.NOR, knowStateAsJustCompletedFirstExam), takeTest1); - - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, orangeStudentQ1Learnt, greenStudentQ1Learnt), takeTest1); - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, orangeStudentQ1Learnt, talkedToGreenStudent), talkToGreenStudent2); - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, orangeStudentQ1Learnt, hasSkull, specimenBrush), - talkToGreenStudent); - - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, talkedToOrangeStudent, hasSkull, specimenBrush), talkToOrangeStudent2); - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, hasSpecialCup, hasSkull, specimenBrush), talkToOrangeStudent); - - goTakeTest1.addStep(new Conditions(talkedToFemaleStudent, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent2); - goTakeTest1.addStep(new Conditions(hasTeddy, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent); - - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, hasSpecialCup), pickpocketWorkmen); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, panningTrayFull, talkedToGuide), searchPanningTray); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, panningTray, talkedToGuide), panWater); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, panningTray), talkToGuide); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy), takeTray); - goTakeTest1.addStep(syncedUp, searchBush); - steps.put(2, goTakeTest1); - - ConditionalStep goTakeTest2 = new ConditionalStep(this, syncStep); - // Sets the state of knowStateAsJustCompletedFirstExam to true for ConditionalStep after this - goTakeTest1.addStep(new Conditions(LogicType.NOR, knowStateAsJustCompletedSecondExam), takeTest2); - - goTakeTest2.addStep(new Conditions(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt, greenStudentQ2Learnt), takeTest2); - goTakeTest2.addStep(new Conditions(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt), talkToGreenStudent3); - goTakeTest2.addStep(new Conditions(syncedUp2, femaleStudentQ2Learnt), talkToOrangeStudent3); - goTakeTest2.addStep(syncedUp2, talkToFemaleStudent3); - steps.put(3, goTakeTest2); - - ConditionalStep goTakeTest3 = new ConditionalStep(this, syncStep); - goTakeTest3.addStep(new Conditions(femaleStudentQ3Learnt, orangeStudentQ3Learnt, greenStudentQ3Learnt), takeTest3); - goTakeTest3.addStep(new Conditions(syncedUp3, femaleStudentQ3Learnt, orangeStudentQ3Learnt), talkToGreenStudent4); - goTakeTest3.addStep(new Conditions(syncedUp3, femaleStudentQ3Learnt), talkToOrangeStudent4); - goTakeTest3.addStep(new Conditions(syncedUp3, femaleExtorting), talkToFemaleStudent5); - goTakeTest3.addStep(syncedUp3, talkToFemaleStudent4); - steps.put(4, goTakeTest3); - - ConditionalStep findTalisman = new ConditionalStep(this, getJar); - findTalisman.addStep(new Conditions(givenTalismanIn), useInvitationOnWorkman); - findTalisman.addStep(new Conditions(talisman), talkToExpert); - findTalisman.addStep(new Conditions(specimenJar, specimenBrush), digForTalisman); - findTalisman.addStep(new Conditions(specimenJar), getBrush); - steps.put(5, findTalisman); - - ConditionalStep learnHowToMakeExplosives = new ConditionalStep(this, useRopeOnWinch2); - learnHowToMakeExplosives.addStep(inDougRoom, talkToDoug); - learnHowToMakeExplosives.addStep(new Conditions(inUndergroundTemple1, arcenia), goUpRope); - learnHowToMakeExplosives.addStep(inUndergroundTemple1, pickUpRoot); - learnHowToMakeExplosives.addStep(new Conditions(rope2Added), goDownToDoug); - - ConditionalStep makeExplosives = new ConditionalStep(this, goDownWinch); - makeExplosives.addStep(new Conditions(chemicalCompound, inUndergroundTemple1), useCompound); - - makeExplosives.addStep(inDougRoom, goUpFromDoug); - makeExplosives.addStep(new Conditions(inUndergroundTemple1, arcenia), goUpRope); - makeExplosives.addStep(inUndergroundTemple1, pickUpRoot); - - makeExplosives.addStep(new Conditions(chemicalCompound), goDownToExplode); - makeExplosives.addStep(new Conditions(arcenia, mixedChemicals2), addRoot); - makeExplosives.addStep(new Conditions(arcenia, mixedChemicals, groundCharcoal), addCharcoal); - makeExplosives.addStep(new Conditions(arcenia, mixedChemicals), grindCharcoal); - makeExplosives.addStep(new Conditions(arcenia, nitrate, nitro), mixNitroWithNitrate); - makeExplosives.addStep(new Conditions(arcenia, powder, nitro), usePowderOnExpert); - makeExplosives.addStep(new Conditions(arcenia, powder, liquid), useLiquidOnExpert); - makeExplosives.addStep(new Conditions(arcenia, powder, liquid), useVialOnBarrel); - makeExplosives.addStep(new Conditions(arcenia, powder, openedBarrel), useVialOnBarrel); - makeExplosives.addStep(new Conditions(arcenia, powder), useTrowelOnBarrel); - makeExplosives.addStep(new Conditions(openPowderChestNearby, arcenia), searchChest); - makeExplosives.addStep(arcenia, unlockChest); - - ConditionalStep discovery = new ConditionalStep(this, useRopeOnWinch); - discovery.addStep(hasKeyOrPowderOrMixtures, makeExplosives); - discovery.addStep(searchedBricks, learnHowToMakeExplosives); - discovery.addStep(new Conditions(inUndergroundTemple1, arcenia), searchBricks); - discovery.addStep(inUndergroundTemple1, pickUpRoot); - discovery.addStep(rope1Added, goDownWinch); - steps.put(6, discovery); - - ConditionalStep explodeWall = new ConditionalStep(this, goDownToExplode2); - explodeWall.addStep(inUndergroundTemple1, useTinderbox); - steps.put(7, explodeWall); - - ConditionalStep completeQuest = new ConditionalStep(this, goDownForTablet); - completeQuest.addStep(new Conditions(tablet.alsoCheckBank(), inUndergroundTemple2), goUpWithTablet); - completeQuest.addStep(new Conditions(tablet.alsoCheckBank()), useTabletOnExpert); - completeQuest.addStep(inUndergroundTemple2, takeTablet); - steps.put(8, completeQuest); - - return steps; + undergroundTemple1 = new Zone(new WorldPoint(3359, 9800, 0), new WorldPoint(3393, 9855, 0)); + undergroundTemple2 = new Zone(new WorldPoint(3360, 9734, 0), new WorldPoint(3392, 9790, 0)); + dougRoom = new Zone(new WorldPoint(3340, 9809, 0), new WorldPoint(3357, 9826, 0)); } @Override @@ -189,10 +236,9 @@ protected void setupRequirements() { pestleAndMortar = new ItemRequirement("Pestle and mortar", ItemID.PESTLE_AND_MORTAR).isNotConsumed(); pestleAndMortar.setHighlightInInventory(true); - vialHighlighted = new ItemRequirement("Vial", ItemID.VIAL_EMPTY); - vialHighlighted.setHighlightInInventory(true); + vial = new ItemRequirement("Vial", ItemID.VIAL_EMPTY); + vial.setHighlightInInventory(true); tinderbox = new ItemRequirement("Tinderbox", ItemID.TINDERBOX).isNotConsumed(); - tinderboxHighlighted = tinderbox.highlighted(); tea = new ItemRequirement("Cup of tea", ItemID.CUP_OF_TEA); ropes2 = new ItemRequirement("Rope", ItemID.ROPE, 2); rope = new ItemRequirement("Rope", ItemID.ROPE); @@ -203,6 +249,10 @@ protected void setupRequirements() charcoal = new ItemRequirement("Charcoal", ItemID.CHARCOAL); charcoal.setTooltip("Obtainable during quest by searching specimen trays"); charcoal.setHighlightInInventory(true); + + varrock2 = new ItemRequirement("Varrock teleports", ItemID.POH_TABLET_VARROCKTELEPORT, 2); + digsiteTeleports = new ItemRequirement("Digsite teleports", ItemID.TELEPORTSCROLL_DIGSITE, 2); + specimenBrush = new ItemRequirement("Specimen brush", ItemID.SPECIMEN_BRUSH).isNotConsumed(); specimenJar = new ItemRequirement("Specimen jar", ItemID.SPECIMEN_JAR).isNotConsumed(); panningTray = new ItemRequirement("Panning tray", ItemID.TRAY_EMPTY).isNotConsumed(); @@ -213,8 +263,6 @@ protected void setupRequirements() trowelHighlighted = new ItemRequirement("Trowel", ItemID.TROWEL).isNotConsumed(); trowelHighlighted.setHighlightInInventory(true); trowelHighlighted.setTooltip("You can get another from one of the Examiners"); - varrock2 = new ItemRequirement("Varrock teleports", ItemID.POH_TABLET_VARROCKTELEPORT, 2); - digsiteTeleports = new ItemRequirement("Digsite teleports", ItemID.TELEPORTSCROLL_DIGSITE, 2); sealedLetter = new ItemRequirement("Sealed letter", ItemID.RECOMMENDEDLETTER); sealedLetter.setTooltip("You can get another from Curator Haig in the Varrock Museum"); specialCup = new ItemRequirement("Special cup", ItemID.ROCK_SAMPLE2); @@ -251,28 +299,15 @@ protected void setupRequirements() key.setHighlightInInventory(true); unstampedLetter = new ItemRequirement("Unstamped letter", ItemID.DIGPLAINLETTER); unstampedLetter.setTooltip("You can get another from the Exam Centre's examiners"); - } - @Override - protected void setupZones() - { - undergroundTemple1 = new Zone(new WorldPoint(3359, 9800, 0), new WorldPoint(3393, 9855, 0)); - undergroundTemple2 = new Zone(new WorldPoint(3360, 9734, 0), new WorldPoint(3392, 9790, 0)); - dougRoom = new Zone(new WorldPoint(3340, 9809, 0), new WorldPoint(3357, 9826, 0)); - } - - public void setupConditions() - { inUndergroundTemple1 = new ZoneRequirement(undergroundTemple1); inUndergroundTemple2 = new ZoneRequirement(undergroundTemple2); inDougRoom = new ZoneRequirement(dougRoom); - knowStateAsJustStartedQuest = new Conditions(true, new VarplayerRequirement(VarPlayerID.ITEXAMLEVEL, 1, Operation.LESS_EQUAL)); knowStateAsJustCompletedFirstExam = new Conditions(true, new VarplayerRequirement(VarPlayerID.ITEXAMLEVEL, 2, Operation.LESS_EQUAL)); knowStateAsJustCompletedSecondExam = new Conditions(true, new VarplayerRequirement(VarPlayerID.ITEXAMLEVEL, 3, Operation.LESS_EQUAL)); - syncedUp = new Conditions(true, LogicType.OR, knowStateAsJustStartedQuest, new WidgetTextRequirement(InterfaceID.Questjournal.TITLE, "The Dig Site")); @@ -282,14 +317,13 @@ public void setupConditions() new DialogRequirement("Hey! Excellent!")); syncedUp3 = new Conditions(true, LogicType.OR, knowStateAsJustCompletedSecondExam, - new WidgetTextRequirement(119, 2, "The Dig Site"), + new WidgetTextRequirement(InterfaceID.Questjournal.TITLE, "The Dig Site"), new DialogRequirement("You got all the questions correct, well done!"), new DialogRequirement("Great, I'm getting good at this.")); talkedToGuide = new VarbitRequirement(VarbitID.ITDIGSITETEA, 1); tea = tea.hideConditioned(talkedToGuide); - // Exam questions 1 talkedToFemaleStudent = new Conditions(true, LogicType.OR, new DialogRequirement("Hey! My lucky mascot!"), @@ -302,7 +336,7 @@ public void setupConditions() orangeGivenAnswer1Diary.addRange(20, 35); talkedToOrangeStudent = new Conditions(true, LogicType.OR, new DialogRequirement("Look what I found!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "to find it and return it to him.")); + new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "He has lost his Special Cup")); orangeStudentQ1Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("The people eligible to use the digsite are:"), orangeGivenAnswer1Diary); @@ -312,7 +346,7 @@ public void setupConditions() talkedToGreenStudent = new Conditions(true, LogicType.OR, new DialogRequirement("Oh wow! You've found it!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "to him; maybe someone has picked it up?")); + new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "He has lost his Animal Skull")); greenStudentQ1Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("The study of Earth Sciences is:"), greenGivenAnswer1Diary); @@ -341,7 +375,7 @@ public void setupConditions() new DialogRequirement("OK, I'll see what I can turn up for you."), new DialogRequirement("Well, I have seen people get them from panning"), new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to bring her an opal")); - WidgetTextRequirement femaleGivenAnswer3Diary = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to speak to the student in the purple skirt about"); + WidgetTextRequirement femaleGivenAnswer3Diary = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to bring her an opal"); femaleGivenAnswer3Diary.addRange(56, 63); femaleStudentQ3Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("Sample preparation: Samples cleaned"), @@ -354,7 +388,7 @@ public void setupConditions() orangeGivenAnswer3Diary); WidgetTextRequirement greenGivenAnswer3Diary = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to speak to the student in the green top about the"); - greenGivenAnswer3Diary.addRange(56, 63); + greenGivenAnswer3Diary.addRange(54, 63); greenStudentQ3Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("Specimen brush use: Brush carefully"), greenGivenAnswer3Diary); @@ -366,25 +400,24 @@ public void setupConditions() rope2Added = new VarbitRequirement(VarbitID.ITDIGSITEWINCH2, 1); // 45 - 54 - hasTeddy = new Conditions(LogicType.OR, teddybear, talkedToFemaleStudent); - hasSkull = new Conditions(LogicType.OR, skull, talkedToGreenStudent); - hasSpecialCup = new Conditions(LogicType.OR, specialCup, talkedToOrangeStudent); + hasTeddy = or(teddybear, talkedToFemaleStudent); + hasSkull = or(skull, talkedToGreenStudent); + hasSpecialCup = or(specialCup, talkedToOrangeStudent); letterStamped = new VarbitRequirement(VarbitID.ITCURATORLETTER, 1); - searchedBricks = new VarbitRequirement(VarbitID.ITDIGSITEHINT, 1); openPowderChestNearby = new ObjectCondition(ObjectID.DIGCHESTOPEN); openedBarrel = new VarbitRequirement(VarbitID.ITDIGSITEBARREL, 1); - hasKeyOrPowderOrMixtures = new Conditions(LogicType.OR, - key, powder, nitrate, mixedChemicals, mixedChemicals2, chemicalCompound, openPowderChestNearby); + hasKeyOrPowderOrMixtures = or(key, powder, nitrate, mixedChemicals, mixedChemicals2, chemicalCompound, openPowderChestNearby); } public void setupSteps() { talkToExaminer = new NpcStep(this, NpcID.EXAMINER, new WorldPoint(3362, 3337, 0), "Talk to an Examiner in the Exam Centre south east of Varrock."); talkToExaminer.addDialogStep("Can I take an exam?"); - ((NpcStep) (talkToExaminer)).addAlternateNpcs(NpcID.QIP_DIGSITE_EXAMINER_02, NpcID.QIP_DIGSITE_EXAMINER_03); + talkToExaminer.addDialogStep("Yes."); + talkToExaminer.addAlternateNpcs(NpcID.QIP_DIGSITE_EXAMINER_02, NpcID.QIP_DIGSITE_EXAMINER_03); talkToHaig = new NpcStep(this, NpcID.CURATOR, new WorldPoint(3257, 3448, 0), "Talk to Curator Haig in the Varrock Museum.", unstampedLetter); talkToExaminer2 = new NpcStep(this, NpcID.EXAMINER, new WorldPoint(3362, 3337, 0), "Return to an Examiner in the Exam Centre south east of Varrock.", sealedLetter); @@ -397,8 +430,8 @@ public void setupSteps() panWater.addSubSteps(searchPanningTray); pickpocketWorkmen = new NpcStep(this, NpcID.DIGWORKMAN1, new WorldPoint(3372, 3390, 0), "Pickpocket workmen until you get an animal skull and a specimen brush.", true); - ((NpcStep) (pickpocketWorkmen)).addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); - ((NpcStep) (pickpocketWorkmen)).setMaxRoamRange(100); + pickpocketWorkmen.addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); + pickpocketWorkmen.setMaxRoamRange(100); talkToFemaleStudent = new NpcStep(this, NpcID.STUDENT2, new WorldPoint(3345, 3425, 0), "Talk to the female student in the north west of the Digsite twice.", teddybear); talkToOrangeStudent = new NpcStep(this, NpcID.STUDENT3, new WorldPoint(3369, 3419, 0), "Talk to the student in an orange shirt in the north east of the Digsite twice.", specialCup); talkToGreenStudent = new NpcStep(this, NpcID.STUDENT1, new WorldPoint(3362, 3398, 0), "Talk to the student in a green shirt in the south of the Digsite twice.", skull); @@ -429,21 +462,22 @@ public void setupSteps() "Brush carefully and slowly using short strokes.", "Handle bones very carefully and keep them away from other samples."); getJar = new ObjectStep(this, ObjectID.QIP_DIGSITE_CUPBOARDSHUT, new WorldPoint(3355, 3332, 0), "Search the cupboard on the south wall of the west room of the Exam Centre for a specimen jar."); - ((ObjectStep) (getJar)).addAlternateObjects(ObjectID.QIP_DIGSITE_CUPBOARDOPEN); + getJar.addAlternateObjects(ObjectID.QIP_DIGSITE_CUPBOARDOPEN); getBrush = new NpcStep(this, NpcID.DIGWORKMAN1, new WorldPoint(3372, 3390, 0), "Pickpocket workmen until you get a specimen brush.", true); - ((NpcStep) (getBrush)).addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); - ((NpcStep) (getBrush)).setMaxRoamRange(100); + getBrush.addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); + getBrush.setMaxRoamRange(100); // NOTE: May not need pick digForTalisman = new ObjectStep(this, ObjectID.DIGDUGUPSOIL2, new WorldPoint(3374, 3438, 0), "Dig in the north east dig spot in the Digsite until you get a talisman.", trowelHighlighted, specimenJar, specimenBrush); digForTalisman.addIcon(ItemID.TROWEL); + digForTalisman.addSubSteps(getBrush); talkToExpert = new NpcStep(this, NpcID.ARCHAEOLOGICAL_EXPERT, new WorldPoint(3357, 3334, 0), "Talk to the Archaeological expert in the Exam Centre.", talisman); useInvitationOnWorkman = new NpcStep(this, NpcID.DIGWORKMAN1, new WorldPoint(3360, 3415, 0), "Use the invitation on any workman.", true, invitation); useInvitationOnWorkman.addIcon(ItemID.DIGEXPERTSCROLL); useInvitationOnWorkman.addDialogStep("I lost the letter you gave me."); - ((NpcStep) (useInvitationOnWorkman)).addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); - ((NpcStep) (useInvitationOnWorkman)).setMaxRoamRange(100); + useInvitationOnWorkman.addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); + useInvitationOnWorkman.setMaxRoamRange(100); useRopeOnWinch = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Use a rope on the west winch.", rope); useRopeOnWinch.addIcon(ItemID.ROPE); goDownWinch = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the west winch."); @@ -463,7 +497,7 @@ public void setupSteps() useTrowelOnBarrel = new ObjectStep(this, ObjectID.DIGBARRELCLOSED, new WorldPoint(3364, 3378, 0), "Use a trowel on the barrel west of the chest's tent.", trowelHighlighted); useTrowelOnBarrel.addIcon(ItemID.TROWEL); - useVialOnBarrel = new ObjectStep(this, ObjectID.DIGBARRELCLOSED, new WorldPoint(3364, 3378, 0), "Use a vial on the barrel west of the chest's tent.", vialHighlighted); + useVialOnBarrel = new ObjectStep(this, ObjectID.DIGBARRELCLOSED, new WorldPoint(3364, 3378, 0), "Use a vial on the barrel west of the chest's tent.", vial); useVialOnBarrel.addIcon(ItemID.VIAL_EMPTY); usePowderOnExpert = new NpcStep(this, NpcID.ARCHAEOLOGICAL_EXPERT, new WorldPoint(3357, 3334, 0), "Use the powder on the Archaeological expert in the Exam Centre.", powder); usePowderOnExpert.addIcon(ItemID.UNIDENTIFIED_POWDER); @@ -471,7 +505,7 @@ public void setupSteps() useLiquidOnExpert.addIcon(ItemID.UNIDENTIFIED_LIQUID); mixNitroWithNitrate = new DetailedQuestStep(this, "Mix the nitroglycerin and ammonium nitrate together.", nitro, nitrate); grindCharcoal = new DetailedQuestStep(this, "Grind charcoal with a pestle and mortar.", pestleAndMortar, charcoal); - addCharcoal = new DetailedQuestStep(this, "Add charcoal to the vial.", groundCharcoal, mixedChemicals); + addCharcoal = new DetailedQuestStep(this, "Add the ground charcoal to the vial.", groundCharcoal, mixedChemicals); addRoot = new DetailedQuestStep(this, "Add arcenia root to the vial.", arcenia, mixedChemicals2); goDownToExplode = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the rope on the west winch.", chemicalCompound, tinderbox); goDownToExplode2 = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the rope on the west winch.", tinderbox); @@ -479,8 +513,10 @@ public void setupSteps() useCompound = new ObjectStep(this, ObjectID.DIGBLASTBRICK, new WorldPoint(3378, 9824, 0), "Use the compound on the bricks to the south.", chemicalCompoundHighlighted); useCompound.addIcon(ItemID.DIGCOMPOUND); - useTinderbox = new ObjectStep(this, ObjectID.DIGBLASTBRICK, new WorldPoint(3378, 9824, 0), "Use a tinderbox on the bricks to the south.", tinderboxHighlighted); + useTinderbox = new ObjectStep(this, ObjectID.DIGBLASTBRICK, new WorldPoint(3378, 9824, 0), "Use a tinderbox on the bricks to the south.", tinderbox.highlighted()); useTinderbox.addIcon(ItemID.TINDERBOX); + waitForBricksToBlowUp = new DetailedQuestStep(this, new WorldPoint(3378, 9824, 0), "Use a tinderbox on the bricks to the south."); + useTinderbox.addSubSteps(waitForBricksToBlowUp); takeTablet = new ObjectStep(this, ObjectID.QIP_DIGSITE_ZAROS_STONE_TABLET_MULTILOC, new WorldPoint(3373, 9746, 0), "Take the stone tablet in the south room."); goDownForTablet = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the rope on the west winch."); takeTablet.addSubSteps(goDownForTablet); @@ -490,35 +526,159 @@ public void setupSteps() useTabletOnExpert.addIcon(ItemID.ZAROSSTONETABLET); useTabletOnExpert.addSubSteps(goUpWithTablet); - syncStep = new DetailedQuestStep(this, "Open the quest's journal to sync your current quest state."); + syncStep = new QuestSyncStep(this, getQuest(), "Open the quest's journal to sync your current quest state."); } @Override - public List getNotes() + public Map loadSteps() { - return Collections.singletonList("This quest helper is susceptible to getting out of sync with the actual quest. If this happens to you, opening up the quest's journal should fix it."); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToExaminer); + + var returnWithLetter = new ConditionalStep(this, talkToHaig); + // This is used to set knowStateAsJustStartedQuest to true + returnWithLetter.addStep(nor(knowStateAsJustStartedQuest), talkToExaminer); + returnWithLetter.addStep(letterStamped, talkToExaminer2); + steps.put(1, returnWithLetter); + + var goTakeTest1 = new ConditionalStep(this, syncStep); + // Sets the state of knowStateAsJustCompleted to true for ConditionalStep after this + goTakeTest1.addStep(nor(knowStateAsJustCompletedFirstExam), takeTest1); + + goTakeTest1.addStep(and(femaleStudentQ1Learnt, orangeStudentQ1Learnt, greenStudentQ1Learnt), takeTest1); + goTakeTest1.addStep(and(femaleStudentQ1Learnt, orangeStudentQ1Learnt, talkedToGreenStudent), talkToGreenStudent2); + goTakeTest1.addStep(and(femaleStudentQ1Learnt, orangeStudentQ1Learnt, hasSkull, specimenBrush), talkToGreenStudent); + + goTakeTest1.addStep(and(femaleStudentQ1Learnt, talkedToOrangeStudent, hasSkull, specimenBrush), talkToOrangeStudent2); + goTakeTest1.addStep(and(femaleStudentQ1Learnt, hasSpecialCup, hasSkull, specimenBrush), talkToOrangeStudent); + + goTakeTest1.addStep(and(talkedToFemaleStudent, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent2); + goTakeTest1.addStep(and(hasTeddy, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent); + + goTakeTest1.addStep(and(syncedUp, hasTeddy, hasSpecialCup), pickpocketWorkmen); + goTakeTest1.addStep(and(syncedUp, hasTeddy, panningTrayFull, talkedToGuide), searchPanningTray); + goTakeTest1.addStep(and(syncedUp, hasTeddy, panningTray, talkedToGuide), panWater); + goTakeTest1.addStep(and(syncedUp, hasTeddy, panningTray), talkToGuide); + goTakeTest1.addStep(and(syncedUp, hasTeddy), takeTray); + goTakeTest1.addStep(syncedUp, searchBush); + steps.put(2, goTakeTest1); + + var goTakeTest2 = new ConditionalStep(this, syncStep); + // Sets the state of knowStateAsJustCompletedFirstExam to true for ConditionalStep after this + goTakeTest1.addStep(nor(knowStateAsJustCompletedSecondExam), takeTest2); + + goTakeTest2.addStep(and(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt, greenStudentQ2Learnt), takeTest2); + goTakeTest2.addStep(and(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt), talkToGreenStudent3); + goTakeTest2.addStep(and(syncedUp2, femaleStudentQ2Learnt), talkToOrangeStudent3); + goTakeTest2.addStep(syncedUp2, talkToFemaleStudent3); + steps.put(3, goTakeTest2); + + var goTakeTest3 = new ConditionalStep(this, syncStep); + goTakeTest3.addStep(and(femaleStudentQ3Learnt, orangeStudentQ3Learnt, greenStudentQ3Learnt), takeTest3); + goTakeTest3.addStep(and(syncedUp3, femaleStudentQ3Learnt, orangeStudentQ3Learnt), talkToGreenStudent4); + goTakeTest3.addStep(and(syncedUp3, femaleStudentQ3Learnt), talkToOrangeStudent4); + goTakeTest3.addStep(and(syncedUp3, femaleExtorting), talkToFemaleStudent5); + goTakeTest3.addStep(syncedUp3, talkToFemaleStudent4); + steps.put(4, goTakeTest3); + + var findTalisman = new ConditionalStep(this, getJar); + findTalisman.addStep(and(givenTalismanIn), useInvitationOnWorkman); + findTalisman.addStep(and(talisman), talkToExpert); + findTalisman.addStep(and(specimenJar, specimenBrush), digForTalisman); + findTalisman.addStep(and(specimenJar), getBrush); + steps.put(5, findTalisman); + + var learnHowToMakeExplosives = new ConditionalStep(this, useRopeOnWinch2); + learnHowToMakeExplosives.addStep(inDougRoom, talkToDoug); + learnHowToMakeExplosives.addStep(and(inUndergroundTemple1, arcenia), goUpRope); + learnHowToMakeExplosives.addStep(inUndergroundTemple1, pickUpRoot); + learnHowToMakeExplosives.addStep(and(rope2Added), goDownToDoug); + + var makeExplosives = new ConditionalStep(this, goDownWinch); + makeExplosives.addStep(and(chemicalCompound, inUndergroundTemple1), useCompound); + + makeExplosives.addStep(inDougRoom, goUpFromDoug); + makeExplosives.addStep(and(inUndergroundTemple1, arcenia), goUpRope); + makeExplosives.addStep(inUndergroundTemple1, pickUpRoot); + + makeExplosives.addStep(chemicalCompound, goDownToExplode); + makeExplosives.addStep(and(arcenia, mixedChemicals2), addRoot); + makeExplosives.addStep(and(arcenia, mixedChemicals, groundCharcoal), addCharcoal); + makeExplosives.addStep(and(arcenia, mixedChemicals), grindCharcoal); + makeExplosives.addStep(and(arcenia, nitrate, nitro), mixNitroWithNitrate); + makeExplosives.addStep(and(arcenia, powder, nitro), usePowderOnExpert); + makeExplosives.addStep(and(arcenia, powder, liquid), useLiquidOnExpert); + makeExplosives.addStep(and(arcenia, powder, liquid), useVialOnBarrel); + makeExplosives.addStep(and(arcenia, powder, openedBarrel), useVialOnBarrel); + makeExplosives.addStep(and(arcenia, powder), useTrowelOnBarrel); + makeExplosives.addStep(and(openPowderChestNearby, arcenia), searchChest); + makeExplosives.addStep(arcenia, unlockChest); + + var discovery = new ConditionalStep(this, useRopeOnWinch); + discovery.addStep(hasKeyOrPowderOrMixtures, makeExplosives); + discovery.addStep(searchedBricks, learnHowToMakeExplosives); + discovery.addStep(and(inUndergroundTemple1, arcenia), searchBricks); + discovery.addStep(inUndergroundTemple1, pickUpRoot); + discovery.addStep(rope1Added, goDownWinch); + steps.put(6, discovery); + + var explodeWall = new ConditionalStep(this, goDownToExplode2); + explodeWall.addStep(inUndergroundTemple1, useTinderbox); + steps.put(7, explodeWall); + + var completeQuest = new ConditionalStep(this, goDownForTablet); + completeQuest.addStep(and(tablet.alsoCheckBank(), inUndergroundTemple2), goUpWithTablet); + completeQuest.addStep(and(tablet.alsoCheckBank()), useTabletOnExpert); + completeQuest.addStep(inUndergroundTemple2, takeTablet); + completeQuest.addStep(inUndergroundTemple1, waitForBricksToBlowUp); + steps.put(8, completeQuest); + + return steps; + } + + @Override + public List getGeneralRequirements() + { + return List.of( + new SkillRequirement(Skill.AGILITY, 10, true), + new SkillRequirement(Skill.HERBLORE, 10, true), + new SkillRequirement(Skill.THIEVING, 25) + ); } @Override public List getItemRequirements() { - return Arrays.asList(pestleAndMortar, vialHighlighted, tinderbox, tea, ropes2, opal, charcoal); + return List.of( + pestleAndMortar, + vial, + tinderbox, + tea, + ropes2, + opal, + charcoal + ); } @Override public List getItemRecommended() { - return Arrays.asList(digsiteTeleports, varrock2); + return List.of( + digsiteTeleports, + varrock2 + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - ArrayList req = new ArrayList<>(); - req.add(new SkillRequirement(Skill.AGILITY, 10, true)); - req.add(new SkillRequirement(Skill.HERBLORE, 10, true)); - req.add(new SkillRequirement(Skill.THIEVING, 25)); - return req; + return List.of( + "This quest helper is susceptible to getting out of sync with the actual quest. If this happens to you, opening up the quest's journal should fix it." + ); } @Override @@ -530,38 +690,114 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Arrays.asList( - new ExperienceReward(Skill.MINING, 15300), - new ExperienceReward(Skill.HERBLORE, 2000)); + return List.of( + new ExperienceReward(Skill.MINING, 15300), + new ExperienceReward(Skill.HERBLORE, 2000) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Gold Bars", ItemID.GOLD_BAR, 2)); + return List.of( + new ItemReward("Gold Bars", ItemID.GOLD_BAR, 2) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Ability to clean specimens in the Varrock Museum")); + return List.of( + new UnlockReward("Ability to clean specimens in the Varrock Museum") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(talkToExaminer, talkToHaig, talkToExaminer2, searchBush, takeTray, talkToGuide, panWater, pickpocketWorkmen, talkToFemaleStudent, talkToFemaleStudent2, - talkToOrangeStudent, talkToOrangeStudent2, talkToGreenStudent, talkToGreenStudent2, takeTest1), tea)); - - allSteps.add(new PanelDetails("Exam 2", Arrays.asList(talkToFemaleStudent3, talkToOrangeStudent3, talkToGreenStudent3, takeTest2))); - allSteps.add(new PanelDetails("Exam 3", Arrays.asList(talkToFemaleStudent4, talkToFemaleStudent5, talkToOrangeStudent4, - talkToGreenStudent4, takeTest3), opal)); - allSteps.add(new PanelDetails("Discovery", Arrays.asList(getJar, digForTalisman, talkToExpert, useInvitationOnWorkman), trowel, specimenBrush)); - allSteps.add(new PanelDetails("Digging deeper", Arrays.asList(useRopeOnWinch, goDownWinch, pickUpRoot, searchBricks, goUpRope, useRopeOnWinch2, goDownToDoug, - talkToDoug, goUpFromDoug, unlockChest, searchChest, useTrowelOnBarrel, useVialOnBarrel, useLiquidOnExpert, usePowderOnExpert, mixNitroWithNitrate, grindCharcoal, addCharcoal, addRoot, goDownToExplode, - useCompound, useTinderbox, takeTablet, useTabletOnExpert), ropes2, trowelHighlighted, pestleAndMortar, vialHighlighted, tinderboxHighlighted, charcoal)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToExaminer, + talkToHaig, + talkToExaminer2, + searchBush, + takeTray, + talkToGuide, + panWater, + pickpocketWorkmen, + talkToFemaleStudent, + talkToFemaleStudent2, + talkToOrangeStudent, + talkToOrangeStudent2, + talkToGreenStudent, + talkToGreenStudent2, + takeTest1 + ), List.of( + tea + ))); + + sections.add(new PanelDetails("Exam 2", List.of( + talkToFemaleStudent3, + talkToOrangeStudent3, + talkToGreenStudent3, + takeTest2 + ))); + + sections.add(new PanelDetails("Exam 3", List.of( + talkToFemaleStudent4, + talkToFemaleStudent5, + talkToOrangeStudent4, + talkToGreenStudent4, + takeTest3 + ), List.of( + opal + ))); + + sections.add(new PanelDetails("Discovery", List.of( + getJar, + digForTalisman, + talkToExpert, + useInvitationOnWorkman + ), List.of( + trowel, + specimenBrush + ))); + + sections.add(new PanelDetails("Digging deeper", List.of( + useRopeOnWinch, + goDownWinch, + pickUpRoot, + searchBricks, + goUpRope, + useRopeOnWinch2, + goDownToDoug, + talkToDoug, + goUpFromDoug, + unlockChest, + searchChest, + useTrowelOnBarrel, + useVialOnBarrel, + useLiquidOnExpert, + usePowderOnExpert, + mixNitroWithNitrate, + grindCharcoal, + addCharcoal, + addRoot, + goDownToExplode, + useCompound, + useTinderbox, + takeTablet, + useTabletOnExpert + ), List.of( + ropes2, + trowelHighlighted, + pestleAndMortar, + vial, + tinderbox, + charcoal + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java index 4c3b5719acd..df73c851dbe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java @@ -50,6 +50,9 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; + +import java.util.*; + import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; import net.runelite.api.QuestState; @@ -61,8 +64,6 @@ import net.runelite.api.gameval.*; import net.runelite.client.eventbus.Subscribe; -import java.util.*; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; /** @@ -509,7 +510,6 @@ private int getSumOfLitBraziers() new WorldPoint(1286, 9438, 1), new WorldPoint(1289, 9435, 1), new WorldPoint(1296, 9435, 1) - ); int total = 0; @@ -612,9 +612,12 @@ protected void setupRequirements() combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); + // Technically only applies for the cultist fight to have these foods available, but as they're recommended last + // It shouldn't impact any existing suggestions for players + food.addAlternates(ItemID.COOKED_LIZARD, ItemID.BREAM_FISH_COOKED); food.setUrlSuffix("Food"); - prayerPotions = new ItemRequirement("Prayer potions", ItemCollections.PRAYER_POTIONS, 3); + prayerPotions.addAlternates(ItemID._4DOSEMOONLIGHTPOTION, ItemID._3DOSEMOONLIGHTPOTION, ItemID._2DOSEMOONLIGHTPOTION, ItemID._1DOSEMOONLIGHTPOTION); whistle = new ItemRequirement("Quetzal whistle", ItemID.HG_QUETZALWHISTLE_BASIC); whistle.addAlternates(ItemID.HG_QUETZALWHISTLE_ENHANCED, ItemID.HG_QUETZALWHISTLE_PERFECTED); @@ -825,7 +828,7 @@ public void setupSteps() enterPassage.addDialogSteps("Enter the passage."); pickBlueChest = new ObjectStep(this, ObjectID.TWILIGHT_TEMPLE_METZLI_CHAMBER_CHEST_CLOSED, new WorldPoint(1723, 9709, 0), "Picklock the chest in the " + "hidden room. Be ready for a fight afterwards."); - fightEnforcer = new NpcStep(this, NpcID.VMQ4_TEMPLE_GUARD_BOSS_FIGHT, new WorldPoint(1712, 9706, 0), "Defeat the enforcer. You cannot use prayers" + + fightEnforcer = new NpcStep(this, NpcID.VMQ4_TEMPLE_GUARD_BOSS_FIGHT, new WorldPoint(1712, 9706, 0), "Defeat the enforcer. You cannot use prayers, or teleport out" + ". Step away each time he goes to attack, and step behind him or sideways if he says 'Traitor!' or 'Thief!'."); pickUpEmissaryScroll = new ItemStep(this, "Pick up the emissary scroll.", emissaryScroll); readEmissaryScroll = new DetailedQuestStep(this, "Read the emissary scroll.", emissaryScroll.highlighted()); @@ -884,7 +887,7 @@ public void setupSteps() showSackToVibia = showSackToVibiaNotPuzzleWrapped.puzzleWrapStep(true); showSackToVibiaNotPuzzleWrapped.addSubSteps(goF2ToF1HideoutEnd, goToF0HideoutEnd); - takePotato.addSubSteps(removePotatoesFromSack, takeKnife, takeCoinPurse, goToF1Hideout, goDownFromF2Hideout, goF1ToF2Hideout, useKnifeOnPottedFan, + takePotato.addSubSteps(takeKnife, takeCoinPurse, goToF1Hideout, goDownFromF2Hideout, goF1ToF2Hideout, useKnifeOnPottedFan, fillCoinPurse, emptyCoinPurse, useBranchOnCoinPurse, goToF0Hideout, goToF0HideoutEnd, goF2ToF1HideoutEnd, showSackToVibia); searchBodyForKey = new NpcStep(this, NpcID.VMQ4_JANUS_HOUSE_JANUS_UNCONSCIOUS, new WorldPoint(1647, 3093, 0), "Search Janus."); @@ -1242,7 +1245,7 @@ public List getPanels() civitasTeleport ))); panels.add(new PanelDetails("The hideout", List.of(talkToQueen, talkToCaptainVibia, inspectWindow, giveBonesOrMeatToDog, enterDoorCode, takePotato, - takeKnife, goToF1Hideout, takeCoinPurse, goF1ToF2Hideout, useKnifeOnPottedFan, fillCoinPurse, useBranchOnCoinPurse, showSackToVibia, + removePotatoesFromSack, takeKnife, goToF1Hideout, takeCoinPurse, goF1ToF2Hideout, useKnifeOnPottedFan, fillCoinPurse, useBranchOnCoinPurse, showSackToVibia, searchBodyForKey, enterTrapdoor, talkToQueenToGoCamTorum), List.of(bone), List.of())); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java index 88a68fe21a9..d2142ed6bc6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java @@ -48,7 +48,6 @@ import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.text.Rs2TextSanitizer; import java.util.*; import java.util.regex.Matcher; @@ -98,7 +97,7 @@ protected void updateSteps() if (widget != null) { - String text = Rs2TextSanitizer.sanitizeWidgetMultilineText(widget.getText()); + String text = widget.getText().replace("
", " "); Matcher jugOnJugMatcher = JUG_VALUES_MATCHER.matcher(text); Matcher jugEmptiedMatcher = JUG_EMPTIED.matcher(text); Matcher jugFilledMatcher = JUG_FILLED.matcher(text); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java index 9eeb50b5f38..28db2ffcf3e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java @@ -632,7 +632,7 @@ public List getPanels() allSteps.add(new PanelDetails("Collecting beard tax", Arrays.asList(collectFromHringAgain, collectFromRaum, collectFromSkuliAgain, collectFromKeepaAgain, collectFromFlosi, talkToGjukiAfterCollection2))); allSteps.add(new PanelDetails("Spy on Mawnis again", Arrays.asList(talkToSlugToSpyAgain, goSpyOnMawnisAgain, reportBackToSlugAgain, talkToGjukiAfterSpy2, talkToMawnisWithDecree))); allSteps.add(prepareForCombatPanel); - allSteps.add(new PanelDetails("Killing the king", Arrays.asList(enterCave, killTrolls, enterKingRoom, killKing, decapitateKing, finishQuest), yakBottom, yakTop, roundShield, meleeWeapon, food)); + allSteps.add(new PanelDetails("Killing the king", Arrays.asList(enterCave, killTrolls, enterKingRoom, killKing, decapitateKing, finishQuest), roundShield, meleeWeapon, food)); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java index 1dca85d6b7a..6ff93e4e06a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java @@ -49,7 +49,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -298,7 +302,7 @@ protected void setupRequirements() petRock = new ItemRequirement("Pet rock", ItemID.VT_USELESS_ROCK).isNotConsumed(); petRock.setTooltip("You can get another from Askeladden"); - emptySlot4 = new ItemRequirement("4 empty inventory slots", -1, 4); + emptySlot4 = new ItemRequirement("Empty inventory slots for vegetables and a pet rock", -1, 4); goldenWool = new ItemRequirement("Golden wool", ItemID.VIKING_GOLDEN_WOOL); goldenFleece = new ItemRequirement("Golden fleece", ItemID.VIKING_GOLDEN_FLEECE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java index e3d178d04c4..9c5d0faa82a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java @@ -32,6 +32,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.TeleportItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -40,7 +42,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -48,14 +58,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class TheGolem extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java index 74be88eb58a..af474f4d6d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java @@ -27,6 +27,7 @@ import com.google.common.collect.Lists; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; +import net.runelite.client.plugins.microbot.questhelper.domain.QuetzalDestination; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.secretsofthenorth.ArrowChestPuzzleStep; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; @@ -37,6 +38,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NoFollowerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.InInstanceRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; @@ -93,6 +95,8 @@ public class TheHeartOfDarkness extends BasicQuestHelper ItemRequirement towerKey, book, poem, scrapOfPaper1, scrapOfPaper2, scrapOfPaper3, completedNote, emissaryHood, emissaryTop, emissaryBottom, emissaryBoots, emissaryRobesEquipped, emissaryRobes, airIcon, waterIcon, earthIcon, fireIcon; + NoFollowerRequirement noFollower; + Requirement atTeomat, builtLandingInOverlook, talkedToSergius, talkedToCaritta, talkedToFelius, princeIsFollowing, inFirstTrialRoom, inSecondTrialRoom, southEastGateUnlocked, southWestChestOpened, hasReadPoem, knowAboutDirections, inArrowPuzzle, combatStarted, startedInvestigation, freeInvSlots4; @@ -406,6 +410,7 @@ protected void setupRequirements() fireIcon = new ItemRequirement("Fire icon", ItemID.VMQ3_RUINS_FIRE_STATUE_REPAIR); + noFollower = new NoFollowerRequirement("No pet following you"); } private void setupConditions() @@ -542,15 +547,11 @@ private void setupSteps() { talkToItzlaAtTeomat = new NpcStep(this, NpcID.VMQ2_ITZLA_VIS, new WorldPoint(1454, 3173, 0), "Talk to Prince Itzla Arkan at the Teomat. You" + " can travel here using Renu the quetzal."); - WidgetHighlight teomatWidget = new WidgetHighlight(874, 15, true); - teomatWidget.setModelIdRequirement(51205); - talkToItzlaAtTeomat.addWidgetHighlight(teomatWidget); + talkToItzlaAtTeomat.addWidgetHighlight(WidgetHighlight.createQuetzalHighlight(QuetzalDestination.THE_TEOMAT)); talkToItzlaAtTeomat.addDialogStep("Yes."); travelToGorge = new NpcStep(this, NpcID.QUETZAL_CHILD_GREEN_NOOP, new WorldPoint(1437, 3169, 0), "Travel on Renu to the Quetzacalli Gorge."); ((NpcStep) travelToGorge).addAlternateNpcs(NpcID.QUETZAL_CHILD_GREEN_FEED, NpcID.QUETZAL_CHILD_GREEN, NpcID.QUETZAL_CHILD_ORANGE, NpcID.QUETZAL_CHILD_BLUE, NpcID.QUETZAL_CHILD_CYAN, NpcID.QUETZAL_CHILD_GREEN_ORANGE); - WidgetHighlight gorgeWidget = new WidgetHighlight(874, 15, true); - gorgeWidget.setModelIdRequirement(54539); - travelToGorge.addWidgetHighlight(gorgeWidget); + travelToGorge.addWidgetHighlight(WidgetHighlight.createQuetzalHighlight(QuetzalDestination.QUETZACALLI_GORGE)); talkToBartender = new NpcStep(this, NpcID.QUETZACALLI_BARTENDER, new WorldPoint(1499, 3224, 0), "Talk to the Bartender in the pub in the Gorge.", coins.quantity(30)); // Told about ground room, 11123 1->0 @@ -635,7 +636,7 @@ private void setupSteps() talkToFelius = new NpcStep(this, NpcID.VMQ3_RECRUIT_1_VIS, new WorldPoint(1659, 3224, 0), "Talk to Felius outside the tower."); talkToCaritta = new NpcStep(this, NpcID.VMQ3_RECRUIT_2_VIS, new WorldPoint(1659, 3224, 0), "Talk to Caritta outside the tower."); talkToPrinceAfterRecruits = new NpcStep(this, NpcID.VMQ3_ITZLA_VIS_CITIZEN, new WorldPoint(1656, 3219, 0), "Talk to the prince at the Tower " + - "of Ascension to the south-east of the salvager overlook again."); + "of Ascension to the south-east of the salvager overlook again.", noFollower); talkToPrinceAfterRecruits.addDialogStep("Could you remind me what Ximoua is?"); talkToJanus = new NpcStep(this, NpcID.VMQ3_FOREBEARER_JANUS_VIS, new WorldPoint(1638, 3224, 0), "Talk to Forebearer Janus inside the tower."); @@ -966,6 +967,7 @@ private void setupSteps() talkToServius = new NpcStep(this, NpcID.VMQ3_SERVIUS_VIS, new WorldPoint(1681, 3168, 0), "Talk to Servius, Teokan of Ralos in the palace" + " in Civitas illa Fortis to complete the quest."); + talkToServius.addWidgetHighlight(WidgetHighlight.createQuetzalHighlight(QuetzalDestination.CIVITAS_ILLA_FORTIS)); talkToServius.addTeleport(civitasIllaFortisTeleport); } @@ -1154,7 +1156,7 @@ public List getPanels() allSteps.add(new PanelDetails("Final Trial", List.of(fightPrinceSidebar, talkToJanusAfterPrinceFight))); allSteps.add(new PanelDetails("Cult", List.of(talkToJanusAfterAllTrials, searchChestForEmissaryRobes, talkToItzlaToFollow, enterTemple, talkToItzlaAfterSermon, talkToFides))); allSteps.add(new PanelDetails("The Old Ones", List.of(enterRuins, takePickaxe, mineRocks, pullFirstLever, climbDownLedge, slideAlongIceLedge, pullSecondLever, jumpOverFrozenPlatforms, pullThirdLever, - pullFourthLever, pullChain, inspectAirMarkings, inspectEarthMarkings, searchAirUrn, searchEarthUrn, inspectWaterMarkings, inspectFireMarkings, + pullFourthLever, pullChain, climbDownIceShortcut, inspectAirMarkings, inspectEarthMarkings, searchAirUrn, searchEarthUrn, inspectWaterMarkings, inspectFireMarkings, searchFireUrn, searchWaterUrn, fixWaterStatue, fixFireStatue, fixEarthStatue, fixAirStatue, activateFirstStatue, activateSecondStatue, activateThirdStatue, activateFourthStatue, enterFinalBossRoom, defeatAmoxliatlSidebar, talkToServius), List.of(combatGear, freeInvSlots4), List.of(food, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theidesofmilk/TheIdesOfMilk.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theidesofmilk/TheIdesOfMilk.java new file mode 100644 index 00000000000..8df4efc5d02 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theidesofmilk/TheIdesOfMilk.java @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2026, adamsbytes + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.helpers.quests.theidesofmilk; + +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; +import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.CombatLevelRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; +import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; +import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; + +public class TheIdesOfMilk extends BasicQuestHelper +{ + // Recommended items + ItemRequirement combatGear; + ItemRequirement food; + + // Mid-quest item requirements + ItemRequirement husbandryBook; + ItemRequirement milkSample1; + ItemRequirement milkSample2; + + // Zones + Zone lumbridgeCastleF1; + + // Miscellaneous requirements + VarbitRequirement gillieInformed; + ZoneRequirement inLumbridgeCastleF1; + NpcCondition brutusNearby; + + // Steps + NpcStep talkToCassius; + NpcStep talkToGillie; + NpcStep talkToSeth; + ObjectStep searchShelves; + NpcStep returnToCassiusWithBook; + NpcStep talkToCassiusAboutBook; + DetailedQuestStep drinkMilkSample1; + NpcStep talkToCassiusAfterDrink; + ObjectStep goUpToLumbridgeCastleF1; + NpcStep talkToDuke; + NpcStep talkToGillieAgain; + DetailedQuestStep drinkMilkSample2; + NpcStep talkToGillieAfterDrink; + ObjectStep openBullPen; + NpcStep killBrutus; + NpcStep talkToGillieAfterFight; + NpcStep finishQuest; + + @Override + protected void setupZones() + { + lumbridgeCastleF1 = new Zone(new WorldPoint(3203, 3206, 1), new WorldPoint(3218, 3231, 1)); + } + + @Override + protected void setupRequirements() + { + husbandryBook = new ItemRequirement("The groats principles", ItemID.COWQUEST_HUSBANDRY_BOOK); + husbandryBook.canBeObtainedDuringQuest(); + + milkSample1 = new ItemRequirement("Milk sample", ItemID.COWQUEST_MILK_SAMPLE_1); + milkSample1.canBeObtainedDuringQuest(); + milkSample1.setTooltip("You can get another from Cassius"); + + milkSample2 = new ItemRequirement("Milk sample", ItemID.COWQUEST_MILK_SAMPLE_2); + milkSample2.canBeObtainedDuringQuest(); + milkSample2.setTooltip("You can get another from Cassius"); + + gillieInformed = new VarbitRequirement(VarbitID.COWQUEST_GILLIE_INFORMATION, 1); + inLumbridgeCastleF1 = new ZoneRequirement(lumbridgeCastleF1); + + combatGear = new ItemRequirement("Combat gear", -1, -1).isNotConsumed(); + combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); + + food = new ItemRequirement("Food", -1, -1); + food.setDisplayItemId(BankSlotIcons.getFood()); + } + + public void setupSteps() + { + talkToCassius = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Speak to Cassius by the pond north-west of Lumbridge to start the quest.", true); + talkToCassius.addDialogStep("Yes."); + + talkToGillie = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Speak to Gillie Groats at the cow field east of Lumbridge."); + talkToGillie.addDialogStep("Can you share what makes your cows so productive?"); + + talkToSeth = new NpcStep(this, NpcID.FAVOUR_SETH_GROATS, + new WorldPoint(3228, 3291, 0), + "Speak to Seth Groats at his farmhouse east of the River Lum."); + + searchShelves = new ObjectStep(this, ObjectID.COWQUEST_SETH_SHELF, + new WorldPoint(3227, 3287, 0), + "Search the shelves in Seth's farmhouse for 'The groats principles'."); + + returnToCassiusWithBook = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Return to Cassius with the book.", true, husbandryBook); + + talkToCassiusAboutBook = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Talk to Cassius.", true); + returnToCassiusWithBook.addSubSteps(talkToCassiusAboutBook); + + drinkMilkSample1 = new DetailedQuestStep(this, + "Drink the milk sample near Cassius.", milkSample1.highlighted()); + + talkToCassiusAfterDrink = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Talk to Cassius after drinking the milk sample.", true); + + goUpToLumbridgeCastleF1 = new ObjectStep(this, QHObjectID.LUMBRIDGE_CASTLE_F0_SOUTH_STAIRCASE, + new WorldPoint(3205, 3208, 0), + "Speak to Duke Horacio on the first floor of Lumbridge Castle.", milkSample2); + + talkToDuke = new NpcStep(this, NpcID.DUKE_OF_LUMBRIDGE, + new WorldPoint(3210, 3220, 1), + "Speak to Duke Horacio on the first floor of Lumbridge Castle.", milkSample2); + talkToDuke.addSubSteps(goUpToLumbridgeCastleF1); + + talkToGillieAgain = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Speak to Gillie Groats at the cow field."); + + drinkMilkSample2 = new DetailedQuestStep(this, + "Drink the milk sample near Gillie.", milkSample2.highlighted()); + + talkToGillieAfterDrink = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Talk to Gillie Groats after drinking the milk sample."); + + brutusNearby = new NpcCondition(NpcID.COWBOSS); + + openBullPen = new ObjectStep(this, ObjectID.FENCEGATE_L_COWBOSS_START, + new WorldPoint(3262, 3294, 0), + "Open the bull pen gate in the north-east corner of the cow field to fight the Bull (level 30).", + combatGear, food); + openBullPen.addDialogStep("Yes."); + + killBrutus = new NpcStep(this, NpcID.COWBOSS, + new WorldPoint(3262, 3294, 0), + "Kill the Bull (level 30). Protect from Melee blocks his basic attacks (max hit 3). Dodge his ground slam ('snorts') and charge ('growls') by walking through him. Special attacks can hit over 15.", + combatGear, food); + openBullPen.addSubSteps(killBrutus); + + talkToGillieAfterFight = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Speak to Gillie Groats after defeating the Bull."); + + finishQuest = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Return to Cassius to complete the quest. You can then speak to Gillie Groats for a cow bell amulet and magic lamp (1,000 XP combat/Prayer).", true); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToCassius); + steps.put(1, talkToCassius); + steps.put(2, talkToCassius); + + var cInvestigate = new ConditionalStep(this, talkToGillie); + cInvestigate.addStep(gillieInformed, talkToSeth); + steps.put(3, cInvestigate); + + var cGetBook = new ConditionalStep(this, searchShelves); + cGetBook.addStep(husbandryBook, returnToCassiusWithBook); + steps.put(4, cGetBook); + var cReturnBook = new ConditionalStep(this, talkToCassiusAboutBook); + cReturnBook.addStep(husbandryBook, returnToCassiusWithBook); + steps.put(5, cReturnBook); + + steps.put(6, drinkMilkSample1); + steps.put(8, talkToCassiusAfterDrink); + var cTalkToDuke = new ConditionalStep(this, goUpToLumbridgeCastleF1); + cTalkToDuke.addStep(inLumbridgeCastleF1, talkToDuke); + steps.put(10, cTalkToDuke); + steps.put(12, talkToGillieAgain); + steps.put(14, drinkMilkSample2); + steps.put(16, talkToGillieAfterDrink); + var cFightBrutus = new ConditionalStep(this, openBullPen); + cFightBrutus.addStep(brutusNearby, killBrutus); + steps.put(18, cFightBrutus); + steps.put(20, talkToGillieAfterFight); + steps.put(21, finishQuest); + + return steps; + } + + @Override + public List getGeneralRecommended() + { + return List.of( + new CombatLevelRequirement(15) + ); + } + + @Override + public List getItemRecommended() + { + return List.of(combatGear, food); + } + + @Override + public List getCombatRequirements() + { + return List.of("Bull (level 30)"); + } + + @Override + public QuestPointReward getQuestPointReward() + { + return new QuestPointReward(1); + } + + @Override + public List getUnlockRewards() + { + return List.of( + new UnlockReward("Access to the cow boss"), + new UnlockReward("Cow bell amulet and magic lamp (1,000 XP combat/Prayer) from Gillie Groats") + ); + } + + @Override + public List getPanels() + { + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToCassius + ))); + + sections.add(new PanelDetails("Investigation", List.of( + talkToGillie, + talkToSeth, + searchShelves + ))); + + sections.add(new PanelDetails("Milk tasting", List.of( + returnToCassiusWithBook, + drinkMilkSample1, + talkToCassiusAfterDrink + ))); + + sections.add(new PanelDetails("The Duke's opinion", List.of( + talkToDuke, + talkToGillieAgain, + drinkMilkSample2, + talkToGillieAfterDrink + ))); + + sections.add(new PanelDetails("The bull fight", List.of( + openBullPen, + talkToGillieAfterFight + ), combatGear, food)); + + sections.add(new PanelDetails("Finishing up", List.of( + finishQuest + ))); + + return sections; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java index 905025d5640..74cf09c84d5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java @@ -27,13 +27,10 @@ import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.ComplexRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -43,97 +40,99 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - +// TODO: fix typo in Sir Vyvin's name public class TheKnightsSword extends BasicQuestHelper { - //Items Required - ItemRequirement pickaxe, redberryPie, ironBars, bluriteOre, bluriteSword, portrait; + // Required items + ItemRequirement redberryPie; + ItemRequirement ironBars; + ItemRequirement bluriteOre; + ItemRequirement pickaxe; - //Items Recommended - ItemRequirement varrockTeleport, faladorTeleports, homeTele; - ComplexRequirement searchCupboardReq; + // Recommended items + ItemRequirement varrockTeleport; + ItemRequirement faladorTeleports; + ItemRequirement homeTele; - Requirement inDungeon, inFaladorCastle1, inFaladorCastle2, inFaladorCastle2Bedroom, sirVyinNotInRoom; + // Mid-quest item requirements + ItemRequirement bluriteSword; + ItemRequirement portrait; - QuestStep talkToSquire, talkToReldo, talkToThurgo, talkToThurgoAgain, talkToSquire2, goUpCastle1, goUpCastle2, searchCupboard, enterDungeon, - mineBlurite, givePortraitToThurgo, bringThurgoOre, finishQuest; + // Zones + Zone dungeon; + Zone faladorCastle1; + Zone faladorCastle2; + Zone faladorCastle2Bedroom; - //Zones - Zone dungeon, faladorCastle1, faladorCastle2, faladorCastle2Bedroom; + // Miscellaneous requirements + NpcRequirement sirVyvinNotInRoom; + ZoneRequirement inDungeon; + ZoneRequirement inFaladorCastle1; + ZoneRequirement inFaladorCastle2; + ZoneRequirement inFaladorCastle2Bedroom; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); + // Steps + NpcStep talkToSquire; - steps.put(0, talkToSquire); - steps.put(1, talkToReldo); - steps.put(2, talkToThurgo); - steps.put(3, talkToThurgoAgain); - steps.put(4, talkToSquire2); + NpcStep talkToReldo; - ConditionalStep getPortrait = new ConditionalStep(this, goUpCastle1); - getPortrait.addStep(portrait.alsoCheckBank(), givePortraitToThurgo); - getPortrait.addStep(inFaladorCastle2, searchCupboard); - getPortrait.addStep(inFaladorCastle1, goUpCastle2); + NpcStep talkToThurgo; - steps.put(5, getPortrait); + NpcStep talkToThurgoAgain; - ConditionalStep returnSwordToSquire = new ConditionalStep(this, enterDungeon); - returnSwordToSquire.addStep(bluriteSword.alsoCheckBank(), finishQuest); - returnSwordToSquire.addStep(bluriteOre.alsoCheckBank(), bringThurgoOre); - returnSwordToSquire.addStep(inDungeon, mineBlurite); + NpcStep talkToSquire2; - steps.put(6, returnSwordToSquire); + ObjectStep goUpCastle1; + ObjectStep goUpCastle2; + ObjectStep searchCupboard; + NpcStep givePortraitToThurgo; - return steps; + ObjectStep enterDungeon; + ObjectStep mineBlurite; + NpcStep bringThurgoOre; + NpcStep finishQuest; + + @Override + protected void setupZones() + { + dungeon = new Zone(new WorldPoint(2979, 9538, 0), new WorldPoint(3069, 9602, 0)); + faladorCastle1 = new Zone(new WorldPoint(2954, 3328, 1), new WorldPoint(2997, 3353, 1)); + faladorCastle2 = new Zone(new WorldPoint(2980, 3331, 2), new WorldPoint(2986, 3346, 2)); + faladorCastle2Bedroom = new Zone(new WorldPoint(2981, 3336, 2), new WorldPoint(2986, 3331, 2)); } @Override protected void setupRequirements() { redberryPie = new ItemRequirement("Redberry pie", ItemID.REDBERRY_PIE); + redberryPie.setTooltip("Purchasable from the grand exchange, or for ironmen: 10 cooking to cook one, or 32 cooking and a chef's hat to buy one from the Cooks' Guild."); ironBars = new ItemRequirement("Iron bar", ItemID.IRON_BAR, 2); bluriteOre = new ItemRequirement("Blurite ore", ItemID.BLURITE_ORE); - bluriteSword = new ItemRequirement("Blurite sword", ItemID.FALADIAN_SWORD); pickaxe = new ItemRequirement("Any pickaxe", ItemCollections.PICKAXES).isNotConsumed(); + varrockTeleport = new ItemRequirement("A teleport to Varrock", ItemID.POH_TABLET_VARROCKTELEPORT); - faladorTeleports = new ItemRequirement("Teleports to Falador", ItemID.POH_TABLET_FALADORTELEPORT, 4); - homeTele = new ItemRequirement("A teleport near Mudskipper Point, such as POH teleport or Fairy Ring to AIQ", - ItemID.NZONE_TELETAB_RIMMINGTON, 2); + faladorTeleports = new ItemRequirement("Teleports to Falador", ItemID.POH_TABLET_FALADORTELEPORT, 3); + homeTele = new ItemRequirement("A teleport near Mudskipper Point, such as POH teleport or Fairy Ring to AIQ", ItemID.NZONE_TELETAB_RIMMINGTON, 2); + + bluriteSword = new ItemRequirement("Blurite sword", ItemID.FALADIAN_SWORD); portrait = new ItemRequirement("Portrait", ItemID.KNIGHTS_PORTRAIT); - } - public void setupConditions() - { inDungeon = new ZoneRequirement(dungeon); inFaladorCastle1 = new ZoneRequirement(faladorCastle1); inFaladorCastle2 = new ZoneRequirement(faladorCastle2); inFaladorCastle2Bedroom = new ZoneRequirement(faladorCastle2Bedroom); - sirVyinNotInRoom = new NpcCondition(NpcID.SIR_VYVIN, faladorCastle2Bedroom); - NpcRequirement sirVyinNotInRoom = new NpcRequirement("Sir Vyin not in the bedroom.", NpcID.SIR_VYVIN, true, faladorCastle2Bedroom); - ZoneRequirement playerIsUpstairs = new ZoneRequirement("Upstairs", faladorCastle2); - searchCupboardReq = new ComplexRequirement(LogicType.AND, "Sir Vyin not in the bedroom.", playerIsUpstairs, sirVyinNotInRoom); - } - - @Override - protected void setupZones() - { - dungeon = new Zone(new WorldPoint(2979, 9538, 0), new WorldPoint(3069, 9602, 0)); - faladorCastle1 = new Zone(new WorldPoint(2954, 3328, 1), new WorldPoint(2997, 3353, 1)); - faladorCastle2 = new Zone(new WorldPoint(2980, 3331, 2), new WorldPoint(2986, 3346, 2)); - faladorCastle2Bedroom = new Zone(new WorldPoint(2981, 3336, 2), new WorldPoint(2986, 3331, 2)); + sirVyvinNotInRoom = new NpcRequirement("Sir Vyvin not in the bedroom.", NpcID.SIR_VYVIN, true, faladorCastle2Bedroom); } public void setupSteps() @@ -142,60 +141,118 @@ public void setupSteps() talkToSquire.addDialogStep("And how is life as a squire?"); talkToSquire.addDialogStep("I can make a new sword if you like..."); talkToSquire.addDialogStep("So would these dwarves make another one?"); - talkToSquire.addDialogStep("Ok, I'll give it a go."); talkToSquire.addDialogStep("Yes."); + talkToSquire.addTeleport(faladorTeleports.quantity(1)); + talkToReldo = new NpcStep(this, NpcID.RELDO_NORMAL, new WorldPoint(3211, 3494, 0), "Talk to Reldo in Varrock Castle's library."); talkToReldo.addDialogStep("What do you know about the Imcando dwarves?"); + talkToReldo.addTeleport(varrockTeleport.quantity(1)); + talkToThurgo = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Talk to Thurgo south of Port Sarim and give him a redberry pie.", redberryPie); talkToThurgo.addDialogStep("Would you like a redberry pie?"); + talkToThurgo.addTeleport(homeTele.quantity(1)); + talkToThurgoAgain = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Talk to Thurgo again."); talkToThurgoAgain.addDialogStep("Can you make a special sword for me?"); + talkToSquire2 = new NpcStep(this, NpcID.SQUIRE, new WorldPoint(2978, 3341, 0), "Talk to the Squire in Falador Castle's courtyard."); + talkToSquire2.addTeleport(faladorTeleports.quantity(1)); + goUpCastle1 = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_LADDER_UP, new WorldPoint(2994, 3341, 0), "Climb up the east ladder in Falador Castle."); + goUpCastle2 = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_STAIRS, new WorldPoint(2985, 3338, 1), "Go up the staircase west of the ladder on the 1st floor."); - searchCupboard = new ObjectStep(this, ObjectID.VYVINCUPBOARDOPEN, new WorldPoint(2985, 3336, 2), "Search the cupboard in the room south of the staircase. You'll need Sir Vyvin to be in the other room.", searchCupboardReq); - ((ObjectStep)searchCupboard).addAlternateObjects(ObjectID.VYVINCUPBOARDSHUT); // 2271 is the closed cupboard - givePortraitToThurgo = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Bring Thurgo the portrait.", ironBars, portrait); + + searchCupboard = new ObjectStep(this, ObjectID.VYVINCUPBOARDOPEN, new WorldPoint(2985, 3336, 2), "Search the cupboard in the room south of the staircase. You'll need Sir Vyvin to be in the other room.", sirVyvinNotInRoom); + searchCupboard.addAlternateObjects(ObjectID.VYVINCUPBOARDSHUT); + + givePortraitToThurgo = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Bring Thurgo the portrait.", pickaxe, ironBars, portrait); givePortraitToThurgo.addDialogStep("About that sword..."); + givePortraitToThurgo.addTeleport(homeTele.quantity(1)); + enterDungeon = new ObjectStep(this, ObjectID.FAI_TRAPDOOR, new WorldPoint(3008, 3150, 0), "Go down the ladder south of Port Sarim. Be prepared for ice giants and ice warriors to attack you.", pickaxe, ironBars); + mineBlurite = new ObjectStep(this, ObjectID.BLURITE_ROCK_1, new WorldPoint(3049, 9566, 0), "Mine a blurite ore in the eastern cavern.", pickaxe); + bringThurgoOre = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Return to Thurgo with a blurite ore and two iron bars.", bluriteOre, ironBars); bringThurgoOre.addDialogStep("Can you make that replacement sword now?"); + finishQuest = new NpcStep(this, NpcID.SQUIRE, new WorldPoint(2978, 3341, 0), "Return to the Squire with the sword to finish the quest.", bluriteSword); + finishQuest.addTeleport(faladorTeleports.quantity(1)); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToSquire); + steps.put(1, talkToReldo); + steps.put(2, talkToThurgo); + steps.put(3, talkToThurgoAgain); + steps.put(4, talkToSquire2); + + var getPortrait = new ConditionalStep(this, goUpCastle1); + getPortrait.addStep(portrait.alsoCheckBank(), givePortraitToThurgo); + getPortrait.addStep(inFaladorCastle2, searchCupboard); + getPortrait.addStep(inFaladorCastle1, goUpCastle2); + + steps.put(5, getPortrait); + + var returnSwordToSquire = new ConditionalStep(this, enterDungeon); + returnSwordToSquire.addStep(bluriteSword.alsoCheckBank(), finishQuest); + returnSwordToSquire.addStep(bluriteOre.alsoCheckBank(), bringThurgoOre); + returnSwordToSquire.addStep(inDungeon, mineBlurite); + + steps.put(6, returnSwordToSquire); + + return steps; + } + + @Override + public List getGeneralRequirements() + { + return List.of( + new SkillRequirement(Skill.MINING, 10, true) + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(redberryPie); - reqs.add(ironBars); - reqs.add(pickaxe); - return reqs; + return List.of( + redberryPie, + ironBars, + pickaxe + ); } @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - reqs.add(varrockTeleport); - reqs.add(faladorTeleports); - reqs.add(homeTele); - return reqs; + return List.of( + varrockTeleport, + faladorTeleports, + homeTele + ); } @Override public List getCombatRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Able to survive attacks from Ice Warriors (level 57) and Ice Giants (level 53)"); - return reqs; + return List.of( + "Able to survive attacks from Ice Warriors (level 57) and Ice Giants (level 53)" + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - return Collections.singletonList(new SkillRequirement(Skill.MINING, 10, true)); + return List.of( + "You can make progress towards the Falador Easy Diary task by mining an additional Blurite ore and smelting another Blurite bar, it will be required for smithing Blurite limbs." + ); } @Override @@ -207,33 +264,57 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.SMITHING, 12725)); + return List.of( + new ExperienceReward(Skill.SMITHING, 12725) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("The ability to smelt Blurite ore."), - new UnlockReward("The ability to smith Blurite bars.")); + return List.of( + new UnlockReward("The ability to smelt Blurite ore."), + new UnlockReward("The ability to smith Blurite bars.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - - allSteps.add(new PanelDetails("Starting off", Arrays.asList(talkToSquire, talkToReldo))); - allSteps.add(new PanelDetails("Finding an Imcando", Arrays.asList(talkToThurgo, talkToThurgoAgain), redberryPie)); - allSteps.add(new PanelDetails("Find the portrait", Arrays.asList(talkToSquire2, goUpCastle1, goUpCastle2, searchCupboard, givePortraitToThurgo))); - allSteps.add(new PanelDetails("Making the sword", Arrays.asList(enterDungeon, mineBlurite, bringThurgoOre), pickaxe, ironBars)); - allSteps.add(new PanelDetails("Return the sword", Collections.singletonList(finishQuest))); - return allSteps; - } + var sections = new ArrayList(); - @Override - public List getNotes() - { - return Collections.singletonList("You can make progress towards the Falador Easy Diary task by mining an additional Blurite ore and smelting another Blurite bar, it will be required for smithing Blurite limbs."); + sections.add(new PanelDetails("Starting off", List.of( + talkToSquire, + talkToReldo + ))); + + sections.add(new PanelDetails("Finding an Imcando", List.of( + talkToThurgo, + talkToThurgoAgain + ), List.of( + redberryPie + ))); + + sections.add(new PanelDetails("Find the portrait", List.of( + talkToSquire2, + goUpCastle1, + goUpCastle2, + searchCupboard, + givePortraitToThurgo + ))); + + sections.add(new PanelDetails("Making the sword", List.of(enterDungeon, + mineBlurite, + bringThurgoOre + ), List.of( + pickaxe, + ironBars + ))); + + sections.add(new PanelDetails("Return the sword", List.of( + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java index 2ea3c3713e6..fe6427589ff 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java @@ -40,82 +40,131 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcEmoteStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.emote.QuestEmote; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class TheLostTribe extends BasicQuestHelper { - //Items Required - ItemRequirement pickaxe, lightSource, brooch, book, key, silverware, treaty; - - //Items Recommended - ItemRequirement varrockTeleport, faladorTeleport, lumbridgeTeleports; - - Requirement inBasement, inLumbridgeF0, inLumbridgeF1, inLumbridgeF2, inTunnels, inMines, - foundRobes, inHamBase, foundSilverwareOrToldOnSigmund, bobKnows, hansKnows; - - DetailedQuestStep goDownFromF2, talkToSigmund, talkToDuke, goDownFromF1, talkToHans, goUpToF1, - goDownIntoBasement, usePickaxeOnRubble, climbThroughHole, grabBrooch, climbOutThroughHole, goUpFromBasement, - showBroochToDuke, searchBookcase, readBook, talkToGenerals, walkToMistag, emoteAtMistag, pickpocketSigmund, - unlockChest, enterHamLair, searchHamCrates, talkToKazgar, talkToMistagForEnd, talkToBob, talkToAllAboutCellar; - - ConditionalStep goToF1Steps, goDownToBasement, goTalkToSigmundToStart, findGoblinWitnessSteps, goTalkToDukeAfterHans, - goMineRubble, enterTunnels, goShowBroochToDuke, goTalkToDukeAfterEmote, goTravelToMistag, goGetKey, goOpenRobeChest, - goIntoHamLair, goToDukeWithSilverware, travelToMakePeace; - - //Zones - Zone basement, lumbridgeF0, lumbridgeF1, lumbridgeF2, tunnels, mines, hamBase; + // Required items + ItemRequirement pickaxe; + ItemRequirement lightSource; + + // Recommended item + ItemRequirement varrockTeleport; + ItemRequirement faladorTeleport; + ItemRequirement lumbridgeTeleports; + + // Mid-quest item requirements + ItemRequirement brooch; + ItemRequirement book; + ItemRequirement key; + ItemRequirement silverware; + ItemRequirement treaty; + + // Zones + Zone basement; + Zone lumbridgeF0; + Zone lumbridgeF1; + Zone lumbridgeF2; + Zone tunnels; + Zone mines; + Zone hamBase; + + // Miscellaneous requirements + ZoneRequirement inBasement; + ZoneRequirement inLumbridgeF0; + ZoneRequirement inLumbridgeF1; + ZoneRequirement inLumbridgeF2; + ZoneRequirement inTunnels; + ZoneRequirement inMines; + VarbitRequirement foundRobes; + ZoneRequirement inHamBase; + VarbitRequirement foundSilverwareOrToldOnSigmund; + VarbitRequirement bobKnows; + VarbitRequirement hansKnows; + + // Steps + ObjectStep goDownIntoBasement; + ObjectStep goDownFromF1; + ObjectStep goUpToF1; + ObjectStep goUpFromBasement; + ObjectStep goDownFromF2; + ObjectStep climbOutThroughHole; + ConditionalStep goToF1Steps; + + NpcStep talkToSigmund; + ConditionalStep goTalkToSigmundToStart; + + NpcStep talkToHans; + NpcStep talkToBob; + NpcStep talkToAllAboutCellar; + ConditionalStep findGoblinWitnessSteps; + + NpcStep talkToDuke; + ConditionalStep goTalkToDukeAfterHans; + + ConditionalStep goDownToBasement; + ObjectStep usePickaxeOnRubble; + ConditionalStep goMineRubble; + + ObjectStep climbThroughHole; + ConditionalStep enterTunnels; + DetailedQuestStep grabBrooch; + NpcStep showBroochToDuke; + ConditionalStep goShowBroochToDuke; + + ObjectStep searchBookcase; + DetailedQuestStep readBook; + + NpcStep talkToGenerals; + + NpcEmoteStep walkToMistag; + NpcEmoteStep emoteAtMistag; + ConditionalStep goTravelToMistag; + + ConditionalStep goTalkToDukeAfterEmote; + + NpcStep pickpocketSigmund; + ConditionalStep goGetKey; + ObjectStep unlockChest; + ConditionalStep goOpenRobeChest; + ObjectStep enterHamLair; + ObjectStep searchHamCrates; + ConditionalStep goIntoHamLair; + ConditionalStep goToDukeWithSilverware; + + NpcStep talkToKazgar; + NpcStep talkToMistagForEnd; + ConditionalStep travelToMakePeace; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - setupConditionalSteps(); - Map steps = new HashMap<>(); - - steps.put(0, goTalkToSigmundToStart); - steps.put(1, findGoblinWitnessSteps); - steps.put(2, goTalkToDukeAfterHans); - steps.put(3, goMineRubble); - - ConditionalStep goGrabBrooch = new ConditionalStep(this, enterTunnels); - goGrabBrooch.addStep(brooch, goShowBroochToDuke); - goGrabBrooch.addStep(inTunnels, grabBrooch); - steps.put(4, goGrabBrooch); - - ConditionalStep getBook = new ConditionalStep(this, searchBookcase); - getBook.addStep(book, readBook); - steps.put(5, getBook); - - steps.put(6, talkToGenerals); - - ConditionalStep makeContactSteps = new ConditionalStep(this, goTravelToMistag); - makeContactSteps.addStep(inMines, emoteAtMistag); - makeContactSteps.addStep(inTunnels, walkToMistag); - - steps.put(7, makeContactSteps); - steps.put(8, goTalkToDukeAfterEmote); - - ConditionalStep revealSigmund = new ConditionalStep(this, goGetKey); - revealSigmund.addStep(silverware.alsoCheckBank(), goToDukeWithSilverware); - revealSigmund.addStep(foundRobes, goIntoHamLair); - revealSigmund.addStep(key, goOpenRobeChest); - steps.put(9, revealSigmund); - - steps.put(10, travelToMakePeace); - - return steps; + basement = new Zone(new WorldPoint(3208, 9614, 0), new WorldPoint(3219, 9625, 0)); + lumbridgeF0 = new Zone(new WorldPoint(3136, 3136, 0), new WorldPoint(3328, 3328, 0)); + lumbridgeF1 = new Zone(new WorldPoint(3203, 3206, 1), new WorldPoint(3217, 3231, 1)); + lumbridgeF2 = new Zone(new WorldPoint(3203, 3206, 2), new WorldPoint(3217, 3231, 2)); + tunnels = new Zone(new WorldPoint(3221, 9602, 0), new WorldPoint(3308, 9661, 0)); + mines = new Zone(new WorldPoint(3309, 9600, 0), new WorldPoint(3327, 9655, 0)); + hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); } @Override @@ -136,22 +185,7 @@ protected void setupRequirements() varrockTeleport = new ItemRequirement("Varrock teleport", ItemID.POH_TABLET_VARROCKTELEPORT); lumbridgeTeleports = new ItemRequirement("Lumbridge teleports", ItemID.POH_TABLET_LUMBRIDGETELEPORT, 3); faladorTeleport = new ItemRequirement("Falador teleport", ItemID.POH_TABLET_FALADORTELEPORT); - } - @Override - protected void setupZones() - { - basement = new Zone(new WorldPoint(3208, 9614, 0), new WorldPoint(3219, 9625, 0)); - lumbridgeF0 = new Zone(new WorldPoint(3136, 3136, 0), new WorldPoint(3328, 3328, 0)); - lumbridgeF1 = new Zone(new WorldPoint(3203, 3206, 1), new WorldPoint(3217, 3231, 1)); - lumbridgeF2 = new Zone(new WorldPoint(3203, 3206, 2), new WorldPoint(3217, 3231, 2)); - tunnels = new Zone(new WorldPoint(3221, 9602, 0), new WorldPoint(3308, 9661, 0)); - mines = new Zone(new WorldPoint(3309, 9600, 0), new WorldPoint(3327, 9655, 0)); - hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); - } - - public void setupConditions() - { inBasement = new ZoneRequirement(basement); inLumbridgeF0 = new ZoneRequirement(lumbridgeF0); inLumbridgeF1 = new ZoneRequirement(lumbridgeF1); @@ -176,46 +210,82 @@ public void setupSteps() goDownFromF1 = new ObjectStep(this, ObjectID.SPIRALSTAIRSMIDDLE, new WorldPoint(3205, 3208, 1), "Go down the staircase."); goDownFromF1.addDialogStep("Climb down the stairs."); goUpToF1 = new ObjectStep(this, ObjectID.SPIRALSTAIRSBOTTOM_3, new WorldPoint(3205, 3208, 0), "Go up to the first floor of Lumbridge Castle."); + goUpToF1.addDialogStep("Can you show me the way out of the mines?"); goUpFromBasement = new ObjectStep(this, ObjectID.LADDER_FROM_CELLAR, new WorldPoint(3209, 9616, 0), "Go up to the surface."); goDownFromF2 = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP_3, new WorldPoint(3205, 3208, 2), "Go downstairs."); + climbOutThroughHole = new ObjectStep(this, ObjectID.LOST_TRIBE_CAVEWALL_HOLE_WALLDECOR, new WorldPoint(3221, 9618, 0), ""); + climbOutThroughHole.setForceClickboxHighlight(true); + + goToF1Steps = new ConditionalStep(this, goUpToF1); + goToF1Steps.addStep(inLumbridgeF2, goDownFromF2); + goToF1Steps.addStep(inBasement, goUpFromBasement); + goToF1Steps.addStep(inTunnels, climbOutThroughHole); + talkToSigmund = new NpcStep(this, NpcID.LOST_TRIBE_SIGMUND_THERE, new WorldPoint(3210, 3222, 1), ""); talkToSigmund.addDialogSteps("Do you have any quests for me?", "Yes."); + goTalkToSigmundToStart = new ConditionalStep(this, goToF1Steps, "Talk to Sigmund in Lumbridge Castle."); + goTalkToSigmundToStart.addStep(inLumbridgeF1, talkToSigmund); + // This isn't just talk to Hans, it's a random one of the NPCs to chat to talkToHans = new NpcStep(this, NpcID.HANS, new WorldPoint(3222, 3218, 0), "Talk to Hans who is roaming around the castle."); talkToHans.addDialogStep("Do you know what happened in the cellar?"); - talkToBob = new NpcStep(this, NpcID.TWOCATS_BOB_CUTSCENE, new WorldPoint(3231, 3203, 0), "Talk to Bob in the south of Lumbridge."); + talkToBob = new NpcStep(this, NpcID.BOB, new WorldPoint(3231, 3203, 0), "Talk to Bob in the south of Lumbridge."); talkToBob.addDialogStep("Do you know what happened in the castle cellar?"); - talkToAllAboutCellar = new NpcStep(this, NpcID.COOK, "Talk to the Cook, Hans, Father Aereck, and Bob in Lumbridge until one tells you about seeing a goblin."); - ((NpcStep)(talkToAllAboutCellar)).addAlternateNpcs(NpcID.FATHER_AERECK); + talkToAllAboutCellar = new NpcStep(this, NpcID.COOK, ""); + talkToAllAboutCellar.addAlternateNpcs(NpcID.FATHER_AERECK); talkToAllAboutCellar.addDialogSteps("Do you know what happened in the castle cellar?"); talkToAllAboutCellar.addSubSteps(talkToHans, talkToBob); + findGoblinWitnessSteps = new ConditionalStep(this, talkToAllAboutCellar, "Talk to the Cook, Hans, Father Aereck, and Bob in Lumbridge until one tells you about seeing a goblin."); + findGoblinWitnessSteps.addStep(inLumbridgeF2, goDownFromF2); + findGoblinWitnessSteps.addStep(inLumbridgeF1, goDownFromF1); + findGoblinWitnessSteps.addStep(inBasement, goUpFromBasement); + findGoblinWitnessSteps.addStep(hansKnows, talkToHans); + findGoblinWitnessSteps.addStep(bobKnows, talkToBob); + talkToDuke = new NpcStep(this, NpcID.DUKE_OF_LUMBRIDGE, new WorldPoint(3210, 3222, 1), ""); + + goTalkToDukeAfterHans = new ConditionalStep(this, goToF1Steps, "Talk to Duke Horacio in Lumbridge Castle."); + goTalkToDukeAfterHans.addDialogSteps("Hans says he saw something in the cellar", "Bob says he saw something in the cellar", "Father Aereck says he saw something in the cellar", "The cook says he saw something in the cellar"); + goTalkToDukeAfterHans.addStep(inLumbridgeF1, talkToDuke); + + goDownToBasement = new ConditionalStep(this, goDownIntoBasement); + goDownToBasement.addStep(inLumbridgeF2, goDownFromF2); + goDownToBasement.addStep(inLumbridgeF1, goDownFromF1); + // Name of person who said they saw something changes usePickaxeOnRubble = new ObjectStep(this, ObjectID.LOST_TRIBE_CELLAR_WALL, new WorldPoint(3219, 9618, 0), ""); usePickaxeOnRubble.addIcon(ItemID.BRONZE_PICKAXE); + goMineRubble = new ConditionalStep(this, goDownToBasement, "Use a pickaxe on the rubble in the Lumbridge Castle basement.", pickaxe.highlighted(), lightSource); + goMineRubble.addStep(inBasement, usePickaxeOnRubble); + climbThroughHole = new ObjectStep(this, ObjectID.LOST_TRIBE_CELLAR_WALL, new WorldPoint(3219, 9618, 0), ""); + climbThroughHole.setForceClickboxHighlight(true); - grabBrooch = new DetailedQuestStep(this, new WorldPoint(3230, 9610, 0), "Pick up the brooch on the floor.", brooch); + enterTunnels = new ConditionalStep(this, goDownToBasement, "Enter the hole in Lumbridge Castle's basement.", lightSource); + enterTunnels.addStep(inBasement, climbThroughHole); - climbOutThroughHole = new ObjectStep(this, ObjectID.LOST_TRIBE_CAVEWALL_HOLE_WALLDECOR, new WorldPoint(3221, 9618, 0), ""); + grabBrooch = new DetailedQuestStep(this, new WorldPoint(3230, 9610, 0), "Pick up the brooch on the floor.", brooch); showBroochToDuke = new NpcStep(this, NpcID.DUKE_OF_LUMBRIDGE, new WorldPoint(3210, 3222, 1), ""); showBroochToDuke.addDialogStep("I dug through the rubble..."); + goShowBroochToDuke = new ConditionalStep(this, goToF1Steps, "Show the brooch to Duke Horacio in Lumbridge Castle.", brooch); + goShowBroochToDuke.addStep(inLumbridgeF1, showBroochToDuke); + searchBookcase = new ObjectStep(this, ObjectID.LOST_TRIBE_BOOKCASE, new WorldPoint(3207, 3496, 0), "Search the north west bookcase in the Varrock Castle Library."); searchBookcase.addTeleport(varrockTeleport); + readBook = new DetailedQuestStep(this, "Read the entire goblin symbol book.", book); - readBook.addWidgetHighlight(183, 16); + readBook.addWidgetHighlight(InterfaceID.LostTribeSymbolBook.LOST_TRIBE_RIGHT_ARROW); talkToGenerals = new NpcStep(this, NpcID.GENERAL_WARTFACE_GREEN, new WorldPoint(2957, 3512, 0), "Talk to the Goblin Generals in the Goblin Village."); talkToGenerals.addTeleport(faladorTeleport); - talkToGenerals.addDialogSteps("Have you ever heard of the Dorgeshuun?", "It doesn't really matter", - "Well either way they refused to fight", "Well I found a brooch underground...", "Well why not show me both greetings?"); + talkToGenerals.addDialogSteps("Have you ever heard of the Dorgeshuun?", "It doesn't really matter", "Well either way they refused to fight", "Well I found a brooch underground...", "Well why not show me both greetings?"); List travelLine = Arrays.asList( new WorldPoint(3222, 9618, 0), @@ -261,52 +331,6 @@ public void setupSteps() emoteAtMistag = new NpcEmoteStep(this, NpcID.LOST_TRIBE_MISTAG_1OP, QuestEmote.GOBLIN_BOW, new WorldPoint(3319, 9615, 0), "Perform the Goblin Bow emote next to Mistag and talk to him.", lightSource); - pickpocketSigmund = new NpcStep(this, NpcID.LOST_TRIBE_SIGMUND_THERE, new WorldPoint(3210, 3222, 1), ""); - unlockChest = new ObjectStep(this, ObjectID.LOST_TRIBE_CHEST, new WorldPoint(3209, 3217, 1), ""); - - enterHamLair = new ObjectStep(this, ObjectID.HAM_MULTI_TRAPDOOR, new WorldPoint(3166, 3252, 0), ""); - - searchHamCrates = new ObjectStep(this, ObjectID.LOST_TRIBE_CRATE, new WorldPoint(3152, 9645, 0), ""); - - talkToKazgar = new NpcStep(this, NpcID.LOST_TRIBE_GUIDE_2OPS, new WorldPoint(3230, 9610, 0), "Travel with Kazgar to shortcut to Mistag."); - talkToMistagForEnd = new NpcStep(this, NpcID.LOST_TRIBE_MISTAG_2OPS, new WorldPoint(3319, 9615, 0), ""); - } - - private void setupConditionalSteps() - { - goToF1Steps = new ConditionalStep(this, goUpToF1); - goToF1Steps.addStep(inLumbridgeF2, goDownFromF2); - goToF1Steps.addStep(inBasement, goUpFromBasement); - goToF1Steps.addStep(inTunnels, climbOutThroughHole); - - goDownToBasement = new ConditionalStep(this, goDownIntoBasement); - goDownToBasement.addStep(inLumbridgeF2, goDownFromF2); - goDownToBasement.addStep(inLumbridgeF1, goDownFromF1); - - goTalkToSigmundToStart = new ConditionalStep(this, goToF1Steps, "Talk to Sigmund in Lumbridge Castle."); - goTalkToSigmundToStart.addStep(inLumbridgeF1, talkToSigmund); - - findGoblinWitnessSteps = new ConditionalStep(this, talkToAllAboutCellar); - findGoblinWitnessSteps.addStep(inLumbridgeF2, goDownFromF2); - findGoblinWitnessSteps.addStep(inLumbridgeF1, goDownFromF1); - findGoblinWitnessSteps.addStep(inBasement, goUpFromBasement); - findGoblinWitnessSteps.addStep(hansKnows, talkToHans); - findGoblinWitnessSteps.addStep(bobKnows, talkToBob); - - goTalkToDukeAfterHans = new ConditionalStep(this, goToF1Steps, "Talk to Duke Horacio in Lumbridge Castle."); - goTalkToDukeAfterHans.addDialogSteps("Hans says he saw something in the cellar", "Bob says he saw something in the cellar", - "Father Aereck says he saw something in the cellar", "The cook says he saw something in the cellar"); - goTalkToDukeAfterHans.addStep(inLumbridgeF1, talkToDuke); - - goMineRubble = new ConditionalStep(this, goDownToBasement, "Go use a pickaxe on the rubble in the Lumbridge Castle basement.", pickaxe.highlighted(), lightSource); - goMineRubble.addStep(inBasement, usePickaxeOnRubble); - - enterTunnels = new ConditionalStep(this, goDownToBasement, "Enter the hole in Lumbridge Castle's basement.", lightSource); - enterTunnels.addStep(inBasement, climbThroughHole); - - goShowBroochToDuke = new ConditionalStep(this, goToF1Steps, "Show the brooch to Duke Horacio in Lumbridge Castle.", brooch); - goShowBroochToDuke.addStep(inLumbridgeF1, showBroochToDuke); - goTravelToMistag = new ConditionalStep(this, goDownToBasement, "Travel through the tunnels under Lumbridge until you reach Mistag.", lightSource); goTravelToMistag.addStep(inBasement, climbThroughHole); goTravelToMistag.addSubSteps(walkToMistag); @@ -315,12 +339,20 @@ private void setupConditionalSteps() goTalkToDukeAfterEmote.addDialogSteps("I've made contact with the cave goblins..."); goTalkToDukeAfterEmote.addStep(inLumbridgeF1, talkToDuke); + pickpocketSigmund = new NpcStep(this, NpcID.LOST_TRIBE_SIGMUND_THERE, new WorldPoint(3210, 3222, 1), ""); + goGetKey = new ConditionalStep(this, goToF1Steps, "Pickpocket Sigmund for a key."); goGetKey.addStep(inLumbridgeF1, pickpocketSigmund); + unlockChest = new ObjectStep(this, ObjectID.LOST_TRIBE_CHEST, new WorldPoint(3209, 3217, 1), ""); + goOpenRobeChest = new ConditionalStep(this, goToF1Steps, "Open the chest in the room next to the Duke's room.", key); goOpenRobeChest.addStep(inLumbridgeF1, unlockChest); + enterHamLair = new ObjectStep(this, ObjectID.HAM_MULTI_TRAPDOOR, new WorldPoint(3166, 3252, 0), ""); + + searchHamCrates = new ObjectStep(this, ObjectID.LOST_TRIBE_CRATE, new WorldPoint(3152, 9645, 0), ""); + goIntoHamLair = new ConditionalStep(this, enterHamLair, "Enter the H.A.M lair west of Lumbridge and search a crate in its entrance for the silverware."); goIntoHamLair.addStep(inHamBase, searchHamCrates); goIntoHamLair.addStep(inLumbridgeF2, goDownFromF2); @@ -331,34 +363,91 @@ private void setupConditionalSteps() goToDukeWithSilverware.addDialogStep("I found the missing silverware in the HAM cave!"); goToDukeWithSilverware.addStep(inLumbridgeF1, talkToDuke); + talkToKazgar = new NpcStep(this, NpcID.LOST_TRIBE_GUIDE_2OPS, new WorldPoint(3230, 9610, 0), "Travel with Kazgar to shortcut to Mistag."); + talkToKazgar.addDialogStep("Can you show me the way to the mines?"); + talkToMistagForEnd = new NpcStep(this, NpcID.LOST_TRIBE_MISTAG_2OPS, new WorldPoint(3319, 9615, 0), ""); + travelToMakePeace = new ConditionalStep(this, goDownToBasement, "Travel through the tunnels until you reach Mistag, and give him the treaty.", lightSource, treaty); + travelToMakePeace.addDialogStep("What was I doing again?"); travelToMakePeace.addStep(inMines, talkToMistagForEnd); travelToMakePeace.addStep(inTunnels, talkToKazgar); travelToMakePeace.addStep(inBasement, climbThroughHole); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, goTalkToSigmundToStart); + + steps.put(1, findGoblinWitnessSteps); + + steps.put(2, goTalkToDukeAfterHans); + + steps.put(3, goMineRubble); + + var goGrabBrooch = new ConditionalStep(this, enterTunnels); + goGrabBrooch.addStep(brooch, goShowBroochToDuke); + goGrabBrooch.addStep(inTunnels, grabBrooch); + steps.put(4, goGrabBrooch); + + var getBook = new ConditionalStep(this, searchBookcase); + getBook.addStep(book, readBook); + steps.put(5, getBook); + + steps.put(6, talkToGenerals); + + var makeContactSteps = new ConditionalStep(this, goTravelToMistag); + makeContactSteps.addStep(inMines, emoteAtMistag); + makeContactSteps.addStep(inTunnels, walkToMistag); + steps.put(7, makeContactSteps); + + steps.put(8, goTalkToDukeAfterEmote); + + var revealSigmund = new ConditionalStep(this, goGetKey); + revealSigmund.addStep(silverware.alsoCheckBank(), goToDukeWithSilverware); + revealSigmund.addStep(foundRobes, goIntoHamLair); + revealSigmund.addStep(key, goOpenRobeChest); + steps.put(9, revealSigmund); + + steps.put(10, travelToMakePeace); + + return steps; + } + @Override public List getItemRequirements() { - return Arrays.asList(pickaxe, lightSource); + return List.of( + pickaxe, + lightSource + ); } @Override public List getItemRecommended() { - return Arrays.asList(lumbridgeTeleports, varrockTeleport, faladorTeleport); + return List.of( + lumbridgeTeleports, + varrockTeleport, + faladorTeleport + ); } @Override public List getGeneralRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.GOBLIN_DIPLOMACY, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.AGILITY, 13, true)); - req.add(new SkillRequirement(Skill.THIEVING, 13, true)); - req.add(new SkillRequirement(Skill.MINING, 17, true)); - return req; + return List.of( + new QuestRequirement(QuestHelperQuest.GOBLIN_DIPLOMACY, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED), + new SkillRequirement(Skill.AGILITY, 13, true), + new SkillRequirement(Skill.THIEVING, 13, true), + new SkillRequirement(Skill.MINING, 17, true) + ); } @Override @@ -370,34 +459,74 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.MINING, 3000)); + return List.of( + new ExperienceReward(Skill.MINING, 3000) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Ring of Life", ItemID.RING_OF_LIFE, 1)); + return List.of( + new ItemReward("Ring of Life", ItemID.RING_OF_LIFE, 1) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to the Dorgesh-Kann mine."), - new UnlockReward("Access to Nardok's Bone Weapon Store"), - new UnlockReward("2 new goblin emotes.")); + return List.of( + new UnlockReward("Access to the Dorgesh-Kaan mine."), + new UnlockReward("Access to Nardok's Bone Weapon Store"), + new UnlockReward("2 new goblin emotes.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(goTalkToSigmundToStart, talkToAllAboutCellar, goTalkToDukeAfterHans))); - allSteps.add(new PanelDetails("Investigating", Arrays.asList(goMineRubble, enterTunnels, grabBrooch, goShowBroochToDuke), pickaxe, lightSource)); - allSteps.add(new PanelDetails("Learning about goblins", Arrays.asList(searchBookcase, readBook, talkToGenerals))); - allSteps.add(new PanelDetails("Making contact", Arrays.asList(goTravelToMistag, emoteAtMistag, goTalkToDukeAfterEmote), lightSource)); - allSteps.add(new PanelDetails("Resolving tensions", Arrays.asList(goGetKey, goOpenRobeChest, goIntoHamLair, goToDukeWithSilverware, travelToMakePeace), lightSource)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + goTalkToSigmundToStart, + findGoblinWitnessSteps, + goTalkToDukeAfterHans + ))); + + sections.add(new PanelDetails("Investigating", List.of( + goMineRubble, + enterTunnels, + grabBrooch, + goShowBroochToDuke + ), List.of( + pickaxe, + lightSource + ))); + + sections.add(new PanelDetails("Learning about goblins", List.of( + searchBookcase, + readBook, + talkToGenerals + ))); + + sections.add(new PanelDetails("Making contact", List.of( + goTravelToMistag, + emoteAtMistag, + goTalkToDukeAfterEmote + ), List.of( + lightSource + ))); + + sections.add(new PanelDetails("Resolving tensions", List.of( + goGetKey, + goOpenRobeChest, + goIntoHamLair, + goToDukeWithSilverware, + travelToMakePeace + ), List.of( + lightSource + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java index 5ba87899d0d..f2778475827 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java @@ -53,6 +53,7 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; @@ -232,7 +233,6 @@ private void setupConditions() learnedAboutChapter1 = new VarbitRequirement(VarbitID.POG_BOLRIE_DIARY_1, 1); learnedAboutChapter2 = new VarbitRequirement(VarbitID.POG_BOLRIE_DIARY_2, 1); - // learnedAboutChapter3 = new VarbitRequirement(VarbitID.POG_BOLRIE_DIARY_3, 1); inSewer1 = new ZoneRequirement(sewer1); inSewer2 = new ZoneRequirement(sewer2); @@ -242,7 +242,7 @@ private void setupConditions() inSewer6 = new Conditions(LogicType.OR, new ZoneRequirement(sewer6Section1), new ZoneRequirement(sewer6Section2)); inBossRoom = new ZoneRequirement(bossRoom); - lecternWidgetActive = new WidgetTextRequirement(854, 5, "Chapter 1. Bad advice"); + lecternWidgetActive = new WidgetTextRequirement(InterfaceID.PogBolriesDiary.CHAPTER1, "Chapter 1. Bad advice"); protectMissiles = new PrayerRequirement("Protect from Missiles to reduce damage taken by the Terrorbirds", Prayer.PROTECT_FROM_MISSILES); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java index 3d2db996f8c..8094f802a28 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java @@ -35,6 +35,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.InventoryID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; @@ -374,11 +375,11 @@ protected void setupSteps() getMoreDiscs = new ObjectStep(getQuestHelper(), ObjectID.POG_CHEST_CLOSED, regionPoint(34, 31), "Get more discs from the chests outside. You can drop discs before you get more. You can also use the exchanger next to Yewnock's machine.", true); useExchanger = new ObjectStep(getQuestHelper(), ObjectID.POG_GNOME_MACHINE_03, regionPoint(22, 33), "A solution has been calculated, exit the machine interface & click Yewnock's exchanger."); - useExchanger.addWidgetHighlight(848, 27); // TODO: Verify that this is the "exit" button in the Machine widget + useExchanger.addWidgetHighlight(InterfaceID.PogCoinMachine.CLOSE); clickMachine = new ObjectStep(getQuestHelper(), ObjectID.POG_GNOME_MACHINE_02, regionPoint(22, 32), "A solution has been found, click Yewnock's machine and insert the discs as prompted."); - clickMachine.addWidgetHighlight(849, 41); + clickMachine.addWidgetHighlight(InterfaceID.PogCoinExchanger.CLOSE); clickMachineOnce = new ObjectStep(getQuestHelper(), ObjectID.POG_GNOME_MACHINE_02, regionPoint(22, 32), "Operate Yewnock's machine to calculate a solution."); @@ -391,14 +392,14 @@ protected void setupSteps() 848, 26); exchangerInsertDisc = new DiscInsertionStep(getQuestHelper(), "Insert the highlighted disc into the highlighted slot."); - exchangerExchange = new WidgetStep(getQuestHelper(), "", 849, 40); + exchangerExchange = new WidgetStep(getQuestHelper(), "", InterfaceID.PogCoinExchanger.EXCHANGE); exchangerConfirm = new DetailedQuestStep(getQuestHelper(), "Click the confirm button."); - exchangerConfirm.addWidgetHighlight(849, 36); + exchangerConfirm.addWidgetHighlight(InterfaceID.PogCoinExchanger.SUBMIT); exchangerReset = new WidgetStep(getQuestHelper(), "Found unexpected disc(s) in the exchange input, reset & follow the instructions."); - exchangerReset.addWidgetHighlight(849, 34); + exchangerReset.addWidgetHighlight(InterfaceID.PogCoinExchanger.RESET); - machineOpen = new WidgetPresenceRequirement(848, 0); - exchangerOpen = new WidgetPresenceRequirement(849, 0); + machineOpen = new WidgetPresenceRequirement(InterfaceID.PogCoinMachine.UNIVERSE); + exchangerOpen = new WidgetPresenceRequirement(InterfaceID.PogCoinExchanger.UNIVERSE); } @Override @@ -453,9 +454,9 @@ public void shutDown() solution.reset(); } - private int getWidgetItemId(int groupId, int childId) + private int getWidgetItemId(int widgetId) { - var widget = client.getWidget(groupId, childId); + var widget = client.getWidget(widgetId); if (widget == null) { return -1; @@ -467,32 +468,32 @@ private int getWidgetItemId(int groupId, int childId) /** * This function will add a widget highlight to the slot where it finds a good exchange, if any * - * @return a pair of widget group + child IDs if there is an exchange we're looking for in one of the slots + * @return a widget ID if there is an exchange we're looking for in one of the slots */ - private Optional> findGoodExchange() + private Optional findGoodExchange() { - var exchangeResultTL = getWidgetItemId(849, 21); - var exchangeResultTR = getWidgetItemId(849, 24); - var exchangeResultBL = getWidgetItemId(849, 27); - var exchangeResultBR = getWidgetItemId(849, 30); + var exchangeResultTL = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_1_MODEL); + var exchangeResultTR = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_2_MODEL); + var exchangeResultBL = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_3_MODEL); + var exchangeResultBR = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_4_MODEL); for (var puzzleNeed : solution.puzzleNeeds) { if (puzzleNeed.getAllIds().contains(exchangeResultTL)) { - return Optional.of(Pair.of(849, 21)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_1_MODEL); } if (puzzleNeed.getAllIds().contains(exchangeResultTR)) { - return Optional.of(Pair.of(849, 24)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_2_MODEL); } if (puzzleNeed.getAllIds().contains(exchangeResultBL)) { - return Optional.of(Pair.of(849, 27)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_3_MODEL); } if (puzzleNeed.getAllIds().contains(exchangeResultBR)) { - return Optional.of(Pair.of(849, 30)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_4_MODEL); } } @@ -689,9 +690,9 @@ protected void updateSteps() exchangerConfirm.clearWidgetHighlights(); // Highlight the confirm button - exchangerConfirm.addWidgetHighlight(849, 36); + exchangerConfirm.addWidgetHighlight(InterfaceID.PogCoinExchanger.SUBMIT); // Highlight the widget with the good exchange - exchangerConfirm.addWidgetHighlight(goodExchangeWidget.getLeft(), goodExchangeWidget.getRight()); + exchangerConfirm.addWidgetHighlight(goodExchangeWidget); startUpStep(exchangerConfirm); return; } @@ -699,9 +700,9 @@ protected void updateSteps() exchangerInsertDisc.setRequirements(solution.toExchange); // Exchanger widget is open - var exchangeInput1 = getWidgetItemId(849, 8); - var exchangeInput2 = getWidgetItemId(849, 13); - var exchangeInput3 = getWidgetItemId(849, 18); + var exchangeInput1 = getWidgetItemId(InterfaceID.PogCoinExchanger.INPUT_1_MODEL); + var exchangeInput2 = getWidgetItemId(InterfaceID.PogCoinExchanger.INPUT_2_MODEL); + var exchangeInput3 = getWidgetItemId(InterfaceID.PogCoinExchanger.INPUT_3_MODEL); List exchangeInputs = Stream.of(exchangeInput1, exchangeInput2, exchangeInput3).filter(itemId -> itemId > 0).collect(Collectors.toUnmodifiableList()); // TODO: Validate that the correct disc is in one of the 3 exchange slots (need their widget IDs or varbits) @@ -713,7 +714,7 @@ protected void updateSteps() // Highlight the first exchanger input exchangerInsertDisc.clearWidgetHighlights(); - exchangerInsertDisc.addWidgetHighlight(849, 8); + exchangerInsertDisc.addWidgetHighlight(InterfaceID.PogCoinExchanger.INPUT_1_MODEL); startUpStep(exchangerInsertDisc); return; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java index 1c9e04dbf0b..97cbbe87f1c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java @@ -59,6 +59,7 @@ public void setup(ThePathOfGlouphrie quest) sewer1Ladder.addRecommended(quest.earmuffsOrSlayerHelmet); sewer2Ladder = new ObjectStep(quest, ObjectID.POG_SEWER_LADDER_TOP, new WorldPoint(1529, 4236, 1), "Climb down the ladder to the east."); + sewer2Ladder.setForceClickboxHighlight(true); sewer2Ladder.addRecommended(quest.protectMissiles); sewer2Ladder.addRecommended(quest.earmuffsOrSlayerHelmetEquipped); sewer3Ladder = new ObjectStep(quest, ObjectID.POG_SEWER_PIPE_SIDE_LADDER, new WorldPoint(1529, 4253, 0), @@ -67,6 +68,7 @@ public void setup(ThePathOfGlouphrie quest) sewer3Ladder.addRecommended(quest.earmuffsOrSlayerHelmetEquipped); sewer4Ladder = new ObjectStep(quest, ObjectID.POG_SEWER_LADDER_TOP, new WorldPoint(1486, 4282, 1), "Climb down the ladder to the north-west. Re-activate your run if you step in any puddles."); + sewer4Ladder.setForceClickboxHighlight(true); sewer4Ladder.addRecommended(quest.protectMissiles); sewer4Ladder.addRecommended(quest.earmuffsOrSlayerHelmetEquipped); sewer4Ladder.setLinePoints(List.of( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theredreef/TheRedReef.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theredreef/TheRedReef.java new file mode 100644 index 00000000000..3dac4184e51 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theredreef/TheRedReef.java @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2026, pajlada + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.helpers.quests.theredreef; + +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; +import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; +import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; +import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NoFollowerRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.CombatLevelRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.PolyZone; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; +import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.client.plugins.microbot.questhelper.steps.WorldEntityStep; +import net.runelite.api.QuestState; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; + +public class TheRedReef extends BasicQuestHelper +{ + // Required items + ItemRequirement rangedCombatGearOrShipWithCannons; + ItemRequirement combatGear; + ItemRequirement combatGearBethel; + ItemRequirement combatGearLobster; + + // Recommended items + ItemRequirement food; + ItemRequirement prayerPotions; + ItemRequirement repairKits; + + // Mid-quest item requirements + ItemRequirement divingHelmet; + ItemRequirement divingHelmetEquipped; + ItemRequirement divingApparatus; + ItemRequirement divingApparatusEquipped; + + // Zones + Zone redRock; + Zone lastLightF0; + + // Miscellaneous requirements + ZoneRequirement onRedRock; + ZoneRequirement onLastLightF0; + ZoneRequirement onLastLightF1; + ZoneRequirement onLastLightF2; + NpcRequirement onZenith; + VarbitRequirement diving; + NpcRequirement giantLobsterAround; + VarbitRequirement onBoat; + FreeInventorySlotRequirement freeInv2; + NoFollowerRequirement noFollower; + + // Steps + // 0 + 2 + NpcStep talkToRaleyToStartQuest; + + // 4 + NpcStep talkToFinn; + + // 6 + NpcStep talkToElderKatt; + + // 8 + NpcStep talkToFloopa; + + // 10 + DetailedQuestStep sailToRedRock; + + // 12 + NpcStep talkToRedRockReceptionist; + + // 14 + ConditionalStep cInspectCases; + + // 16 + NpcStep talkToTheodorePaxton; + + // 18 + NpcStep sinkBlackEyeBethelBoats; + + // 20 + ObjectStep disembarkAtLastLight; + + // 22 + NpcStep killPiratesAtLastLight; + + // 24 + ObjectStep climbUpToF1; + ObjectStep climbUpToF2; + NpcStep killBlackEyeBethel; + + // 26 + ObjectStep climbDownToF1; + ObjectStep climbDownToF0; + ObjectStep sailToRedRock2; + ObjectStep boardYourShip; + NpcStep talkToTheodorePaxtonAgain; + ConditionalStep cReturnToTheodorePaxton; + + // 28 + WorldEntityStep sailToZenith; + + // 30 + NpcStep talkToSpencerBrentwood; + DetailedQuestStep equipDivingGearAndDive; + NpcStep dive; + DetailedQuestStep listenToSpencer; + + // 32 + ObjectStep repairCoralDredger; + NpcStep fightTheGiantLobster; + + // 34 + ObjectStep repairCoralDredger2; + + // 36 + NpcStep talkToSpencerNearEastCoralDredger; + + // 38 + NpcStep talkToSpencerAboutFuturePlans; + + // 40 + ConditionalStep cReturnToFloopa; + + @Override + protected void setupZones() + { + redRock = new PolyZone(List.of( + new WorldPoint(2809, 2508, 0), + new WorldPoint(2804, 2511, 0) + )); + + lastLightF0 = new Zone( + new WorldPoint(2867, 2319, 0), + new WorldPoint(2849, 2335, 0) + ); + } + + @Override + protected void setupRequirements() + { + rangedCombatGearOrShipWithCannons = new ItemRequirement("Ranged/Mage combat gear to skip boat combat, or a boat with cannons to deal with pirates", -1, -1).isNotConsumed(); + rangedCombatGearOrShipWithCannons.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + combatGear = new ItemRequirement("Combat gear", -1, -1).isNotConsumed(); + combatGear.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + combatGearBethel = new ItemRequirement("Combat gear to fight Black Eye Bethel", -1, -1).isNotConsumed(); + combatGearBethel.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + combatGearLobster = new ItemRequirement("Any combat gear to fight a giant lobster", -1, -1).isNotConsumed(); + combatGearLobster.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + + food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); + prayerPotions = new ItemRequirement("Prayer potions", ItemCollections.PRAYER_POTIONS, -1); + repairKits = new ItemRequirement("Boat repair kits", ItemCollections.BOAT_REPAIR_KITS, 5); + + divingHelmet = new ItemRequirement("Deep sea helmet", ItemID.TRR_DIVING_HELMET); + divingHelmetEquipped = divingHelmet.equipped(); + divingHelmetEquipped.setHighlightInInventory(true); + divingApparatus = new ItemRequirement("Deep sea apparatus", ItemID.TRR_DIVING_BACKPACK); + divingApparatusEquipped = divingApparatus.equipped(); + divingApparatusEquipped.setHighlightInInventory(true); + + var rr1 = new Zone( + new WorldPoint(2805, 2500, 0), + new WorldPoint(2790, 2527, 0) + ); + var rr2 = new Zone( + new WorldPoint(2808, 2521, 0), + new WorldPoint(2806, 2522, 0) + ); + var rr3 = new Zone( + new WorldPoint(2806, 2510, 0), + new WorldPoint(2808, 2509, 0) + ); + var rr4 = new Zone( + new WorldPoint(2789, 2515, 0), + new WorldPoint(2785, 2529, 0) + ); + onRedRock = new ZoneRequirement(rr1, rr2, rr3, rr4); + + onLastLightF0 = new ZoneRequirement(lastLightF0); + onLastLightF1 = new ZoneRequirement(new Zone(11300, 1)); + onLastLightF2 = new ZoneRequirement(new Zone(11300, 2)); + + onZenith = new NpcRequirement(NpcID.TRR_SPENCER_BRENTWOOD_VIS); + + diving = new VarbitRequirement(VarbitID.PLAYER_DIVING, 1); + giantLobsterAround = new NpcRequirement(NpcID.TRR_GIANT_LOBSTER); + onBoat = new VarbitRequirement(VarbitID.SAILING_BOARDED_BOAT, 1); + freeInv2 = new FreeInventorySlotRequirement(2); + noFollower = new NoFollowerRequirement("No pet following you"); + } + + void setupSteps() + { + talkToRaleyToStartQuest = new NpcStep(this, NpcID.TT_RALEY_CONCH, new WorldPoint(3186, 2405, 0), "Talk to Elder Raley at his home in The Great Conch to start the quest."); + talkToRaleyToStartQuest.addDialogStep("Yes."); + + talkToFinn = new NpcStep(this, NpcID.TORTUGAN_FINN, new WorldPoint(3197, 2401, 0), "Talk to Finn, south-east of Elder Raley's house, about Floopa's whereabouts."); + + talkToElderKatt = new NpcStep(this, NpcID.TORTUGAN_GROVE_GUARDIAN, new WorldPoint(3196, 2466, 0), "Head to The Sacred Grove and talk to Elder Katt."); + + talkToFloopa = new NpcStep(this, NpcID.TRR_FLOOPA_VIS, new WorldPoint(3194, 2490, 0), "Enter The Sacred Grove and talk to Floopa."); + + sailToRedRock = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(2809, 2509, 0), "Sail to Red Rock, north-west of The Great Conch."); + + talkToRedRockReceptionist = new NpcStep(this, NpcID.TRR_RED_ROCK_RECEPTIONIST, new WorldPoint(2792, 2522, 0), "Talk to the receptionist on Red Rock."); + + var needToInspectCase1 = new VarbitRequirement(VarbitID.TRR_DISPLAY_CASE_1, 0); + var inspectCase1 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_1, new WorldPoint(2796, 2522, 0), ""); + + var needToInspectCase2 = new VarbitRequirement(VarbitID.TRR_DISPLAY_CASE_2, 0); + var inspectCase2 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_2, new WorldPoint(2794, 2524, 0), ""); + + var needToInspectCase3 = new VarbitRequirement(VarbitID.TRR_DISPLAY_CASE_3, 0); + var inspectCase3 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_3, new WorldPoint(2789, 2523, 0), ""); + + var inspectCase4 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_4, new WorldPoint(2789, 2519, 0), ""); + + cInspectCases = new ConditionalStep(this, inspectCase4, "Familiarize yourself with the history of the Red Reef Trading Company by inspecting the display cases around the building."); + cInspectCases.addStep(needToInspectCase1, inspectCase1); + cInspectCases.addStep(needToInspectCase2, inspectCase2); + cInspectCases.addStep(needToInspectCase3, inspectCase3); + + talkToTheodorePaxton = new NpcStep(this, NpcID.TRR_THEODORE_PAXTON, new WorldPoint(2795, 2517, 0), "Talk to Theodore Paxton."); + + // TODO: add all pirate npc ids + sinkBlackEyeBethelBoats = new NpcStep(this, new int[]{NpcID.TRR_PIRATE_1, NpcID.TRR_PIRATE_2, NpcID.TRR_PIRATE_3, NpcID.TRR_PIRATE_4}, new WorldPoint(2834, 2357, 0), + "Get ready for boat combat, then sail south towards Last Light and deal with Black Eye Bethel. Protect from Missiles to avoid most damage. Repair your ship. " + + "Combat is over when all boats are sunk or all pirates are killed.", rangedCombatGearOrShipWithCannons, combatGearBethel); + sinkBlackEyeBethelBoats.setRecommended(List.of(food, prayerPotions, repairKits)); + + disembarkAtLastLight = new ObjectStep(this, ObjectID.SAILING_MOORING_DISEMBARK, new WorldPoint(2849, 2327, 0), "Disembark at Last Light."); + + killPiratesAtLastLight = new NpcStep(this, new int[]{NpcID.TRR_PIRATE_1, NpcID.TRR_PIRATE_2, NpcID.TRR_PIRATE_3, NpcID.TRR_PIRATE_4}, new WorldPoint(2855, 2325, 0), "Kill all six pirates at Last Light.", true); + + var blackEyeBethelText = "Kill Black Eye Bethel. Use Protect from Melee to avoid some damage. Avoid her charge attack. Re-enable your prayers if she disables them."; + climbUpToF1 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_BASE, new WorldPoint(2863, 2326, 0), blackEyeBethelText, combatGearBethel); + climbUpToF2 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_MIDDLE, new WorldPoint(2863, 2326, 1), blackEyeBethelText, combatGearBethel); + climbUpToF2.addDialogStep("Climb up."); + killBlackEyeBethel = new NpcStep(this, NpcID.TRR_PIRATE_CAPTAIN, new WorldPoint(2862, 2323, 2), blackEyeBethelText, combatGearBethel); + killBlackEyeBethel.addSubSteps(climbUpToF1, climbUpToF2); + + sailToRedRock2 = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(2809, 2509, 0), "Sail to Red Rock, north of Last Light."); + climbDownToF1 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_TOP, new WorldPoint(2863, 2326, 2), "Climb down the tower."); + climbDownToF0 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_MIDDLE, new WorldPoint(2862, 2326, 1), "Climb down the tower."); + climbDownToF0.addDialogStep("Climb down."); + boardYourShip = new ObjectStep(this, ObjectID.SAILING_MOORING_EMBARK, new WorldPoint(2849, 2327, 0), "Board your boat."); + talkToTheodorePaxtonAgain = new NpcStep(this, NpcID.TRR_THEODORE_PAXTON, new WorldPoint(2795, 2517, 0), "Talk to Theodore Paxton."); + cReturnToTheodorePaxton = new ConditionalStep(this, sailToRedRock2, "Return to Theodore Paxton on Red Rock with the good news."); + cReturnToTheodorePaxton.addStep(onRedRock, talkToTheodorePaxtonAgain); + cReturnToTheodorePaxton.addStep(onLastLightF2, climbDownToF1); + cReturnToTheodorePaxton.addStep(onLastLightF1, climbDownToF0); + cReturnToTheodorePaxton.addStep(onLastLightF0, boardYourShip); + + sailToZenith = new WorldEntityStep(this, 9, new WorldPoint(2874, 2506, 0), + "Sail to and board the Zenith, east of Red Rock. If you don't see the Zenith there, try hopping to a different world.", combatGearLobster); + talkToSpencerBrentwood = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, new WorldPoint(2878, 2505, 0), "Talk to Spencer Brentwood aboard the Zenith.", combatGearLobster); + equipDivingGearAndDive = new DetailedQuestStep(this, "Equip the deep sea diving gear and dive down to the bottom of the sea.", combatGearLobster, divingHelmetEquipped, divingApparatusEquipped); + dive = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, "Talk to Spencer Brentwood again with the deep sea diving gear equipped to dive down to the bottom of the sea.", combatGearLobster, divingHelmetEquipped, divingApparatusEquipped, noFollower); + dive.addDialogStep("Let's go."); + dive.addSubSteps(equipDivingGearAndDive); + listenToSpencer = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_DIVING_A, new WorldPoint(2836, 8922, 1), "Listen to Spencer Brentwood's instructions."); + + repairCoralDredger = new ObjectStep(this, ObjectID.TRR_CORAL_DREDGER_BROKEN_OP, new WorldPoint(2844, 8942, 1), "Head north and repair the Coral dredger, ready to fight a Giant lobster.", combatGearLobster); + fightTheGiantLobster = new NpcStep(this, NpcID.TRR_GIANT_LOBSTER, "Kill the Giant lobster. Avoid the blue particles on the floor."); + + repairCoralDredger2 = new ObjectStep(this, ObjectID.TRR_CORAL_DREDGER_BROKEN_OP, new WorldPoint(2844, 8942, 1), "Repair the Coral dredger."); + + talkToSpencerNearEastCoralDredger = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_DIVING_VIS, new WorldPoint(2857, 8915, 1), "Talk to Spencer Brentwood near the eastern coral dredger."); + + talkToSpencerAboutFuturePlans = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, new WorldPoint(2878, 2505, 0), "Talk to Spencer Brentwood aboard the Zenith after repairing the coral dredgers."); + + var talkToSpencerBrentwoodAgain = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, new WorldPoint(2878, 2505, 0), "Return to Spencer Brentwood to disembark onto your boat."); + talkToSpencerBrentwoodAgain.addDialogStep("Actually, I'd like to disembark."); + + var sailToGreatConch = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(3174, 2367, 0), "Sail to The Great Conch."); + var talkToFloopaAtElderRaleysHouse = new NpcStep(this, NpcID.TT_FLOOPA_VIS, new WorldPoint(3185, 2405, 0), ""); + + cReturnToFloopa = new ConditionalStep(this, talkToFloopaAtElderRaleysHouse, "Return to Floopa at Elder Raley's house at The Great Conch."); + cReturnToFloopa.addStep(onZenith, talkToSpencerBrentwoodAgain); + cReturnToFloopa.addStep(onBoat, sailToGreatConch); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToRaleyToStartQuest); + steps.put(2, talkToRaleyToStartQuest); + + steps.put(4, talkToFinn); + + steps.put(6, talkToElderKatt); + + steps.put(8, talkToFloopa); + + steps.put(10, sailToRedRock); + + var cTalkToReceptionist = new ConditionalStep(this, sailToRedRock); + cTalkToReceptionist.addStep(onRedRock, talkToRedRockReceptionist); + steps.put(12, cTalkToReceptionist); + + var cInspectCases = new ConditionalStep(this, sailToRedRock); + cInspectCases.addStep(onRedRock, this.cInspectCases); + steps.put(14, cInspectCases); + + var cTalkToMrPaxton = new ConditionalStep(this, sailToRedRock); + cTalkToMrPaxton.addStep(onRedRock, talkToTheodorePaxton); + steps.put(16, cTalkToMrPaxton); + + steps.put(18, sinkBlackEyeBethelBoats); + + steps.put(20, disembarkAtLastLight); + + var cKillPiratesAtLastLight = new ConditionalStep(this, disembarkAtLastLight); + cKillPiratesAtLastLight.addStep(onLastLightF0, killPiratesAtLastLight); + steps.put(22, cKillPiratesAtLastLight); + + var cKillBlackEyeBethel = new ConditionalStep(this, disembarkAtLastLight); + cKillBlackEyeBethel.addStep(onLastLightF0, climbUpToF1); + cKillBlackEyeBethel.addStep(onLastLightF1, climbUpToF2); + cKillBlackEyeBethel.addStep(onLastLightF2, killBlackEyeBethel); + steps.put(24, cKillBlackEyeBethel); + + steps.put(26, cReturnToTheodorePaxton); + + var cInitialDive = new ConditionalStep(this, sailToZenith); + cInitialDive.addStep(diving, listenToSpencer); + cInitialDive.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cInitialDive.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cInitialDive.addStep(onZenith, talkToSpencerBrentwood); + steps.put(28, cInitialDive); + steps.put(30, cInitialDive); + + var cFightLobster = new ConditionalStep(this, sailToZenith); + cFightLobster.addStep(and(diving, giantLobsterAround), fightTheGiantLobster); + cFightLobster.addStep(diving, repairCoralDredger); + cFightLobster.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cFightLobster.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cFightLobster.addStep(onZenith, talkToSpencerBrentwood); + + steps.put(32, cFightLobster); + + var cRepairNorthernCoralDredger = new ConditionalStep(this, sailToZenith); + cRepairNorthernCoralDredger.addStep(diving, repairCoralDredger2); + cRepairNorthernCoralDredger.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cRepairNorthernCoralDredger.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cRepairNorthernCoralDredger.addStep(onZenith, talkToSpencerBrentwood); + steps.put(34, cRepairNorthernCoralDredger); + + var cRepairEasternCoralDredgerWithSpencer = new ConditionalStep(this, sailToZenith); + cRepairEasternCoralDredgerWithSpencer.addStep(diving, talkToSpencerNearEastCoralDredger); + cRepairEasternCoralDredgerWithSpencer.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cRepairEasternCoralDredgerWithSpencer.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cRepairEasternCoralDredgerWithSpencer.addStep(onZenith, talkToSpencerBrentwood); + + steps.put(36, cRepairEasternCoralDredgerWithSpencer); + + var cTalkToSpencerAboutFuturePlans = new ConditionalStep(this, sailToZenith); + cTalkToSpencerAboutFuturePlans.addStep(onZenith, talkToSpencerAboutFuturePlans); + + steps.put(38, cTalkToSpencerAboutFuturePlans); + + steps.put(40, cReturnToFloopa); + + return steps; + } + + @Override + public List getGeneralRequirements() + { + return List.of( + new QuestRequirement(QuestHelperQuest.TROUBLED_TORTUGANS, QuestState.FINISHED), + new SkillRequirement(Skill.SAILING, 52, false), + new SkillRequirement(Skill.SMITHING, 48, false) + ); + } + + @Override + public List getGeneralRecommended() + { + return List.of( + new SkillRequirement(Skill.PRAYER, 40, false, "43 prayer for Protect from Missiles & Melee"), + new CombatLevelRequirement(65) + ); + } + + @Override + public List getItemRequirements() + { + return List.of( + rangedCombatGearOrShipWithCannons, + combatGear + ); + } + + @Override + public List getItemRecommended() + { + return List.of( + food, + prayerPotions, + repairKits + ); + } + + @Override + public List getCombatRequirements() + { + return List.of( + "2 pirate ships, or the crew on the ship with ranged combat gear", + "6 pirates (lvl 52)", + "Black Eye Bethel (lvl 191)", + "Giant lobster (lvl 112)" + ); + } + + @Override + public QuestPointReward getQuestPointReward() + { + return new QuestPointReward(2); + } + + @Override + public List getExperienceRewards() + { + return List.of( + new ExperienceReward(Skill.SAILING, 15000), + new ExperienceReward(Skill.SMITHING, 5000) + ); + } + + @Override + public List getItemRewards() + { + return List.of( + new ItemReward("Bosun's Workbench Schematic", /*ItemID.LOST_SCHEMATIC_BOSUNS_WORKBENCH*/ -1) // NOTE: The gameval for this item is not in the latest RuneLite release + ); + } + + @Override + public List getUnlockRewards() + { + return List.of( + new UnlockReward("Access to the Great Conch sacred grove") + ); + } + + @Override + public List getPanels() + { + var sections = new ArrayList(); + + sections.add(new PanelDetails("Finding Floopa", List.of( + talkToRaleyToStartQuest, + talkToFinn, + talkToElderKatt, + talkToFloopa + ))); + + sections.add(new PanelDetails("Infiltrating the Red Reef", List.of( + sailToRedRock, + talkToRedRockReceptionist, + cInspectCases, + talkToTheodorePaxton + ))); + + sections.add(new PanelDetails("Dealing with Black Eye Bethel", List.of( + sinkBlackEyeBethelBoats, + disembarkAtLastLight, + killPiratesAtLastLight, + killBlackEyeBethel, + cReturnToTheodorePaxton + ), List.of( + rangedCombatGearOrShipWithCannons, + combatGearBethel + ), List.of( + food, + prayerPotions, + repairKits + ))); + + sections.add(new PanelDetails("Helping the Zenith", List.of( + sailToZenith, + talkToSpencerBrentwood, + dive, + listenToSpencer, + repairCoralDredger, + fightTheGiantLobster, + repairCoralDredger2, + talkToSpencerNearEastCoralDredger, + talkToSpencerAboutFuturePlans + ), List.of( + combatGearLobster, + freeInv2 + ), List.of( + food + ))); + + sections.add(new PanelDetails("Return to Floopa", List.of( + cReturnToFloopa + ))); + + return sections; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java index aa5fa847ba8..534620bed0c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,6 +41,10 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -47,13 +52,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class TheRestlessGhost extends BasicQuestHelper { // Recommended items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java index 02a15095cad..f692f5bf4ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java @@ -5,8 +5,8 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.events.VarbitChanged; import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.VarPlayerID; import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java index ee1bfac5698..64b0ec34b77 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java @@ -191,7 +191,7 @@ protected void setupRequirements() bronzeBar3 = new ItemRequirement("Bronze bars", ItemID.BRONZE_BAR, 3); hammer = new ItemRequirement("Hammer", ItemCollections.HAMMER).isNotConsumed(); - metalKey = new KeyringRequirement("Metal key", configManager, KeyringCollection.METAL_KEY); + metalKey = new KeyringRequirement("Metal key", KeyringCollection.METAL_KEY); metalKey.setTooltip("You can get another by killing the Mercenary Guard outside the Desert Mining Camp"); slaveTop = new ItemRequirement("Slave shirt", ItemID.SLAVE_SHIRT); slaveTop.setTooltip("You can trade in a desert robe set for slave clothes with the Male Slave"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java index 100a526c8f8..25371badb2f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java @@ -45,7 +45,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; @@ -476,15 +480,6 @@ public List getItemRequirements() return reqs; } - @Override - public List getNotes() - { - ArrayList reqs = new ArrayList<>(); - reqs.add("Currently this helper only shows you how to marry Astrid. If you'd like to be friends with her or choose to be with Brand, " + - "you can either follow an external guide for now, or simply talk to King Vargas after the quest to change."); - return reqs; - } - @Override public List getItemRecommended() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java index 0a50496100c..98e697d07b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java @@ -246,7 +246,6 @@ private class PipeSolverSolution { private final WidgetDetails pieceInfo; - private final Widget piece; private final int correctOrientation, selectedVBit, targetX, targetY; public PipeSolverSolution(WidgetDetails piece, int targetX, int targetY, int correctOrientation, int selectedVBit) @@ -257,15 +256,20 @@ public PipeSolverSolution(WidgetDetails piece, int targetX, int targetY, int cor public PipeSolverSolution(WidgetDetails pieceDetails, int targetX, int targetY, int correctOrientation, int selectedVBit, Function getPieceX, Function getPieceY) { this.pieceInfo = pieceDetails; - this.piece = PuzzleSolver.this.getWidget(pieceInfo); - if (this.piece == null) - throw new WidgetNotFoundException(); this.targetX = targetX; this.targetY = targetY; this.correctOrientation = correctOrientation; this.selectedVBit = selectedVBit; } + private Widget getPiece() + { + Widget widget = PuzzleSolver.this.getWidget(pieceInfo); + if (widget == null) + throw new WidgetNotFoundException(); + return widget; + } + public boolean isSolved() { return !isSelected(); @@ -278,27 +282,27 @@ public boolean isSelected() public boolean isLeft() { - return piece.getOriginalX() < targetX - 4; + return getPiece().getOriginalX() < targetX - 4; } public boolean isRight() { - return piece.getOriginalX() > targetX + 4; + return getPiece().getOriginalX() > targetX + 4; } public boolean isAbove() { - return piece.getOriginalY() < targetY - 4; + return getPiece().getOriginalY() < targetY - 4; } public boolean isBelow() { - return piece.getOriginalY() > targetY + 4; + return getPiece().getOriginalY() > targetY + 4; } public boolean isOriented() { - return piece.getModelId() == correctOrientation; + return getPiece().getModelId() == correctOrientation; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java index a1954872842..9beea133524 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java @@ -33,6 +33,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcHintArrowRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; @@ -42,7 +43,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -50,13 +60,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class TreeGnomeVillage extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java index cf26b3e11f9..d40f4b6171d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.events.GameTick; import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; @@ -40,26 +41,21 @@ public class PuzzleStep extends QuestStep { - private final Character ENTRY_ONE = 'K'; - private final Character ENTRY_TWO = 'U'; - private final Character ENTRY_THREE = 'R'; - private final Character ENTRY_FOUR = 'T'; - - private final int SLOT_ONE = 42; - private final int SLOT_TWO = 43; - private final int SLOT_THREE = 44; - private final int SLOT_FOUR = 45; - - private final int ARROW_ONE_LEFT = 46; - private final int ARROW_ONE_RIGHT = 47; - private final int ARROW_TWO_LEFT = 48; - private final int ARROW_TWO_RIGHT = 49; - private final int ARROW_THREE_LEFT = 50; - private final int ARROW_THREE_RIGHT = 51; - private final int ARROW_FOUR_LEFT = 52; - private final int ARROW_FOUR_RIGHT = 53; - - private final int COMPLETE = 55; + private final int ENTRY_ONE = 11; // K + private final int ENTRY_TWO = 21; // U + private final int ENTRY_THREE = 18; // R + private final int ENTRY_FOUR = 20; // T + + private final int ARROW_ONE_LEFT = InterfaceID.TribalDoor.TRIBALA_LEFT; + private final int ARROW_ONE_RIGHT = InterfaceID.TribalDoor.TRIBALA_RIGHT; + private final int ARROW_TWO_LEFT = InterfaceID.TribalDoor.TRIBALB_LEFT; + private final int ARROW_TWO_RIGHT = InterfaceID.TribalDoor.TRIBALB_RIGHT; + private final int ARROW_THREE_LEFT = InterfaceID.TribalDoor.TRIBALC_LEFT; + private final int ARROW_THREE_RIGHT = InterfaceID.TribalDoor.TRIBALC_RIGHT; + private final int ARROW_FOUR_LEFT = InterfaceID.TribalDoor.TRIBALD_LEFT; + private final int ARROW_FOUR_RIGHT = InterfaceID.TribalDoor.TRIBALD_RIGHT; + + private final int COMPLETE = InterfaceID.TribalDoor.TRIBALENTER; private final HashMap highlightButtons = new HashMap<>(); private final HashMap distance = new HashMap<>(); @@ -86,15 +82,15 @@ public void onGameTick(GameTick gameTick) private void updateSolvedPositionState() { - highlightButtons.replace(1, matchStateToSolution(SLOT_ONE, ENTRY_ONE, ARROW_ONE_RIGHT, ARROW_ONE_LEFT)); - highlightButtons.replace(2, matchStateToSolution(SLOT_TWO, ENTRY_TWO, ARROW_TWO_RIGHT, ARROW_TWO_LEFT)); - highlightButtons.replace(3, matchStateToSolution(SLOT_THREE, ENTRY_THREE, ARROW_THREE_RIGHT, ARROW_THREE_LEFT)); - highlightButtons.replace(4, matchStateToSolution(SLOT_FOUR, ENTRY_FOUR, ARROW_FOUR_RIGHT, ARROW_FOUR_LEFT)); + highlightButtons.replace(1, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE1, ENTRY_ONE, ARROW_ONE_RIGHT, ARROW_ONE_LEFT)); + highlightButtons.replace(2, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE2, ENTRY_TWO, ARROW_TWO_RIGHT, ARROW_TWO_LEFT)); + highlightButtons.replace(3, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE3, ENTRY_THREE, ARROW_THREE_RIGHT, ARROW_THREE_LEFT)); + highlightButtons.replace(4, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE4, ENTRY_FOUR, ARROW_FOUR_RIGHT, ARROW_FOUR_LEFT)); - distance.replace(1, matchStateToDistance(SLOT_ONE, ENTRY_ONE)); - distance.replace(2, matchStateToDistance(SLOT_TWO, ENTRY_TWO)); - distance.replace(3, matchStateToDistance(SLOT_THREE, ENTRY_THREE)); - distance.replace(4, matchStateToDistance(SLOT_FOUR, ENTRY_FOUR)); + distance.replace(1, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE1, ENTRY_ONE)); + distance.replace(2, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE2, ENTRY_TWO)); + distance.replace(3, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE3, ENTRY_THREE)); + distance.replace(4, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE4, ENTRY_FOUR)); if (highlightButtons.get(1) + highlightButtons.get(2) + highlightButtons.get(3) + highlightButtons.get(4) == 0) @@ -107,22 +103,17 @@ private void updateSolvedPositionState() } } - private int matchStateToSolution(int slot, Character target, int arrowRightId, int arrowLeftId) + private int matchStateToSolution(int varbitID, int target, int arrowRightId, int arrowLeftId) { - Widget widget = client.getWidget(InterfaceID.TRIBAL_DOOR, slot); - if (widget == null) return 0; - char current = widget.getText().charAt(0); - int currentPos = (int) current - (int) 'A'; - int id = Math.floorMod(currentPos - target, 26) < Math.floorMod(target - currentPos, 26) ? arrowRightId : arrowLeftId; - if (current != target) return id; + int currentPos = client.getVarbitValue(varbitID); + int id = Math.floorMod(currentPos - target, 26) < Math.floorMod(target - currentPos, 26) ? arrowLeftId : arrowRightId; + if (currentPos != target) return id; return 0; } - private int matchStateToDistance(int slot, Character target) + private int matchStateToDistance(int varbitID, int target) { - Widget widget = client.getWidget(InterfaceID.TRIBAL_DOOR, slot); - if (widget == null) return 0; - char current = widget.getText().charAt(0); + int current = client.getVarbitValue(varbitID); return Math.min(Math.floorMod(current - target, 26), Math.floorMod(target - current, 26)); } @@ -137,7 +128,7 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) continue; } - Widget widget = client.getWidget(InterfaceID.TRIBAL_DOOR, entry.getValue()); + Widget widget = client.getWidget(entry.getValue()); if (widget != null) { graphics.setColor(new Color(questHelper.getConfig().targetOverlayColor().getRed(), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java index c0d3ea0310d..187a5a8396f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java @@ -43,6 +43,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; @@ -127,7 +128,7 @@ public void setupConditions() { inEntrance = new ZoneRequirement(houseGroundFloorEntrance); inMiddleRoom = new ZoneRequirement(houseGroundFloorMiddleRoom); - openedLockWidget = new WidgetTextRequirement(369, 54,"Combination Lock Door"); + openedLockWidget = new WidgetTextRequirement(InterfaceID.TribalDoor.TITLE_TEXT, "Combination Lock Door"); inStairway = new ZoneRequirement(houseGroundFloor); investigatedStairs = new WidgetTextRequirement(229, 1, "Your trained senses as a thief enable you to see that there is a trap
in these stairs. You make a note of its location for future reference
when using these stairs."); isUpstairs = new ZoneRequirement(houseFirstFloor); @@ -137,7 +138,7 @@ public void setupConditions() public void setupSteps() { talkToKangaiMau = new NpcStep(this, NpcID.KANGAI_MAU, new WorldPoint(2794, 3182, 0), "Talk to Kangai Mau in the Brimhaven food store."); - talkToKangaiMau.addDialogSteps("I'm in search of adventure!", "Ok, I will get it back."); + talkToKangaiMau.addDialogSteps("I'm in search of adventure!", "Ok, I will get it back.", "Yes."); investigateCrate = new ObjectStep(this, ObjectID.HORNCRATE, new WorldPoint(2650, 3273, 0), "Travel to the GPDT depot in Ardougne and investigate the most northeastern crate for a label."); useLabel = new ObjectStep(this, ObjectID.TELEPORTCRATE, new WorldPoint(2650, 3271, 0), "Use the label on the highlighted crate.", addressLabel); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java index 234599667fe..c1c125ca56f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java index 6fa67c894e2..91cb6ce6b8f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java @@ -33,6 +33,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.List; import net.runelite.api.ItemContainer; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; @@ -42,8 +43,6 @@ import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; -import java.util.List; - public class RepairTown extends DetailedOwnerStep { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java index c7f7035eaf0..cbaf94cd402 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java @@ -33,6 +33,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,7 +43,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -48,13 +60,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class TroubledTortugans extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java index 186f7c26757..119ef3a54b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java @@ -29,62 +29,83 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class VampyreSlayer extends BasicQuestHelper { - //Items Required - ItemRequirement hammer, beer, garlic, garlicObtainable, stake, combatGear; - - //Items Recommended - ItemRequirement varrockTeleport, draynorManorTeleport; - - Requirement inManor, inBasement, isUpstairsInMorgans, draynorNearby; - - QuestStep talkToMorgan, goUpstairsMorgan, getGarlic, ifNeedGarlic, talkToHarlow, talkToHarlowAgain, enterDraynorManor, goDownToBasement, openCoffin, killDraynor; + // Required items + ItemRequirement hammer; + ItemRequirement beer; + ItemRequirement twoCoins; + ItemRequirements beerOrTwoCoins; + ItemRequirement combatGear; - //Zones - Zone manor, basement, upstairsInMorgans; - - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); + // Recommended items + ItemRequirement varrockTeleport; + ItemRequirement draynorManorTeleport; + ItemRequirement garlic; + ItemRequirement garlicObtainable; - steps.put(0, talkToMorgan); + // Mid-quest item requirements + ItemRequirement stake; - ConditionalStep getGarlicAndStake = new ConditionalStep(this, goUpstairsMorgan); - getGarlicAndStake.addStep(garlic, talkToHarlow); - getGarlicAndStake.addStep(isUpstairsInMorgans, getGarlic); + // Zones + Zone manor; + Zone basement; + Zone upstairsInMorgans; - steps.put(1, getGarlicAndStake); + // Miscellaneous requirements + ZoneRequirement inManor; + ZoneRequirement inBasement; + ZoneRequirement isUpstairsInMorgans; + NpcCondition draynorNearby; + Conditions givenBeerToHarlow; - ConditionalStep prepareAndKillDraynor = new ConditionalStep(this, getGarlicAndStake); - prepareAndKillDraynor.addStep(draynorNearby, killDraynor); - prepareAndKillDraynor.addStep(inBasement, openCoffin); - prepareAndKillDraynor.addStep(inManor, goDownToBasement); - prepareAndKillDraynor.addStep(stake, enterDraynorManor); + // Steps + NpcStep talkToMorgan; - steps.put(2, prepareAndKillDraynor); + ObjectStep goUpstairsMorgan; + ObjectStep getGarlic; + ConditionalStep cGetGarlic; + NpcStep talkToHarlow; + NpcStep buyBeer; + NpcStep talkToHarlowAgain; + ObjectStep enterDraynorManor; + ObjectStep goDownToBasement; + ObjectStep openCoffin; + NpcStep killDraynor; - return steps; + @Override + protected void setupZones() + { + basement = new Zone(new WorldPoint(3074, 9767, 0), new WorldPoint(3081, 9779, 0)); + manor = new Zone(new WorldPoint(3097, 3354, 0), new WorldPoint(3119, 3373, 0)); + upstairsInMorgans = new Zone(new WorldPoint(3096, 3266, 1), new WorldPoint(3102, 3270, 1)); } @Override @@ -96,77 +117,109 @@ protected void setupRequirements() stake.setTooltip("You can get another from Dr. Harlow in the Blue Moon Inn in Varrock."); hammer = new ItemRequirement("Hammer", ItemCollections.HAMMER).isNotConsumed(); garlic = new ItemRequirement("Garlic", ItemID.GARLIC); - garlic.setTooltip("Optional, makes Count Draynor weaker"); - beer = new ItemRequirement("A beer, or 2 coins to buy one", ItemID.BEER); + garlic.setTooltip("Weakens Count Draynor"); + beer = new ItemRequirement("Beer", ItemID.BEER); + twoCoins = new ItemRequirement("Coins", ItemID.COINS, 2); + beerOrTwoCoins = new ItemRequirements(LogicType.OR, "A beer, or 2 coins to buy one", beer, twoCoins); combatGear = new ItemRequirement("Combat gear + food to defeat Count Draynor", -1, -1).isNotConsumed(); combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); - garlicObtainable = new ItemRequirement("Garlic", ItemID.GARLIC); + garlicObtainable = garlic.copy(); garlicObtainable.canBeObtainedDuringQuest(); - } - public void setupConditions() - { inBasement = new ZoneRequirement(basement); inManor = new ZoneRequirement(manor); isUpstairsInMorgans = new ZoneRequirement(upstairsInMorgans); draynorNearby = new NpcCondition(NpcID.COUNT_DRAYNOR); - } - @Override - protected void setupZones() - { - basement = new Zone(new WorldPoint(3074, 9767, 0), new WorldPoint(3081, 9779, 0)); - manor = new Zone(new WorldPoint(3097, 3354, 0), new WorldPoint(3119, 3373, 0)); - upstairsInMorgans = new Zone(new WorldPoint(3096, 3266, 1), new WorldPoint(3102, 3270, 1)); + var givenBeerToHarlow1 = new DialogRequirement("You give a beer to Dr Harlow."); + givenBeerToHarlow1.setMustBeActive(true); + givenBeerToHarlow1.setAllowMesbox(true); + var givenBeerToHarlow2 = new DialogRequirement("Cheersh matey...", "So tell me how to kill vampyres then.", "Yesh, yesh vampyres, I was very good at killing em once", "Well, you're going to need a stake"); + givenBeerToHarlow2.setMustBeActive(true); + givenBeerToHarlow = or(givenBeerToHarlow1, givenBeerToHarlow2); } public void setupSteps() { talkToMorgan = new NpcStep(this, NpcID.MORGAN, new WorldPoint(3098, 3268, 0), "Talk to Morgan in the north of Draynor Village."); - talkToMorgan.addDialogStep("Ok, I'm up for an adventure."); - talkToMorgan.addDialogStep("Accept quest"); - goUpstairsMorgan = new ObjectStep(this, ObjectID.STAIRS, new WorldPoint(3100, 3267, 0), "Go upstairs in Morgan's house and search the cupboard for some garlic."); - getGarlic = new ObjectStep(this, ObjectID.GARLICCUPBOARDOPEN, new WorldPoint(3096, 3270, 1), "Search the cupboard upstairs in Morgan's house."); - ((ObjectStep) getGarlic).addAlternateObjects(ObjectID.GARLICCUPBOARDSHUT); - ifNeedGarlic = new DetailedQuestStep(this, "If you need garlic, you can get some from the cupboard upstairs in Morgan's house."); - ifNeedGarlic.addSubSteps(goUpstairsMorgan, getGarlic); - - talkToHarlow = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow in the Blue Moon Inn in Varrock.", beer); + talkToMorgan.addDialogStep("Yes."); + + goUpstairsMorgan = new ObjectStep(this, ObjectID.STAIRS, new WorldPoint(3100, 3267, 0), "Climb the stairs."); + getGarlic = new ObjectStep(this, ObjectID.GARLICCUPBOARDOPEN, new WorldPoint(3096, 3270, 1), "Search the cupboard."); + getGarlic.addAlternateObjects(ObjectID.GARLICCUPBOARDSHUT); + cGetGarlic = new ConditionalStep(this, goUpstairsMorgan, "Get garlic from the cupboard upstairs in Morgan's house.\n\nYou can tick off this section in the sidebar to skip the garlic acquisition."); + cGetGarlic.addStep(isUpstairsInMorgans, getGarlic); + + talkToHarlow = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow in the Blue Moon Inn in Varrock.", beerOrTwoCoins); talkToHarlow.addDialogStep("Morgan needs your help!"); - talkToHarlowAgain = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow again with a beer. You can buy one for 2gp in the Blue Moon Inn.", beer); - enterDraynorManor = new ObjectStep(this, ObjectID.HAUNTEDDOORL, new WorldPoint(3108, 3353, 0), "Prepare to fight Count Draynor (level 34), and enter Draynor Manor.", combatGear, stake, hammer, garlic); - goDownToBasement = new ObjectStep(this, ObjectID.CRYPTSTAIRSDOWN, new WorldPoint(3116, 3358, 0), "Enter Draynor Manor's basement.", combatGear, stake, hammer, garlic); - openCoffin = new ObjectStep(this, ObjectID.VAMPCOFFIN, new WorldPoint(3078, 9776, 0), "Open the coffin and kill Count Draynor.", combatGear, stake, hammer, garlic); - killDraynor = new NpcStep(this, NpcID.COUNT_DRAYNOR, new WorldPoint(3077, 9769, 0), "Kill Count Draynor.", combatGear, stake, hammer, garlic); + buyBeer = new NpcStep(this, NpcID.BLUEMOON_BARTENDER, "Buy a beer from the bartender in the Blue Moon Inn in Varrock.", twoCoins); + buyBeer.addDialogStep("A glass of your finest ale please."); + talkToHarlowAgain = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow again with a beer.", beer); + talkToHarlowAgain.addDialogStep("Yes. Here you go."); + + List countDraynorReqs = List.of(hammer, stake, combatGear); + List countDraynorRecommended = List.of(garlic); + enterDraynorManor = new ObjectStep(this, ObjectID.HAUNTEDDOORL, new WorldPoint(3108, 3353, 0), "Prepare to fight Count Draynor (level 34), and enter Draynor Manor.", countDraynorReqs, countDraynorRecommended); + goDownToBasement = new ObjectStep(this, ObjectID.CRYPTSTAIRSDOWN, new WorldPoint(3116, 3358, 0), "Enter Draynor Manor's basement.", countDraynorReqs, countDraynorRecommended); + openCoffin = new ObjectStep(this, ObjectID.VAMPCOFFIN, new WorldPoint(3078, 9776, 0), "Open the coffin and kill Count Draynor.", countDraynorReqs, countDraynorRecommended); + killDraynor = new NpcStep(this, NpcID.COUNT_DRAYNOR, new WorldPoint(3077, 9769, 0), "Kill Count Draynor.", countDraynorReqs, countDraynorRecommended); openCoffin.addSubSteps(killDraynor); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToMorgan); + + var getGarlicAndStake = new ConditionalStep(this, cGetGarlic); + getGarlicAndStake.addStep(garlic, talkToHarlow); + steps.put(1, getGarlicAndStake); + + var getStake = new ConditionalStep(this, talkToHarlowAgain); + getStake.addStep(givenBeerToHarlow, talkToHarlowAgain); + getStake.addStep(not(beer), buyBeer); + var prepareAndKillDraynor = new ConditionalStep(this, getStake); + prepareAndKillDraynor.addStep(draynorNearby, killDraynor); + prepareAndKillDraynor.addStep(inBasement, openCoffin); + prepareAndKillDraynor.addStep(inManor, goDownToBasement); + prepareAndKillDraynor.addStep(stake, enterDraynorManor); + + steps.put(2, prepareAndKillDraynor); + + return steps; + } + @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(hammer); - reqs.add(beer); - reqs.add(combatGear); - return reqs; + return List.of( + hammer, + beerOrTwoCoins, + combatGear + ); } @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - reqs.add(varrockTeleport); - reqs.add(draynorManorTeleport); - reqs.add(garlicObtainable); - return reqs; + return List.of( + varrockTeleport, + draynorManorTeleport, + garlicObtainable + ); } @Override public List getCombatRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Count Draynor (level 34)"); - return reqs; + return List.of( + "Count Draynor (level 34)" + ); } @Override @@ -178,17 +231,46 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.ATTACK, 4825)); + return List.of( + new ExperienceReward(Skill.ATTACK, 4825) + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToMorgan + ))); + + var garlicSection = new PanelDetails("Get garlic", List.of( + cGetGarlic + )); + garlicSection.setLockingStep(cGetGarlic); + sections.add(garlicSection); + + sections.add(new PanelDetails("Get a stake", List.of( + talkToHarlow, + buyBeer, + talkToHarlowAgain + ), List.of( + beerOrTwoCoins + ))); + + sections.add(new PanelDetails("Kill Count Draynor", List.of( + enterDraynorManor, + goDownToBasement, + openCoffin + ), List.of( + hammer, + stake, + combatGear + ), List.of( + garlic + ))); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(talkToMorgan, ifNeedGarlic))); - allSteps.add(new PanelDetails("Get a stake", Arrays.asList(talkToHarlow, talkToHarlowAgain), beer)); - allSteps.add(new PanelDetails("Kill Count Draynor", Arrays.asList(enterDraynorManor, goDownToBasement, openCoffin), hammer, stake, garlic, combatGear)); - return allSteps; + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java index 6d70f71b89e..c24aa9b27e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java @@ -52,7 +52,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java index 7e2e1bcda4e..a815e6d73c7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java @@ -45,7 +45,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -467,7 +471,7 @@ public void setupSteps() stealRockCake = new ObjectStep(this, ObjectID.ROCKCOUNTER_WITHCAKES, new WorldPoint(2514, 3036, 0), "Steal a rock cake from Gu'Tanoth's market."); - talkToGuardBattlement = new NpcStep(this, NpcID.OGRE_GUARD3, new WorldPoint(2503, 3012, 0), "Talk to an Ogre Guard next to the battelement."); + talkToGuardBattlement = new NpcStep(this, NpcID.OGRE_GUARD3, new WorldPoint(2503, 3012, 0), "Talk to an Ogre Guard next to the battlement."); talkToGuardBattlement.addDialogStep("But I am a friend to ogres..."); talkToGuardWithRockCake = new ObjectStep(this, NpcID.OGRE_GUARD3, new WorldPoint(2507, 3012, 0), "Attempt to cross the battlement again with a rock cake.", rockCake); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java index 53a9e9909ea..dbc6f03668e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java @@ -29,13 +29,23 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -43,10 +53,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class WaterfallQuest extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java index cd5151d3ea1..755a965577d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java @@ -185,6 +185,7 @@ public void setupSteps() talkToSurok = new NpcStep(this, NpcID.SUROK_SUROK, new WorldPoint(3211, 3493, 0), "Talk to Surok Magis in the Varrock Library.", letterToSurok); talkToSurokNoLetter = new NpcStep(this, NpcID.WGS_SUROK_TRANSITION, new WorldPoint(3211, 3493, 0), "Talk to Surok Magis in the Varrock Library."); + ((NpcStep) talkToSurokNoLetter).addAlternateNpcs(NpcID.SUROK_SUROK_TYPE1); talkToSurokNoLetter.addDialogSteps("Go on, then!", "Go on then!"); talkToSurok.addSubSteps(talkToSurokNoLetter); @@ -278,7 +279,7 @@ public List getPanels() List allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToRat))); allSteps.add(new PanelDetails("Help Rat", Arrays.asList(killOutlaws, bringFolderToRat))); - allSteps.add(new PanelDetails("Help Surok", Arrays.asList(talkToSurok, enterChaosAltar, useWandOnAltar, bringWandToSurok), chaosRunes15, chaosTalismanOrAbyss, bowl)); + allSteps.add(new PanelDetails("Help Surok", Arrays.asList(talkToSurok, enterChaosAltar, useWandOnAltar, bringWandToSurok), chaosRunes15, chaosTalismanOrAbyss, bowl, wand)); allSteps.add(new PanelDetails("Defeat Surok", Arrays.asList(talkToRatAfterSurok, talkToZaff, talkToSurokToFight, fightRoald, talkToRatToFinish))); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java index 777c1b452d6..f72bf89f64d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java @@ -984,7 +984,7 @@ protected void setupRequirements() placedEarthBlock = new VarbitRequirement(VarbitID.WGS_EARTH_KEY_USED, 1); notPlacedFireBlock = new VarbitRequirement(VarbitID.WGS_FIRE_KEY_USED, 0); - noWeaponOrShieldEquipped = new ComplexRequirement("No weapon or shield equipped", new NoItemRequirement("", ItemSlots.WEAPON), new NoItemRequirement("", ItemSlots.SHIELD)); + noWeaponOrShieldEquipped = new NoItemRequirement("Nothing equipped in your hands", ItemSlots.EMPTY_HANDS); airCavity = new Zone(new WorldPoint(4107, 5095, 0), new WorldPoint(4119, 5116, 0)); inAirCavity = new ZoneRequirement(airCavity); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java index e88fb2908ae..44fd46da666 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java @@ -32,13 +32,25 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -46,13 +58,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class WitchsHouse extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java index e33a50f6de6..6dff4d5a391 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java @@ -33,17 +33,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class WitchsPotion extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java index cc33e64f752..5768cf0b31f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java @@ -29,22 +29,20 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.DigStep; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; public class XMarksTheSpot extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java index c1a357b1715..d84dffe7cca 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java @@ -31,6 +31,9 @@ import net.runelite.api.Item; import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.Callable; @Slf4j @@ -52,12 +55,36 @@ public ItemAndLastUpdated(TrackedContainers containerType) this.containerType = containerType; } + /// Updates the full list of items in this container public void update(int updateTick, Item[] items) { this.lastUpdated = updateTick; this.items = items; } + /// Helper function to add a single item into the container. + /// + /// Prefer using the update method if possible. + public void add(int updateTick, int itemID, int itemQuantity) + { + this.lastUpdated = updateTick; + + var newItems = new ArrayList<>(List.of(this.items)); + newItems.add(new Item(itemID, itemQuantity)); + + this.items = newItems.toArray(new Item[0]); + } + + /// Helper function to remove items with a given item ID from the container. + /// + /// Prefer using the update method if possible. + public void removeByItemID(int updateTick, int itemID) + { + this.lastUpdated = updateTick; + + this.items = Arrays.stream(this.items).filter((item) -> item.getId() != itemID).toArray(Item[]::new); + } + /** * Get the Items contained within the Tracked Container. * If this instance of ItemAndLastUpdated has a method in specialMethodToObtainItems to obtain the current state of the Container other than diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java index 7b423627391..625ea5f6a73 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java @@ -44,7 +44,7 @@ public class NewVersionManager private final String LAST_VERSION_SEEN_CONFIG_KEY = "lastversionchecked"; - private final String UPDATE_CHAT_TEXT = "Quest Helper has been updated to 4.12.1! This improves the default order for Sea Charting, and adds a proximity mode you can toggle at the top of it!"; + private final String UPDATE_CHAT_TEXT = "Quest Helper has been updated to 4.15.1! You can now filter by leagues regions, and the League's Helper is improved."; public void updateChatWithNotificationIfNewVersion() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java index 03a1bac8dc2..9ad173886d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java @@ -56,8 +56,11 @@ public class QuestContainerManager @Getter private final static ItemAndLastUpdated runePouchData = new ItemAndLastUpdated(TrackedContainers.RUNE_POUCH); + @Getter + private final static ItemAndLastUpdated keyRingData = new ItemAndLastUpdated(TrackedContainers.KEY_RING); + @Getter - private final static List orderedListOfContainers = List.of(equippedData, inventoryData, bankData, runePouchData, potionData, groupStorageData); + private final static List orderedListOfContainers = List.of(equippedData, inventoryData, bankData, runePouchData, potionData, groupStorageData, keyRingData); static Set RUNE_POUCHES = Set.of(ItemID.BH_RUNE_POUCH, ItemID.BH_RUNE_POUCH_TROUVER, ItemID.DIVINE_RUNE_POUCH, ItemID.DIVINE_RUNE_POUCH_TROUVER); private static final int NUM_SLOTS = 6; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java index 85864b9f0f7..a94bbb3682c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.config.LeagueFiltering; import net.runelite.client.plugins.microbot.questhelper.config.SkillFiltering; import net.runelite.client.plugins.microbot.questhelper.panel.QuestHelperPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestDetails; @@ -229,6 +230,7 @@ public void updateQuestList() .filter(config.difficulty()) .filter(QuestDetails::showCompletedQuests) .filter(SkillFiltering::passesSkillFilter) + .filter(LeagueFiltering::passesLeagueFilter) .sorted(config.orderListBy()) .collect(Collectors.toList()); Map completedQuests = QuestHelperQuest.getQuestHelpers(isDeveloperMode()) @@ -476,6 +478,7 @@ private void getAllItemRequirements() .stream() .filter(pred) .filter(QuestDetails::isNotCompleted) + .filter(LeagueFiltering::passesLeagueFilter) .sorted(config.orderListBy()) .collect(Collectors.toList()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java index d05de52e615..4a411b70fb2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java @@ -33,7 +33,6 @@ import net.runelite.api.*; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; import net.runelite.client.util.Text; import javax.inject.Inject; @@ -131,7 +130,7 @@ private void handleShieldOfArrav() return; } - WorldPoint location = Rs2Player.getWorldLocation(); + WorldPoint location = player.getWorldLocation(); QuestHelperQuest questToStart = PHOENIX_START_ZONE.contains(location) ? QuestHelperQuest.SHIELD_OF_ARRAV_PHOENIX_GANG : QuestHelperQuest.SHIELD_OF_ARRAV_BLACK_ARM_GANG; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java index 6d16420abf0..c4d05be9914 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java @@ -26,6 +26,11 @@ public QuestHelperMinimapOverlay(QuestHelperPlugin plugin) @Override public Dimension render(Graphics2D graphics) { + if (plugin.isInCutscene()) + { + return null; + } + QuestHelper quest = plugin.getSelectedQuest(); if (quest != null && quest.getCurrentStep() != null && quest.getCurrentStep().getActiveStep() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java index 9be7416147a..c37ee6b597e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java @@ -31,6 +31,7 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPanel; +import net.runelite.client.ui.overlay.OverlayPriority; import javax.inject.Inject; import java.awt.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java index 7960babaf2e..1f3ee50951f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java @@ -49,6 +49,11 @@ public QuestHelperWorldArrowOverlay(QuestHelperPlugin plugin) @Override public Dimension render(Graphics2D graphics) { + if (plugin.isInCutscene()) + { + return null; + } + QuestHelper quest = plugin.getSelectedQuest(); if (quest != null && quest.getCurrentStep() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java index feac0cba6f1..51988c55b84 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java @@ -54,6 +54,11 @@ public Dimension render(Graphics2D graphics) return null; } + if (plugin.isInCutscene()) + { + return null; + } + QuestHelper quest = plugin.getSelectedQuest(); if (quest != null && quest.getCurrentStep() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java index 002db5eb04d..911c32400f1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java @@ -63,15 +63,24 @@ public Dimension render(Graphics2D graphics) QuestHelper quest = plugin.getSelectedQuest(); - if (quest != null && quest.getCurrentStep() != null) + if (quest != null) { - quest.makeWorldOverlayHint(graphics, plugin); - quest.getCurrentStep().makeWorldOverlayHint(graphics, plugin); + var currentStep = quest.getCurrentStep(); + if (currentStep != null) + { + if (!plugin.isInCutscene() || currentStep.getActiveStep().isAllowInCutscene()) + { + currentStep.makeWorldOverlayHint(graphics, plugin); + } + } } - plugin.getBackgroundHelpers().forEach((name, questHelper) -> questHelper.getCurrentStep().makeWorldOverlayHint(graphics, plugin)); + if (!plugin.isInCutscene()) + { + plugin.getBackgroundHelpers().forEach((name, questHelper) -> questHelper.getCurrentStep().makeWorldOverlayHint(graphics, plugin)); - plugin.getRuneliteObjectManager().makeWorldOverlayHint(graphics); + plugin.getRuneliteObjectManager().makeWorldOverlayHint(graphics); + } return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java index f79c75fb306..53a0f7f66ae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java @@ -72,7 +72,7 @@ public static JTextArea makeJTextArea() jTextArea.setOpaque(false); jTextArea.setEditable(false); jTextArea.setFocusable(false); - jTextArea.setBackground(UIManager.getColor("Label.background")); + jTextArea.setBackground(javax.swing.UIManager.getColor("Label.background")); jTextArea.setBorder(new EmptyBorder(0, 0, 0, 0)); return jTextArea; @@ -86,7 +86,7 @@ public static JTextArea makeJTextArea(String text) jTextArea.setOpaque(false); jTextArea.setEditable(false); jTextArea.setFocusable(false); - jTextArea.setBackground(UIManager.getColor("Label.background")); + jTextArea.setBackground(javax.swing.UIManager.getColor("Label.background")); jTextArea.setBorder(new EmptyBorder(0, 0, 0, 0)); return jTextArea; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/ManualStepSkipStore.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/ManualStepSkipStore.java new file mode 100644 index 00000000000..528815a9d80 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/ManualStepSkipStore.java @@ -0,0 +1,112 @@ +package net.runelite.client.plugins.microbot.questhelper.panel; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.config.ConfigManager; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * Persists per-RuneScape-profile manual step skips under {@link QuestHelperConfig#QUEST_HELPER_GROUP}, + * one JSON map key per displayed helper name (same grouping as sidebar order). + */ +public final class ManualStepSkipStore +{ + private static final Type MAP_TYPE = new TypeToken>() + { + }.getType(); + + private ManualStepSkipStore() + { + } + + public static String configKeyForQuest(String displayedQuestName) + { + return QuestHelperConfig.QUEST_HELPER_MANUAL_SKIPS_KEY_PREFIX + slug(displayedQuestName); + } + + private static String slug(String name) + { + if (name == null) + { + return "helper"; + } + String s = name.trim().replaceAll("[^a-zA-Z0-9_-]+", "_"); + if (s.length() > 96) + { + s = s.substring(0, 96); + } + return s.isEmpty() ? "helper" : s; + } + + public static Map load(ConfigManager cm, Gson gson, String displayedQuestName) + { + if (cm == null || cm.getRSProfileKey() == null) + { + return new HashMap<>(); + } + String ck = configKeyForQuest(displayedQuestName); + String raw = cm.getRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + if ((raw == null || raw.isBlank()) && cm.getRSProfileKey() != null) + { + String legacy = cm.getConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + if (legacy != null && !legacy.isBlank()) + { + cm.setRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck, legacy); + cm.unsetConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + raw = legacy; + } + } + if (raw == null || raw.isBlank()) + { + return new HashMap<>(); + } + try + { + Map m = gson.fromJson(raw, MAP_TYPE); + return m != null ? new HashMap<>(m) : new HashMap<>(); + } + catch (RuntimeException e) + { + return new HashMap<>(); + } + } + + public static void put(ConfigManager cm, Gson gson, String displayedQuestName, String slotKey, boolean skipped) + { + if (cm == null || cm.getRSProfileKey() == null || slotKey == null || slotKey.isBlank()) + { + return; + } + String ck = configKeyForQuest(displayedQuestName); + Map map = load(cm, gson, displayedQuestName); + if (skipped) + { + map.put(slotKey, true); + } + else + { + map.remove(slotKey); + } + if (map.isEmpty()) + { + cm.unsetRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + } + else + { + cm.setRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck, gson.toJson(map)); + } + } + + public static void clearAll(ConfigManager cm, String displayedQuestName) + { + if (cm == null || cm.getRSProfileKey() == null) + { + return; + } + cm.unsetRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, configKeyForQuest(displayedQuestName)); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java index b1bfcc9590c..5830295f1b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java @@ -37,7 +37,7 @@ public class PanelDetails { @Getter - int id = -1; + int id = Integer.MIN_VALUE; @Getter String header; @@ -139,6 +139,11 @@ public void addSteps(QuestStep... steps) this.steps.addAll(Arrays.asList(steps)); } + public void addSteps(Collection steps) + { + this.steps.addAll(steps); + } + public boolean contains(QuestStep currentStep) { if (getSteps().contains(currentStep)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java index 2c840fa1f7b..a8893857eea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.managers.QuestManager; +import net.runelite.client.plugins.microbot.questhelper.panel.regionfiltering.RegionFilterPanel; import net.runelite.client.plugins.microbot.questhelper.panel.skillfiltering.SkillFilterPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestDetails; @@ -39,6 +40,9 @@ import net.runelite.api.GameState; import net.runelite.api.QuestState; import net.runelite.api.Skill; +import net.runelite.api.WorldType; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.config.ConfigManager; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; @@ -54,12 +58,13 @@ import javax.swing.event.DocumentListener; import javax.swing.plaf.basic.BasicButtonUI; import java.awt.*; +import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; @Slf4j @@ -74,17 +79,37 @@ public class QuestHelperPanel extends PluginPanel private final JPanel searchQuestsPanel; private final JPanel allDropdownSections = new JPanel(); + private final JPanel filterStackPanel = new JPanel(); private final JComboBox filterDropdown, difficultyDropdown, orderDropdown; private final JComboBox stateDropdown = new JComboBox<>(); private JPanel statePanel; private final JButton skillExpandButton = new JButton(); + private JPanel regionsFilterSection; + private RegionFilterPanel regionFilterPanel; private final IconTextField searchBar = new IconTextField(); private final FixedWidthPanel questListPanel = new FixedWidthPanel(); private final FixedWidthPanel questListWrapper = new FixedWidthPanel(); private final JScrollPane scrollableContainer; + private final CardLayout viewportLayout = new CardLayout(); + private final JPanel viewportContent = new JPanel(viewportLayout) + { + @Override + public Dimension getPreferredSize() + { + for (Component component : getComponents()) + { + if (component.isVisible()) + { + return component.getPreferredSize(); + } + } + return super.getPreferredSize(); + } + }; public static final int DROPDOWN_HEIGHT = 26; public boolean questActive = false; + private String activeView = VIEW_QUEST_LIST; private final ArrayList questSelectPanels = new ArrayList<>(); @@ -98,6 +123,9 @@ public class QuestHelperPanel extends PluginPanel private static final ImageIcon SETTINGS_ICON; private static final ImageIcon COLLAPSED_ICON; private static final ImageIcon EXPANDED_ICON; + private static final String VIEW_QUEST_LIST = "quest_list"; + private static final String VIEW_QUEST_OVERVIEW = "quest_overview"; + private static final String VIEW_SETTINGS = "settings"; private int nextDesiredScrollValue = 0; @@ -160,14 +188,14 @@ public QuestHelperPanel(QuestHelperPlugin questHelperPlugin, QuestManager questM onSearchBarChanged(); }); - settingsBtn.addMouseListener(new MouseAdapter() + settingsBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { settingsBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { if (settingsPanelActive()) { @@ -189,14 +217,14 @@ public void mouseExited(MouseEvent evt) discordBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); discordBtn.setUI(new BasicButtonUI()); discordBtn.addActionListener((ev) -> LinkBrowser.browse("https://discord.gg/XCfwNnz6RB")); - discordBtn.addMouseListener(new MouseAdapter() + discordBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { discordBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { discordBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); } @@ -211,14 +239,14 @@ public void mouseExited(MouseEvent evt) githubBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); githubBtn.setUI(new BasicButtonUI()); githubBtn.addActionListener((ev) -> LinkBrowser.browse("https://github.com/Zoinkwiz/quest-helper")); - githubBtn.addMouseListener(new MouseAdapter() + githubBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { githubBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { githubBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); } @@ -233,14 +261,14 @@ public void mouseExited(MouseEvent evt) patreonBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); patreonBtn.setUI(new BasicButtonUI()); patreonBtn.addActionListener((ev) -> LinkBrowser.browse("https://www.patreon.com/zoinkwiz")); - patreonBtn.addMouseListener(new MouseAdapter() + patreonBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { patreonBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { patreonBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); } @@ -318,21 +346,21 @@ public void changedUpdate(DocumentEvent e) skillExpandButton.setHorizontalTextPosition(SwingConstants.LEFT); skillExpandButton.setIconTextGap(10); skillExpandButton.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent mouseEvent) { - skillFilterPanel.setVisible(!skillFilterPanel.isVisible()); - if (skillFilterPanel.isVisible()) - { - skillExpandButton.setIcon(EXPANDED_ICON); - } - else + @Override + public void mousePressed(MouseEvent mouseEvent) { - skillExpandButton.setIcon(COLLAPSED_ICON); + skillFilterPanel.setVisible(!skillFilterPanel.isVisible()); + if (skillFilterPanel.isVisible()) + { + skillExpandButton.setIcon(EXPANDED_ICON); + } + else + { + skillExpandButton.setIcon(COLLAPSED_ICON); + } } - } - }); + }); JPanel skillExpandBar = new JPanel(); skillExpandBar.setLayout(new BorderLayout()); @@ -362,6 +390,53 @@ public void mousePressed(MouseEvent mouseEvent) } }); + // Region filtering + JButton regionExpandButton = new JButton(); + regionExpandButton.setForeground(Color.GRAY); + regionExpandButton.setIcon(COLLAPSED_ICON); + regionExpandButton.setHorizontalTextPosition(SwingConstants.LEFT); + regionExpandButton.setIconTextGap(10); + + regionFilterPanel = new RegionFilterPanel(questHelperPlugin.spriteManager, () -> { + questHelperPlugin.getClientThread().invokeLater(questManager::updateQuestList); + int count = regionFilterPanel.getSelectedCount(); + regionExpandButton.setText(count > 0 ? String.format("%d active", count) : ""); + }); + regionFilterPanel.setVisible(false); + + JLabel regionFilterName = JGenerator.makeJLabel("Region filtering"); + regionFilterName.setForeground(Color.WHITE); + questHelperPlugin.spriteManager.getSpriteAsync(2214, 0, sprite -> { + if (sprite != null) + { + SwingUtilities.invokeLater(() -> regionFilterName.setIcon(new ImageIcon(sprite))); + } + }); + + JPanel regionExpandBar = new JPanel(); + regionExpandBar.setLayout(new BorderLayout()); + regionExpandBar.setToolTipText("Choose league regions to filter quests by"); + regionExpandBar.add(regionFilterName, BorderLayout.CENTER); + regionExpandBar.add(regionExpandButton, BorderLayout.EAST); + + MouseAdapter regionExpandListener = new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + regionFilterPanel.setVisible(!regionFilterPanel.isVisible()); + regionExpandButton.setIcon(regionFilterPanel.isVisible() ? EXPANDED_ICON : COLLAPSED_ICON); + } + }; + regionExpandButton.addMouseListener(regionExpandListener); + regionExpandBar.addMouseListener(regionExpandListener); + + regionsFilterSection = new JPanel(); + regionsFilterSection.setLayout(new BorderLayout()); + regionsFilterSection.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + regionsFilterSection.add(regionExpandBar, BorderLayout.CENTER); + regionsFilterSection.add(regionFilterPanel, BorderLayout.SOUTH); + // Filter dropdown + search allDropdownSections.setLayout(new BoxLayout(allDropdownSections, BoxLayout.Y_AXIS)); allDropdownSections.setBorder(new EmptyBorder(0, 0, 10, 0)); @@ -369,14 +444,23 @@ public void mousePressed(MouseEvent mouseEvent) allDropdownSections.add(difficultyPanel); allDropdownSections.add(orderPanel); allDropdownSections.add(skillsFilterPanel); + allDropdownSections.add(regionsFilterSection); - searchQuestsPanel.add(allDropdownSections, BorderLayout.NORTH); + // Set initial visibility based on config and current world type + updateRegionFilterVisibility(questHelperPlugin.getClient().getWorldType().contains(WorldType.SEASONAL)); + + filterStackPanel.setLayout(new BoxLayout(filterStackPanel, BoxLayout.Y_AXIS)); + filterStackPanel.setOpaque(false); + filterStackPanel.add(Box.createVerticalStrut(8)); + filterStackPanel.add(allDropdownSections); + + searchQuestsPanel.add(filterStackPanel, BorderLayout.NORTH); // Wrapper questListWrapper.setLayout(new BorderLayout()); questListWrapper.add(questListPanel, BorderLayout.NORTH); - scrollableContainer = new JScrollPane(questListWrapper); + scrollableContainer = new JScrollPane(viewportContent); scrollableContainer.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); @@ -394,6 +478,9 @@ public void mousePressed(MouseEvent mouseEvent) questOverviewWrapper.setLayout(new BorderLayout()); questOverviewWrapper.add(questOverviewPanel, BorderLayout.NORTH); + viewportContent.add(questListWrapper, VIEW_QUEST_LIST); + viewportContent.add(questOverviewWrapper, VIEW_QUEST_OVERVIEW); + viewportContent.add(assistLevelPanel, VIEW_SETTINGS); if (questHelperPlugin.isDeveloperMode()) { @@ -404,8 +491,56 @@ public void mousePressed(MouseEvent mouseEvent) var devModePanel = new JPanel(); devModePanel.setLayout(new BorderLayout()); + var togglePuzzleHelper = new JMenuItem(new AbstractAction("toggle puzzle helper") + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + var v = questHelperPlugin.getConfig().solvePuzzles(); + configManager.setConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, "solvePuzzles", !v); + } + }); + + var toggleCutsceneStatus = new JMenuItem(new AbstractAction("toggle cutscene status") + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + questHelperPlugin.getClientThread().invoke(() -> { + // from RuneLite core's devtools ::setvarb + var varbit = VarbitID.CUTSCENE_STATUS; + var client = questHelperPlugin.getClient(); + + var currentStatus = client.getVarbitValue(VarbitID.CUTSCENE_STATUS); + var varbitComposition = client.getVarbit(varbit); + var value = currentStatus == 0 ? 1 : 0; + + client.setVarbitValue(client.getVarps(), varbit, value); + client.queueChangedVarp(varbitComposition.getIndex()); + var varbitChanged = new VarbitChanged(); + varbitChanged.setVarbitId(varbit); + varbitChanged.setValue(value); + questHelperPlugin.getEventBus().post(varbitChanged); // fake event + }); + } + }); + + var menu = new JPopupMenu("Menu"); + menu.add(togglePuzzleHelper); + menu.add(toggleCutsceneStatus); var reloadQuest = new JButton("reload quest"); + reloadQuest.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + if (SwingUtilities.isRightMouseButton(e) && e.getClickCount() == 1) + { + menu.show(reloadQuest, e.getX(), e.getY()); + } + } + }); reloadQuest.addActionListener((ev) -> { nextDesiredScrollValue = scrollableContainer.getVerticalScrollBar().getValue(); var currentQuest = questHelperPlugin.getSelectedQuest(); @@ -417,6 +552,10 @@ public void mousePressed(MouseEvent mouseEvent) }); devModePanel.add(reloadQuest, BorderLayout.SOUTH); + JPanel previewNavPanel = new JPanel(new GridLayout(2, 1, 0, 4)); + previewNavPanel.setBackground(ColorScheme.DARK_GRAY_COLOR); + devModePanel.add(previewNavPanel, BorderLayout.CENTER); + // State dropdown for BasicQuestHelper stateDropdown.setFocusable(false); stateDropdown.addItemListener((ev) -> { @@ -443,7 +582,7 @@ else if (selectedItem != null) } } }); - + // Create a panel with label for the state dropdown statePanel = makeDropdownPanel(stateDropdown, "Quest State"); statePanel.setPreferredSize(new Dimension(PANEL_WIDTH, DROPDOWN_HEIGHT)); @@ -468,12 +607,11 @@ private void onSearchBarChanged() if ((questOverviewPanel.currentQuest == null || !text.isEmpty())) { activateQuestList(); - questSelectPanels.forEach(questListPanel::remove); showMatchingQuests(text); } else { - scrollableContainer.setViewportView(questOverviewWrapper); + showView(VIEW_QUEST_OVERVIEW); } revalidate(); } @@ -515,21 +653,25 @@ private JPanel makeDropdownPanel(JComboBox dropdown, String name) private void showMatchingQuests(String text) { - if (text.isEmpty()) + questSelectPanels.forEach(questListPanel::remove); + + if (text == null || text.isEmpty()) { questSelectPanels.forEach(questListPanel::add); - return; } - - final String[] searchTerms = text.toLowerCase().split(" "); - - questSelectPanels.forEach(listItem -> + else { - if (Text.matchesSearchTerms(Arrays.asList(searchTerms), listItem.getKeywords())) + final String[] searchTerms = text.toLowerCase().split(" "); + questSelectPanels.forEach(listItem -> { - questListPanel.add(listItem); - } - }); + if (Text.matchesSearchTerms(Arrays.asList(searchTerms), listItem.getKeywords())) + { + questListPanel.add(listItem); + } + }); + } + revalidate(); + repaint(); } public void refresh(List questHelpers, boolean loggedOut, @@ -590,10 +732,11 @@ public void refresh(List questHelpers, boolean loggedOut, showMatchingQuests(searchBar.getText() != null ? searchBar.getText() : ""); } + public void addQuest(QuestHelper quest, boolean isActive) { allDropdownSections.setVisible(false); - scrollableContainer.setViewportView(questOverviewWrapper); + showView(VIEW_QUEST_OVERVIEW); questOverviewPanel.addQuest(quest, isActive); updateStateDropdown(quest); @@ -631,7 +774,9 @@ public void removeQuest() questActive = false; questOverviewPanel.removeQuest(); activateQuestList(); + showMatchingQuests(searchBar.getText() != null ? searchBar.getText() : ""); updateStateDropdown(null); + scrollableContainer.getVerticalScrollBar().setValue(0); repaint(); revalidate(); @@ -639,12 +784,12 @@ public void removeQuest() private boolean settingsPanelActive() { - return scrollableContainer.getViewport().getView() == assistLevelPanel; + return VIEW_SETTINGS.equals(activeView); } private void activateSettings() { - scrollableContainer.setViewportView(assistLevelPanel); + showView(VIEW_SETTINGS); searchQuestsPanel.setVisible(false); repaint(); @@ -655,7 +800,7 @@ private void deactivateSettings() { if (questActive && searchBar.getText().isEmpty()) { - scrollableContainer.setViewportView(questOverviewWrapper); + showView(VIEW_QUEST_OVERVIEW); } else { @@ -669,7 +814,7 @@ private void deactivateSettings() private void activateQuestList() { - scrollableContainer.setViewportView(questListWrapper); + showView(VIEW_QUEST_LIST); searchQuestsPanel.setVisible(true); allDropdownSections.setVisible(true); @@ -677,6 +822,17 @@ private void activateQuestList() revalidate(); } + private void showView(String viewName) + { + if (viewName.equals(activeView)) + { + return; + } + + viewportLayout.show(viewportContent, viewName); + activeView = viewName; + } + private void updateStateDropdown(QuestHelper questHelper) { if (!questHelperPlugin.isDeveloperMode()) return; @@ -746,7 +902,7 @@ public void setSelectedQuest(QuestHelper questHelper) else { assistLevelPanel.rebuild(questHelper, configManager, this); - scrollableContainer.setViewportView(assistLevelPanel); + showView(VIEW_SETTINGS); searchQuestsPanel.setVisible(false); } } @@ -785,4 +941,31 @@ public void refreshSkillFiltering() skillExpandButton.setText(String.format("%d active", numFilteredSkills)); } } + + /** + * Updates visibility of the region filter section based on config and world type. + */ + public void updateRegionFilterVisibility(boolean isLeagueWorld) + { + QuestHelperConfig.RegionFilterVisibility visibility = questHelperPlugin.getConfig().regionFilterVisibility(); + boolean shouldShow; + switch (visibility) + { + case SHOW: + shouldShow = true; + break; + case HIDE: + shouldShow = false; + break; + case AUTO: + default: + shouldShow = isLeagueWorld; + break; + } + regionsFilterSection.setVisible(shouldShow); + if (!shouldShow) + { + regionFilterPanel.clearSelection(); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java index d2d63233d3b..ba751a8ea03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java @@ -56,8 +56,8 @@ import java.awt.event.ItemEvent; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.*; import java.util.List; +import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; @@ -81,7 +81,10 @@ public class QuestOverviewPanel extends JPanel private final QuestRewardsPanel questRewardsPanel; private final JPanel questExternalResourcesList; - private final JPanel questStepsContainer = new JPanel(); + private JPanel questStepsContainer; + private final CardLayout questStepsLayout = new CardLayout(); + private final JPanel questStepsHost = new JPanel(questStepsLayout); + private final JPanel activeStepsCard = new JPanel(new BorderLayout()); private final JPanel actionsContainer = new JPanel(); private final JPanel configContainer = new JPanel(); @@ -90,6 +93,8 @@ public class QuestOverviewPanel extends JPanel private final JLabel questNameLabel = JGenerator.makeJLabel(); private static final ImageIcon CLOSE_ICON = Icon.CLOSE.getIcon(); + private static final String ACTIVE_STEPS_CARD = "active"; + private static final String EMPTY_STEPS_CARD = "empty"; private final List allQuestStepPanelList = new CopyOnWriteArrayList<>(); public QuestOverviewPanel(QuestHelperPlugin questHelperPlugin, QuestManager questManager) @@ -109,7 +114,7 @@ public QuestOverviewPanel(QuestHelperPlugin questHelperPlugin, QuestManager ques actionsContainer.setBorder(new EmptyBorder(5, 5, 5, 10)); actionsContainer.setVisible(false); - final JPanel viewControls = new JPanel(new GridLayout(1, 3, 10, 0)); + final JPanel viewControls = new JPanel(new GridLayout(1, 1, 6, 0)); viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR); JButton closeBtn = new JButton(); @@ -197,11 +202,15 @@ public QuestOverviewPanel(QuestHelperPlugin questHelperPlugin, QuestManager ques introPanel.add(overviewPanel, BorderLayout.NORTH); /* Container for quest steps */ - questStepsContainer.setLayout(new BoxLayout(questStepsContainer, BoxLayout.Y_AXIS)); + questStepsContainer = createQuestStepsContainer(); + activeStepsCard.add(questStepsContainer, BorderLayout.CENTER); + questStepsHost.add(new JPanel(), EMPTY_STEPS_CARD); + questStepsHost.add(activeStepsCard, ACTIVE_STEPS_CARD); + questStepsLayout.show(questStepsHost, EMPTY_STEPS_CARD); add(actionsContainer); add(configContainer); add(introPanel); - add(questStepsContainer); + add(questStepsHost); } private JComboBox makeNewDropdown(Enum[] values, String key) @@ -251,6 +260,10 @@ public void addQuest(QuestHelper quest, boolean isActive) { currentQuest = quest; allQuestStepPanelList.clear(); + questStepsContainer = createQuestStepsContainer(); + activeStepsCard.removeAll(); + activeStepsCard.add(questStepsContainer, BorderLayout.CENTER); + questStepsLayout.show(questStepsHost, ACTIVE_STEPS_CARD); List steps = quest.getPanels(); QuestStep currentStep; @@ -324,7 +337,8 @@ public void removeQuest() introPanel.setVisible(false); configContainer.setVisible(false); configContainer.removeAll(); - questStepsContainer.removeAll(); + questStepsLayout.show(questStepsHost, EMPTY_STEPS_CARD); + allQuestStepPanelList.clear(); questGeneralRequirementsPanel.setRequirements(null); questGeneralRecommendedPanel.setRequirements(null); questItemRequirementsPanel.setRequirements(null); @@ -337,6 +351,13 @@ public void removeQuest() revalidate(); } + private JPanel createQuestStepsContainer() + { + JPanel container = new JPanel(); + container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); + return container; + } + /// The quest helper's X is clicked private void closeHelper() { @@ -415,6 +436,10 @@ public void setupQuestRequirements(QuestHelper quest) private static void collectRequirements(QuestHelper quest, List allRequirements, Set processedQuestIds) { + if (quest.getQuest() == null) + { + return; + } if (quest.getQuest().getQuestHelper().getGeneralRequirements() == null) return; List generalRequirements = quest.getQuest().getQuestHelper().getGeneralRequirements(); @@ -524,6 +549,11 @@ private void updateCombatRequirementsPanels(List combatRequirementList) private void updateExternalResourcesPanel(QuestHelper quest) { List externalResourcesList; + if (quest.getQuest() == null) + { + questExternalResourcesList.removeAll(); + return; + } try { externalResourcesList = Collections.singletonList(ExternalQuestResources.valueOf(quest.getQuest().name().toUpperCase()).getWikiURL()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java index 27e547a1705..1782997e9d3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java @@ -50,8 +50,11 @@ import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class QuestRequirementsPanel extends JPanel { @@ -92,7 +95,7 @@ public static JPanel createHeader(@NonNull String header) var headerPanel = new JPanel(); headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); headerPanel.setLayout(new BorderLayout()); - headerPanel.setBorder(new EmptyBorder(5, 5, 5, 10)); + headerPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); var headerLabel = JGenerator.makeJTextArea(header); headerLabel.setForeground(Color.WHITE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java index 42f5beab26d..dbef8c712aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java @@ -58,7 +58,7 @@ public QuestRewardsPanel() rewardsText.setOpaque(false); rewardsText.setEditable(false); rewardsText.setFocusable(false); - rewardsText.setBackground(UIManager.getColor("Label.background")); + rewardsText.setBackground(javax.swing.UIManager.getColor("Label.background")); rewardsText.setFont(Fonts.getOriginalFont()); rewardsText.setBorder(new EmptyBorder(0, 0, 0, 0)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestStepPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestStepPanel.java deleted file mode 100644 index 290e67db96b..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestStepPanel.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2020, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.panel; - -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; -import net.runelite.client.plugins.microbot.questhelper.managers.QuestManager; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.FontManager; -import net.runelite.client.util.SwingUtil; - -import javax.annotation.Nullable; -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - -public class QuestStepPanel extends JPanel implements MouseListener -{ - private static final int TITLE_PADDING = 5; - - @Getter - private final PanelDetails panelDetails; - private final QuestHelperPlugin questHelperPlugin; - - private final JPanel headerPanel = new JPanel(); - private final JTextPane headerLabel = JGenerator.makeJTextPane(); - private final JPanel bodyPanel = new JPanel(); - private final JCheckBox lockStep = new JCheckBox(); - @Getter - private final JPanel leftTitleContainer; - private final JPanel viewControls; - private final HashMap steps = new HashMap<>(); - private final @Nullable QuestRequirementsPanel requiredItemsPanel; - private final @Nullable QuestRequirementsPanel recommendedItemsPanel; - private boolean stepAutoLocked; - private final QuestHelper questHelper; - private QuestStep lastHighlightedStep = null; - - public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestManager questManager, QuestHelperPlugin questHelperPlugin) - { - this.panelDetails = panelDetails; - this.questHelperPlugin = questHelperPlugin; - this.questHelper = questManager.getSelectedQuest(); - - setLayout(new BorderLayout(0, 1)); - setBorder(new EmptyBorder(5, 0, 0, 0)); - - leftTitleContainer = new JPanel(new BorderLayout(5, 0)); - - headerLabel.addMouseListener(this); - addMouseListener(this); - - headerLabel.setText(panelDetails.getHeader()); - headerLabel.setFont(FontManager.getRunescapeBoldFont()); - - headerLabel.setMinimumSize(new Dimension(1, headerLabel.getPreferredSize().height)); - - headerPanel.setLayout(new BoxLayout(headerPanel, BoxLayout.X_AXIS)); - headerPanel.setBorder(new EmptyBorder(7, 7, 3, 7)); - - headerPanel.add(Box.createRigidArea(new Dimension(TITLE_PADDING, 0))); - leftTitleContainer.add(headerLabel, BorderLayout.CENTER); - headerPanel.add(leftTitleContainer, BorderLayout.WEST); - - viewControls = new JPanel(new GridLayout(1, 3, 10, 0)); - - SwingUtil.addModalTooltip(lockStep, "Mark section as incomplete", "Mark section as complete"); - lockStep.setBackground(ColorScheme.DARKER_GRAY_COLOR); - lockStep.addActionListener(ev -> lockSection(lockStep.isSelected())); - lockStep.setVisible(false); - headerPanel.add(lockStep, BorderLayout.EAST); - - viewControls.add(lockStep); - - headerPanel.add(viewControls, BorderLayout.EAST); - - if (panelDetails.contains(currentStep)) - { - headerLabel.setForeground(Color.BLACK); - headerPanel.setBackground(ColorScheme.BRAND_ORANGE); - viewControls.setBackground(ColorScheme.BRAND_ORANGE); - leftTitleContainer.setBackground(ColorScheme.BRAND_ORANGE); - } - else - { - headerLabel.setForeground(Color.WHITE); - headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - leftTitleContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - } - - /* Body */ - bodyPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - bodyPanel.setLayout(new BorderLayout()); - bodyPanel.setBorder(new EmptyBorder(10, 5, 10, 5)); - - if (panelDetails.getRequirements() != null) - { - requiredItemsPanel = new QuestRequirementsPanel("Bring the following items:", panelDetails.getRequirements(), questManager, false); - bodyPanel.add(requiredItemsPanel, BorderLayout.NORTH); - } - else - { - requiredItemsPanel = null; - } - - if (panelDetails.getRecommended() != null) - { - recommendedItemsPanel = new QuestRequirementsPanel("Optionally bring the following items:", panelDetails.getRecommended(), questManager, - false); - bodyPanel.add(recommendedItemsPanel, BorderLayout.CENTER); - } - else - { - recommendedItemsPanel = null; - } - - JPanel questStepsPanel = new JPanel(); - questStepsPanel.setLayout(new BoxLayout(questStepsPanel, BoxLayout.Y_AXIS)); - questStepsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - - for (QuestStep step : panelDetails.getSteps()) - { - JTextPane questStepLabel = JGenerator.makeJTextPane(); - questStepLabel.setLayout(new BorderLayout()); - questStepLabel.setAlignmentX(SwingConstants.LEFT); - questStepLabel.setAlignmentY(SwingConstants.TOP); - questStepLabel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - questStepLabel.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createMatteBorder(1, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR.brighter()), - BorderFactory.createEmptyBorder(5, 5, 10, 0) - )); - questStepLabel.setText(generateText(step)); - questStepLabel.setOpaque(true); - questStepLabel.setVisible(step.isShowInSidebar()); - - steps.put(step, questStepLabel); - questStepsPanel.add(questStepLabel); - - } - - bodyPanel.add(questStepsPanel, BorderLayout.SOUTH); - - add(headerPanel, BorderLayout.NORTH); - add(bodyPanel, BorderLayout.CENTER); - - if (!panelDetails.getSteps().contains(currentStep)) - { - collapse(); - } - } - - public String generateText(QuestStep step) - { - StringBuilder text = new StringBuilder(); - - if (step.getText() != null) - { - var first = true; - for (var line : step.getText()) - { - if (!first) - { - text.append("\n\n"); - } - text.append(line); - first = false; - } - } - - return text.toString(); - } - - public List getSteps() - { - return new ArrayList<>(steps.keySet()); - } - - public HashMap getStepsLabels() - { - return steps; - } - - public void setLockable(boolean canLock) - { - lockStep.setVisible(canLock); - } - - public void updateHighlightCheck(Client client, QuestStep newStep, QuestHelper currentQuest) - { - if (panelDetails.getHideCondition() == null || !panelDetails.getHideCondition().check(client)) - { - setVisible(true); - boolean highlighted = false; - setLockable(panelDetails.getLockingQuestSteps() != null && - (panelDetails.getVars() == null || panelDetails.getVars().contains(currentQuest.getVar()))); - - for (QuestStep sidebarStep : getSteps()) - { - if (sidebarStep.getConditionToHide() != null && sidebarStep.getConditionToHide().check(client)) continue; - if (sidebarStep.containsSteps(newStep, new HashSet<>())) - { - highlighted = true; - updateHighlight(sidebarStep); - break; - } - } - - if (!highlighted) - { - removeHighlight(); - } - } - else - { - setVisible(false); - } - } - - - public void updateHighlight(QuestStep currentStep) - { - expand(); - - if (steps.get(lastHighlightedStep) != null) - { - steps.get(lastHighlightedStep).setForeground(Color.LIGHT_GRAY); - } - else - { - headerLabel.setForeground(Color.BLACK); - headerPanel.setBackground(ColorScheme.BRAND_ORANGE); - viewControls.setBackground(ColorScheme.BRAND_ORANGE); - leftTitleContainer.setBackground(ColorScheme.BRAND_ORANGE); - } - - if (steps.get(currentStep) != null) - { - steps.get(currentStep).setForeground(ColorScheme.BRAND_ORANGE); - } - - lastHighlightedStep = currentStep; - } - - public void removeHighlight() - { - headerLabel.setForeground(Color.WHITE); - if (isCollapsed()) - { - applyDimmer(false, headerPanel); - } - headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - leftTitleContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - if (steps.get(currentlyActiveQuestSidebarStep()) != null) - { - steps.get(currentlyActiveQuestSidebarStep()).setForeground(Color.LIGHT_GRAY); - } - - collapse(); - } - - public void updateLock() - { - if (panelDetails.getLockingQuestSteps() == null) - { - return; - } - - if (panelDetails.getLockingQuestSteps().isUnlockable()) - { - stepAutoLocked = false; - lockStep.setEnabled(true); - } - else - { - if (!stepAutoLocked) - { - collapse(); - } - stepAutoLocked = true; - lockStep.setEnabled(false); - } - - if (panelDetails.getLockingQuestSteps().isLocked()) - { - lockStep.setSelected(true); - } - } - - private void lockSection(boolean locked) - { - if (locked) - { - panelDetails.getLockingQuestSteps().setLockedManually(true); - if (!isCollapsed()) - { - collapse(); - } - } - else - { - panelDetails.getLockingQuestSteps().setLockedManually(false); - if (isCollapsed()) - { - expand(); - } - } - } - - private void collapse() - { - if (!isCollapsed()) - { - bodyPanel.setVisible(false); - applyDimmer(false, headerPanel); - } - } - - private void expand() - { - if (isCollapsed()) - { - bodyPanel.setVisible(true); - applyDimmer(true, headerPanel); - } - } - - boolean isCollapsed() - { - return !bodyPanel.isVisible(); - } - - private void applyDimmer(boolean brighten, JPanel panel) - { - for (Component component : panel.getComponents()) - { - Color color = component.getForeground(); - component.setForeground(brighten ? color.brighter() : color.darker()); - } - } - - public void updateRequirements(Client client) - { - if (requiredItemsPanel != null) - { - requiredItemsPanel.update(client, questHelperPlugin); - } - - if (recommendedItemsPanel != null) - { - recommendedItemsPanel.update(client, questHelperPlugin); - } - - updateStepVisibility(client); - } - - public void updateStepVisibility(Client client) - { - boolean stepVisibilityChanged = false; - for (QuestStep step : steps.keySet()) - { - boolean oldVisibility = step.isShowInSidebar(); - boolean newVisibility = step.getConditionToHide() == null || !step.getConditionToHide().check(client); - stepVisibilityChanged = stepVisibilityChanged || (oldVisibility != newVisibility); - - step.setShowInSidebar(newVisibility); - steps.get(step).setVisible(newVisibility); - } - - if (stepVisibilityChanged) - { - updateHighlightCheck(client, currentlyActiveQuestSidebarStep(), questHelper); - } - } - - private QuestStep currentlyActiveQuestSidebarStep() - { - return questHelperPlugin.getSelectedQuest().getCurrentStep().getActiveStep(); - } - - @Override - public void mouseClicked(MouseEvent e) - { - if (e.getButton() == MouseEvent.BUTTON1) - { - if (isCollapsed()) - { - expand(); - } - else - { - collapse(); - } - } - } - - @Override - public void mousePressed(MouseEvent mouseEvent) - { - } - - @Override - public void mouseReleased(MouseEvent mouseEvent) - { - } - - @Override - public void mouseEntered(MouseEvent mouseEvent) - { - } - - @Override - public void mouseExited(MouseEvent mouseEvent) - { - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java index 6945285280d..1522e462e11 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java @@ -26,7 +26,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import lombok.Getter; - import java.util.ArrayList; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java index b24beed088f..dfd06d9c33d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java @@ -27,9 +27,8 @@ import com.google.common.collect.ImmutableList; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import lombok.Getter; - import java.util.List; +import lombok.Getter; /** * The order of these quests are parsed using data from the OSRS Wiki @@ -261,6 +260,8 @@ public class IronmanOptimalQuestGuide QuestHelperQuest.THE_CORSAIR_CURSE, QuestHelperQuest.IN_SEARCH_OF_KNOWLEDGE, QuestHelperQuest.HOPESPEARS_WILL, + QuestHelperQuest.THE_IDES_OF_MILK, + QuestHelperQuest.THE_RED_REEF, // Quests & mini quests that are not part of the OSRS Wiki's Optimal Ironman Quest Guide QuestHelperQuest.VALE_TOTEMS, QuestHelperQuest.BALLOON_TRANSPORT_GRAND_TREE, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java index 1e2a0ce6478..84d9ed1ece0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java @@ -27,9 +27,8 @@ import com.google.common.collect.ImmutableList; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import lombok.Getter; - import java.util.List; +import lombok.Getter; /** * The order of these quests are parsed using data from the OSRS Wiki @@ -266,6 +265,8 @@ public class OptimalQuestGuide QuestHelperQuest.SONG_OF_THE_ELVES, QuestHelperQuest.CLOCK_TOWER, QuestHelperQuest.THE_CORSAIR_CURSE, + QuestHelperQuest.THE_IDES_OF_MILK, + QuestHelperQuest.THE_RED_REEF, // Quests & mini quests that are not part of the OSRS Wiki's Optimal Quest Guide QuestHelperQuest.VALE_TOTEMS, QuestHelperQuest.BARBARIAN_TRAINING, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java index 45dac69e04b..221ef4d55f8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java @@ -27,9 +27,8 @@ import com.google.common.collect.ImmutableList; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import lombok.Getter; - import java.util.List; +import lombok.Getter; /** * The order of these quests are parsed using data from the OSRS Wiki @@ -226,6 +225,8 @@ public class ReleaseDate QuestHelperQuest.PRYING_TIMES, QuestHelperQuest.CURRENT_AFFAIRS, QuestHelperQuest.TROUBLED_TORTUGANS, + QuestHelperQuest.THE_IDES_OF_MILK, + QuestHelperQuest.THE_RED_REEF, // Miniquests QuestHelperQuest.ALFRED_GRIMHANDS_BARCRAWL, QuestHelperQuest.THE_MAGE_ARENA, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java index 85251329c00..c623ec6c751 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java @@ -29,8 +29,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Client; - import javax.swing.*; +import java.util.HashMap; import java.util.List; public abstract class AbstractQuestSection extends JPanel diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java index af26014f442..c86c481c799 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java @@ -36,7 +36,6 @@ import net.runelite.client.ui.FontManager; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.SwingUtil; - import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; @@ -44,15 +43,20 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class QuestSectionSection extends AbstractQuestSection implements MouseListener { // Idea is to contain multiple sections or queststeppanel private static final int TITLE_PADDING = 5; - private static final ImageIcon DRAG_ICON = new ImageIcon(ImageUtil.loadImageResource(QuestHelperPlugin.class, "/hamburger.png")); + private static final ImageIcon DRAG_ICON = new ImageIcon(ImageUtil.loadImageResource(QuestHelperPlugin.class, "hamburger.png")); private final QuestOverviewPanel questOverviewPanel; private final QuestHelperPlugin questHelperPlugin; @@ -125,7 +129,7 @@ public QuestSectionSection(QuestOverviewPanel questOverviewPanel, TopLevelPanelD stepsPanel.setBorder(new EmptyBorder(10, 5, 10, 5)); // Dragging functionality - this.draggable = panelDetails.getPanelDetails().stream().anyMatch((pDetails -> pDetails.getId() != -1)); + this.draggable = panelDetails.getPanelDetails().stream().anyMatch((pDetails -> pDetails.getId() != Integer.MIN_VALUE)); List order = questHelperPlugin.loadSidebarOrder(questManager.getSelectedQuest()); List panelDetailsList = panelDetails.getPanelDetails(); @@ -476,7 +480,7 @@ private void swapPanels(AbstractQuestSection a, AbstractQuestSection b) public List getIds() { List allIds = new ArrayList<>(); - if (panelDetails.getId() != -1) allIds.add(panelDetails.getId()); + if (panelDetails.getId() != Integer.MIN_VALUE) allIds.add(panelDetails.getId()); allIds.addAll(subPanels.stream() .map(AbstractQuestSection::getIds) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java index 5665aca9eec..dcbefe6f8cd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java @@ -27,9 +27,12 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.managers.QuestManager; import net.runelite.client.plugins.microbot.questhelper.panel.JGenerator; +import net.runelite.client.plugins.microbot.questhelper.panel.ManualStepSkipStore; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.QuestRequirementsPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.ManualRequirement; +import net.runelite.client.plugins.microbot.questhelper.steps.BoardShipStep; import net.runelite.client.plugins.microbot.questhelper.steps.PortTaskStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Client; @@ -41,19 +44,26 @@ import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; +import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; public class QuestStepPanel extends AbstractQuestSection implements MouseListener { private static final int TITLE_PADDING = 5; private final QuestHelperPlugin questHelperPlugin; - private final HashMap steps = new HashMap<>(); + private final Map stepTextPanes = new HashMap<>(); + private final Map stepRowPanels = new HashMap<>(); + private final Map manualSkipBoxes = new HashMap<>(); + private final Map persistedManualSkips; + private final List orderedSidebarSteps = new ArrayList<>(); + private boolean suppressManualSkipEvents; private final @Nullable QuestRequirementsPanel requiredItemsPanel; private final @Nullable QuestRequirementsPanel recommendedItemsPanel; private boolean stepAutoLocked; @@ -65,6 +75,18 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan this.panelDetails = panelDetails; this.questHelperPlugin = questHelperPlugin; this.questHelper = questManager.getSelectedQuest(); + if (this.questHelper != null) + { + this.persistedManualSkips = ManualStepSkipStore.load( + this.questHelper.getConfigManager(), + this.questHelper.gson, + this.questHelper.getDisplayedQuestName() + ); + } + else + { + this.persistedManualSkips = new HashMap<>(); + } setLayout(new BorderLayout(0, 1)); setBorder(new EmptyBorder(5, 0, 0, 0)); @@ -131,7 +153,7 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan if (panelDetails.getRecommended() != null) { recommendedItemsPanel = new QuestRequirementsPanel("Optionally bring the following items:", panelDetails.getRecommended(), questManager, - false); + false); bodyPanel.add(recommendedItemsPanel, BorderLayout.CENTER); } else @@ -145,18 +167,16 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan for (QuestStep step : panelDetails.getSteps()) { - if(step instanceof PortTaskStep) + if (step instanceof PortTaskStep) { for (QuestStep step2 : ((PortTaskStep) step).getStepsList()) { - JTextPane questStepLabel = createQuestStepLabel(step2); - steps.put(step2, questStepLabel); - questStepsPanel.add(questStepLabel); + addStepRow(questStepsPanel, step2); } - }else{ - JTextPane questStepLabel = createQuestStepLabel(step); - steps.put(step, questStepLabel); - questStepsPanel.add(questStepLabel); + } + else + { + addStepRow(questStepsPanel, step); } } @@ -171,7 +191,179 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan } } - private JTextPane createQuestStepLabel(QuestStep step){ + private void addStepRow(JPanel questStepsPanel, QuestStep step) + { + orderedSidebarSteps.add(step); + JPanel row = buildStepRow(step); + stepRowPanels.put(step, row); + questStepsPanel.add(row); + } + + private JPanel buildStepRow(QuestStep step) + { + JPanel row = new JPanel(new BorderLayout()); + row.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + JTextPane questStepLabel = createQuestStepTextPane(step); + stepTextPanes.put(step, questStepLabel); + row.add(questStepLabel, BorderLayout.CENTER); + + ManualRequirement m = step.getSidebarManualSkipRequirement(); + String pk = step.getSidebarManualSkipPersistenceKey(); + if (m != null && pk != null && !pk.isBlank()) + { + boolean persistedSkipped = Boolean.TRUE.equals(persistedManualSkips.get(pk)); + if (persistedSkipped) + { + m.setShouldPass(true); + } + + JCheckBox skip = new JCheckBox(); + skip.setToolTipText("Skip step"); + skip.setOpaque(true); + Client c = questHelperPlugin.getClient(); + skip.setSelected(c != null && m.check(c)); + manualSkipBoxes.put(step, skip); + skip.addActionListener(e -> { + if (suppressManualSkipEvents) + { + return; + } + boolean sel = skip.isSelected(); + m.setShouldPass(sel); + if (sel) + { + persistedManualSkips.put(pk, true); + } + else + { + persistedManualSkips.remove(pk); + } + if (questHelper != null) + { + questHelper.notifyManualSidebarSkipChanged(pk, sel); + } + }); + skip.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + maybeShowManualSkipContextMenu(step, skip, e); + } + + @Override + public void mouseReleased(MouseEvent e) + { + maybeShowManualSkipContextMenu(step, skip, e); + } + }); + row.add(skip, BorderLayout.EAST); + } + + row.setVisible(step.isShowInSidebar()); + return row; + } + + private void maybeShowManualSkipContextMenu(QuestStep clickedStep, JCheckBox source, MouseEvent e) + { + if (!e.isPopupTrigger()) + { + return; + } + JPopupMenu menu = new JPopupMenu(); + JMenuItem tickUpTo = new JMenuItem("Tick all up to this step"); + tickUpTo.addActionListener(ev -> tickManualSkipCheckboxesUpTo(clickedStep)); + menu.add(tickUpTo); + JMenuItem resetAll = new JMenuItem("Reset all tick boxes"); + resetAll.addActionListener(ev -> resetAllManualSkipCheckboxes()); + menu.add(resetAll); + menu.show(source, e.getX(), e.getY()); + } + + private void tickManualSkipCheckboxesUpTo(QuestStep clickedStep) + { + if (clickedStep == null || orderedSidebarSteps.isEmpty()) + { + return; + } + int endIndex = orderedSidebarSteps.indexOf(clickedStep); + if (endIndex < 0) + { + return; + } + suppressManualSkipEvents = true; + try + { + for (int i = 0; i <= endIndex; i++) + { + QuestStep step = orderedSidebarSteps.get(i); + ManualRequirement m = step.getSidebarManualSkipRequirement(); + String pk = step.getSidebarManualSkipPersistenceKey(); + if (m == null || pk == null || pk.isBlank()) + { + continue; + } + m.setShouldPass(true); + persistedManualSkips.put(pk, true); + JCheckBox box = manualSkipBoxes.get(step); + if (box != null) + { + box.setSelected(true); + } + if (questHelper != null) + { + questHelper.notifyManualSidebarSkipChanged(pk, true); + } + } + } + finally + { + suppressManualSkipEvents = false; + } + } + + private void resetAllManualSkipCheckboxes() + { + if (questHelper != null) + { + questHelper.resetAllManualSidebarSkips(); + } + if (manualSkipBoxes.isEmpty()) + { + return; + } + suppressManualSkipEvents = true; + try + { + for (Map.Entry e : manualSkipBoxes.entrySet()) + { + QuestStep step = e.getKey(); + JCheckBox box = e.getValue(); + ManualRequirement m = step.getSidebarManualSkipRequirement(); + String pk = step.getSidebarManualSkipPersistenceKey(); + if (m != null) + { + m.setShouldPass(false); + } + if (pk != null && !pk.isBlank()) + { + persistedManualSkips.remove(pk); + } + if (box != null) + { + box.setSelected(false); + } + } + } + finally + { + suppressManualSkipEvents = false; + } + } + + private JTextPane createQuestStepTextPane(QuestStep step) + { JTextPane questStepLabel = JGenerator.makeJTextPane(); questStepLabel.setLayout(new BorderLayout()); questStepLabel.setAlignmentX(SwingConstants.LEFT); @@ -183,13 +375,37 @@ private JTextPane createQuestStepLabel(QuestStep step){ )); questStepLabel.setText(generateText(step)); questStepLabel.setOpaque(true); - questStepLabel.setVisible(step.isShowInSidebar()); + questStepLabel.setVisible(true); return questStepLabel; } + private void syncManualSkipCheckboxesFromRequirements(Client client) + { + if (manualSkipBoxes.isEmpty()) + { + return; + } + suppressManualSkipEvents = true; + try + { + for (Map.Entry e : manualSkipBoxes.entrySet()) + { + ManualRequirement m = e.getKey().getSidebarManualSkipRequirement(); + if (m != null) + { + e.getValue().setSelected(client != null && m.check(client)); + } + } + } + finally + { + suppressManualSkipEvents = false; + } + } + public void updateAllText() { - steps.forEach((questStep, textPane) -> { + stepTextPanes.forEach((questStep, textPane) -> { if (textPane != null) { String newText = generateText(questStep); @@ -226,7 +442,7 @@ public String generateText(QuestStep step) public List getSteps() { - return new ArrayList<>(steps.keySet()); + return new ArrayList<>(stepTextPanes.keySet()); } public void setLockable(boolean canLock) @@ -282,19 +498,19 @@ public boolean updateHighlightCheck(Client client, QuestStep newStep, QuestHelpe public void updateTextToFaded(QuestStep questStep) { - if (steps.get(questStep) != null) + if (stepTextPanes.get(questStep) != null) { - steps.get(questStep).setForeground(Color.DARK_GRAY); - steps.get(questStep).setToolTipText(questStep.getFadeCondition().getDisplayText()); + stepTextPanes.get(questStep).setForeground(Color.DARK_GRAY); + stepTextPanes.get(questStep).setToolTipText(questStep.getFadeCondition().getDisplayText()); } } public void updateTextToUnfaded(QuestStep questStep) { - if (steps.get(questStep) != null) + if (stepTextPanes.get(questStep) != null) { - steps.get(questStep).setForeground(Color.LIGHT_GRAY); - steps.get(questStep).setToolTipText(null); + stepTextPanes.get(questStep).setForeground(Color.LIGHT_GRAY); + stepTextPanes.get(questStep).setToolTipText(null); } } @@ -302,14 +518,14 @@ public void updateHighlight(QuestStep currentStep) { expand(); - if (steps.get(lastHighlightedStep) != null) + if (stepTextPanes.get(lastHighlightedStep) != null) { - steps.get(lastHighlightedStep).setForeground(Color.LIGHT_GRAY); + stepTextPanes.get(lastHighlightedStep).setForeground(Color.LIGHT_GRAY); } - if (steps.get(currentStep) != null) + if (stepTextPanes.get(currentStep) != null) { - steps.get(currentStep).setForeground(ColorScheme.BRAND_ORANGE); + stepTextPanes.get(currentStep).setForeground(ColorScheme.BRAND_ORANGE); headerLabel.setForeground(Color.BLACK); headerPanel.setBackground(ColorScheme.BRAND_ORANGE); viewControls.setBackground(ColorScheme.BRAND_ORANGE); @@ -329,9 +545,9 @@ public void removeHighlight() headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); leftTitleContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - if (steps.get(currentlyActiveQuestSidebarStep()) != null) + if (stepTextPanes.get(currentlyActiveQuestSidebarStep()) != null) { - steps.get(currentlyActiveQuestSidebarStep()).setForeground(Color.LIGHT_GRAY); + stepTextPanes.get(currentlyActiveQuestSidebarStep()).setForeground(Color.LIGHT_GRAY); } collapse(); @@ -430,19 +646,24 @@ public void updateRequirements(Client client) } updateStepVisibility(client); + syncManualSkipCheckboxesFromRequirements(client); } public boolean updateStepVisibility(Client client) { boolean stepVisibilityChanged = false; - for (QuestStep step : steps.keySet()) + for (QuestStep step : stepTextPanes.keySet()) { boolean oldVisibility = step.isShowInSidebar(); boolean newVisibility = step.getConditionToHide() == null || !step.getConditionToHide().check(client); stepVisibilityChanged = stepVisibilityChanged || (oldVisibility != newVisibility); step.setShowInSidebar(newVisibility); - steps.get(step).setVisible(newVisibility); + JPanel row = stepRowPanels.get(step); + if (row != null) + { + row.setVisible(newVisibility); + } } if (stepVisibilityChanged) @@ -463,7 +684,7 @@ protected QuestStep currentlyActiveQuestSidebarStep() public List getIds() { - if (panelDetails.getId() == -1) return List.of(); + if (panelDetails.getId() == Integer.MIN_VALUE) return List.of(); return List.of(panelDetails.getId()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/regionfiltering/RegionFilterPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/regionfiltering/RegionFilterPanel.java new file mode 100644 index 00000000000..2d3a4a1d577 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/regionfiltering/RegionFilterPanel.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2026, Syrif + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.panel.regionfiltering; + +import net.runelite.client.plugins.microbot.questhelper.config.LeagueFiltering; +import net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueRegion; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.util.ImageUtil; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.EnumSet; + +public class RegionFilterPanel extends JPanel +{ + private final EnumSet selectedRegions = EnumSet.noneOf(LeagueRegion.class); + private final Runnable onChanged; + private final SpriteManager spriteManager; + public RegionFilterPanel(SpriteManager spriteManager, Runnable onChanged) + { + super(); + this.spriteManager = spriteManager; + this.onChanged = onChanged; + + setBorder(new EmptyBorder(10, 10, 10, 10)); + setLayout(new GridLayout(0, 3, 7, 7)); + + for (LeagueRegion region : LeagueRegion.values()) + { + add(createRegionButton(region)); + } + } + + private JButton createRegionButton(LeagueRegion region) + { + JButton button = new JButton(); + button.setOpaque(true); + button.setFocusPainted(false); + button.setBackground(ColorScheme.DARKER_GRAY_COLOR); + button.setToolTipText(region.getDisplayName()); + button.setText(region.getDisplayName()); + button.setFont(button.getFont().deriveFont(Font.PLAIN, 9f)); + button.setForeground(Color.GRAY); + button.setMargin(new Insets(4, 2, 4, 2)); + + // Load sprite async on client thread, replace text with icon when ready + spriteManager.getSpriteAsync(region.getSpriteId(), 0, sprite -> { + if (sprite != null) + { + ImageIcon selectedIcon = new ImageIcon(sprite); + ImageIcon deselectedIcon = new ImageIcon(ImageUtil.alphaOffset(sprite, -180)); + button.putClientProperty("selectedIcon", selectedIcon); + button.putClientProperty("deselectedIcon", deselectedIcon); + SwingUtilities.invokeLater(() -> { + button.setText(null); + if (selectedRegions.contains(region)) + { + button.setIcon(selectedIcon); + } + else + { + button.setIcon(deselectedIcon); + } + button.setPreferredSize(new Dimension(sprite.getWidth() + 10, sprite.getHeight() + 10)); + button.revalidate(); + }); + } + }); + + button.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + if (selectedRegions.contains(region)) + { + selectedRegions.remove(region); + updateButtonState(button, false); + } + else + { + selectedRegions.add(region); + updateButtonState(button, true); + } + LeagueFiltering.setSelectedRegions(selectedRegions.isEmpty() ? null : EnumSet.copyOf(selectedRegions)); + onChanged.run(); + } + + @Override + public void mouseEntered(MouseEvent e) + { + button.setBackground(button.getBackground().brighter()); + } + + @Override + public void mouseExited(MouseEvent e) + { + if (selectedRegions.contains(region)) + { + button.setBackground(ColorScheme.BRAND_ORANGE); + } + else + { + button.setBackground(ColorScheme.DARKER_GRAY_COLOR); + } + } + }); + + return button; + } + + private void updateButtonState(JButton button, boolean selected) + { + if (selected) + { + button.setBackground(ColorScheme.BRAND_ORANGE); + ImageIcon selectedIcon = (ImageIcon) button.getClientProperty("selectedIcon"); + if (selectedIcon != null) + { + button.setIcon(selectedIcon); + } + else + { + button.setForeground(Color.WHITE); + } + } + else + { + button.setBackground(ColorScheme.DARKER_GRAY_COLOR); + ImageIcon deselectedIcon = (ImageIcon) button.getClientProperty("deselectedIcon"); + if (deselectedIcon != null) + { + button.setIcon(deselectedIcon); + } + else + { + button.setForeground(Color.GRAY); + } + } + } + + public int getSelectedCount() + { + return selectedRegions.size(); + } + + /** + * Clears all selected regions and resets button states. + */ + public void clearSelection() + { + if (selectedRegions.isEmpty()) + { + return; + } + selectedRegions.clear(); + LeagueFiltering.setSelectedRegions(null); + for (Component comp : getComponents()) + { + if (comp instanceof JButton) + { + updateButtonState((JButton) comp, false); + } + } + onChanged.run(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java index 552e6bcaadf..ecd46990f18 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java @@ -25,18 +25,14 @@ package net.runelite.client.plugins.microbot.questhelper.playerquests.bikeshedder; import com.google.common.collect.ImmutableMap; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; +import net.runelite.client.plugins.microbot.questhelper.collections.KeyringCollection; import net.runelite.client.plugins.microbot.questhelper.collections.TeleportCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SpellbookRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; @@ -46,6 +42,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.client.plugins.microbot.questhelper.steps.widget.NormalSpells; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; import java.util.ArrayList; import java.util.Arrays; @@ -91,13 +93,95 @@ public class BikeShedder extends BasicQuestHelper private ItemRequirement anyCoins; private ItemStep getCoins; + // Sailing + private NpcStep talkToNpcOnBoat; + private NpcStep talkToKlarenceFromShip; + private ObjectStep useSalvagingHook; + private ObjectStep useObjectOffBoat; + private ZoneRequirement onBoat1; + private ZoneRequirement onBoat2; + private ZoneRequirement onBoat3; + private ZoneRequirement onBoat4; + + // Keyring + private ItemRequirement dustyKeyItem; + private KeyringRequirement dustyKeyKeyRing; + private DetailedQuestStep keyringStep; + @Override public Map loadSteps() { + setupRequirements(); + var lumbridge = new Zone(new WorldPoint(3217, 3210, 0), new WorldPoint(3226, 3228, 0)); var outsideLumbridge = new ZoneRequirement(false, lumbridge); moveToLumbridge.setHighlightZone(lumbridge); var steps = new ConditionalStep(this, confuseHans); + + // aldarin bank + var plankNoBank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); + { + // Do not check bank for plank + var plankStep = new DetailedQuestStep(this, "Plank requirement will not check bank", plankNoBank); + var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will not check bank (Requirement used as conditional step passed)", plankNoBank); + var cPlankStep = new ConditionalStep(this, plankStep); + cPlankStep.addStep(plankNoBank, plankStepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2926, 0)), cPlankStep); + } + + { + // Check bank for plank using alsoCheckBank + var plank = plankNoBank.alsoCheckBank(); + plank.setName("Plank (check bank 1)"); + var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 1", plank); + var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 1 (Requirement used as conditional step passed)", plank); + var cPlankStep = new ConditionalStep(this, plankStep); + cPlankStep.addStep(plank, plankStepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2925, 0)), cPlankStep); + } + + { + // Check bank for plank using setShouldCheckBank + var plank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); + plank.setShouldCheckBank(true); + plank.setName("Plank (check bank 2)"); + var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 2", plank); + var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 2 (Requirement used as conditional step passed)", plank); + var cPlankStep = new ConditionalStep(this, plankStep); + cPlankStep.addStep(plank, plankStepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2924, 0)), cPlankStep); + } + + // mistrock bank + { + // does not need to be equipped + var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); + var step = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped", blueWizardHat); + var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped (Requirement used as conditional step passed)", blueWizardHat); + var cStep = new ConditionalStep(this, step); + cStep.addStep(blueWizardHat, stepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1383, 2866, 0)), cStep); + } + + { + // must be equipped + var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); + blueWizardHat.setMustBeEquipped(true); + var step = new DetailedQuestStep(this, "Blue wizard hat, must be equipped", blueWizardHat); + var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, must be equipped (Requirement used as conditional step passed)", blueWizardHat); + var cStep = new ConditionalStep(this, step); + cStep.addStep(blueWizardHat, stepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1382, 2866, 0)), cStep); + } + + // Boat + steps.addStep(onBoat1, talkToNpcOnBoat); + steps.addStep(onBoat2, talkToKlarenceFromShip); + steps.addStep(onBoat3, useSalvagingHook); + steps.addStep(onBoat4, useObjectOffBoat); + + steps.addStep(new ZoneRequirement(new WorldPoint(2655, 3286, 0)), keyringStep); + steps.addStep(byStaircaseInSunrisePalace, goDownstairsInSunrisePalace); steps.addStep(outsideLumbridge, moveToLumbridge); steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3218, 0)), haveRunes); @@ -108,6 +192,7 @@ public Map loadSteps() steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3216, 0)), getCoins); steps.addStep(conditionalRequirementZoneRequirement, conditionalRequirementLookAtCoins); steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3221, 0)), lookAtCooksAssistant); + return new ImmutableMap.Builder() .put(-1, steps) .build(); @@ -174,22 +259,86 @@ protected void setupRequirements() var fire30 = new ItemRequirement("Fire runes", ItemID.FIRERUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 63)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 63)); var air30 = new ItemRequirement("Air runes", ItemID.AIRRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 66)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 66)); var water30 = new ItemRequirement("Water runes", ItemID.WATERRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 56)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 56)); var earth30 = new ItemRequirement("Earth runes", ItemID.EARTHRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 60)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 60)); elemental30Unique = new ItemRequirements(LogicType.OR, "Elemental runes as ItemRequirements OR", air30, water30, earth30, fire30); elemental30Unique.addAlternates(ItemID.FIRERUNE, ItemID.EARTHRUNE, ItemID.AIRRUNE); elemental30 = new ItemRequirement("Elemental rune as ItemRequirement", List.of(ItemID.AIRRUNE, ItemID.EARTHRUNE, ItemID.WATERRUNE, - ItemID.FIRERUNE), 30); + ItemID.FIRERUNE), 30); elemental30.setTooltip("You have potato"); haveRunes = new DetailedQuestStep(this, "Compare rune checks for ItemRequirement and ItemRequirements with OR.", elemental30, elemental30Unique); anyCoins = new ItemRequirement("Coins", ItemCollections.COINS); getCoins = new ItemStep(this, new WorldPoint(3224, 3215, 0), "Get coins", anyCoins); + + // Sailing + + var zones1 = new Zone[] { + new Zone(new WorldPoint(3843, 6402, 1), new WorldPoint(3844, 6402, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6389, 1), new WorldPoint(3876, 6389, 1)), + new Zone(new WorldPoint(3842, 6365, 1), new WorldPoint(3860, 6365, 1)), + new Zone(new WorldPoint(3843, 6354, 1), new WorldPoint(3884, 6354, 1)) + }; + onBoat1 = new ZoneRequirement(zones1); + + var zones2 = new Zone[] { + new Zone(new WorldPoint(3843, 6403, 1), new WorldPoint(3844, 6403, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6390, 1), new WorldPoint(3876, 6390, 1)), + new Zone(new WorldPoint(3842, 6366, 1), new WorldPoint(3860, 6366, 1)), + new Zone(new WorldPoint(3843, 6355, 1), new WorldPoint(3884, 6355, 1)) + }; + onBoat2 = new ZoneRequirement(zones2); + + var zones3 = new Zone[] { + new Zone(new WorldPoint(3843, 6404, 1), new WorldPoint(3844, 6404, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6391, 1), new WorldPoint(3876, 6391, 1)), + new Zone(new WorldPoint(3842, 6367, 1), new WorldPoint(3860, 6367, 1)), + new Zone(new WorldPoint(3843, 6356, 1), new WorldPoint(3884, 6356, 1)) + }; + onBoat3 = new ZoneRequirement(zones3); + + var zones4 = new Zone[] { + new Zone(new WorldPoint(3843, 6405, 1), new WorldPoint(3844, 6405, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6312, 1), new WorldPoint(3876, 6392, 1)), + new Zone(new WorldPoint(3842, 6368, 1), new WorldPoint(3860, 6368, 1)), + new Zone(new WorldPoint(3843, 6357, 1), new WorldPoint(3884, 6357, 1)) + }; + onBoat4 = new ZoneRequirement(zones4); + + talkToNpcOnBoat = new NpcStep(this, NpcID.SAILING_INTRO_ANNE_BOAT, "Talk to a ship NPC."); + List shipNpcs = new ArrayList<>(); + for (int i = NpcID.SAILING_CREW_GENERIC_1_WORLD; i <= NpcID.SAILING_CREW_GHOST_JENKINS_CARGO_3; i++) + { + shipNpcs.add(i); + } + talkToNpcOnBoat.addHighlightZones(zones1); + talkToNpcOnBoat.addAlternateNpcs(shipNpcs.toArray(new Integer[0])); + + talkToKlarenceFromShip = new NpcStep(this, NpcID.KLARENSE, new WorldPoint(3046, 3205, 0), "Klarence off the ship."); + talkToKlarenceFromShip.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); + talkToKlarenceFromShip.addHighlightZones(zones2); + List salvagingHookIds = new ArrayList<>(); + for (int i = ObjectID.SAILING_INTRO_SALVAGING_HOOK; i <= ObjectID.SALVAGING_HOOK_LARGE_DRAGON_B; i++) + { + salvagingHookIds.add(i); + } + + useSalvagingHook = new ObjectStep(this, ObjectID.SAILING_INTRO_SALVAGING_HOOK, "Use the salvaging hook."); + useSalvagingHook.addAlternateObjects(salvagingHookIds.toArray(new Integer[0])); + useSalvagingHook.addHighlightZones(zones3); + + useObjectOffBoat = new ObjectStep(this, ObjectID.DRAGONSHIPGANGPLANK_ON, new WorldPoint(3047, 3205, 0), "Click Klarense's gangplank."); + useObjectOffBoat.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); + useObjectOffBoat.addHighlightZones(zones4); + + dustyKeyItem = new ItemRequirement("Dusty key (ItemReq)", ItemID.DUSTY_KEY); + dustyKeyKeyRing = new KeyringRequirement("Dusty key (KeyRingReq)", KeyringCollection.DUSTY_KEY); + keyringStep = new DetailedQuestStep(this, "We need the dusty key", dustyKeyItem, dustyKeyKeyRing); } @Override @@ -211,6 +360,8 @@ public List getPanels() panels.add(new PanelDetails("Item step", List.of(getCoins), List.of(anyCoins))); panels.add(new PanelDetails("Quest state", List.of(lookAtCooksAssistant), List.of(lookAtCooksAssistantRequirement, lookAtCooksAssistantTextRequirement))); panels.add(new PanelDetails("Ensure staircase upstairs in Sunrise Palace is highlighted", List.of(goDownstairsInSunrisePalace), List.of())); + panels.add(new PanelDetails("Sailing", List.of(talkToNpcOnBoat, talkToKlarenceFromShip, useSalvagingHook, useObjectOffBoat), List.of())); + panels.add(new PanelDetails("Key ring", List.of(keyringStep), List.of(dustyKeyItem, dustyKeyKeyRing))); return panels; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/cookshelper/CooksHelper.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/cookshelper/CooksHelper.java deleted file mode 100644 index 50bc5a9b56f..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/cookshelper/CooksHelper.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2023, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.playerquests.cookshelper; - -import net.runelite.api.QuestState; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; -import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.PlayerMadeQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; -import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.PlayerQuestStateRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.RuneliteConfigSetter; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.dialog.RuneliteDialogStep; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.dialog.RuneliteObjectDialogStep; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.dialog.RunelitePlayerDialogStep; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.FaceAnimationIDs; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.FakeItem; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.FakeNpc; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.ReplacedObject; -import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; -import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.client.plugins.microbot.questhelper.steps.TileStep; -import net.runelite.client.plugins.microbot.questhelper.steps.playermadesteps.RuneliteObjectStep; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class CooksHelper extends PlayerMadeQuestHelper -{ - private RuneliteObjectStep talkToCook, talkToHopleez, grabCabbage, returnToHopleez; - - private DetailedQuestStep standNextToCook, standNextToHopleez, standNextToHopleez2; - - private Requirement nearCook, nearHopleez; - - private FakeNpc cooksCousin, hopleez; - - private FakeItem cabbage; - - private PlayerQuestStateRequirement talkedToCooksCousin, talkedToHopleez, displayCabbage, pickedCabbage; - - @Override - public QuestStep loadStep() - { - itemWidget = ItemID.TOP_HAT; - rotationX = 100; - zoom = 200; - - setupRequirements(); - createRuneliteObjects(); - setupSteps(); - - PlayerQuestStateRequirement req = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 0); - - ConditionalStep questSteps = new ConditionalStep(this, standNextToCook); - questSteps.addStep(req.getNewState(4), new DetailedQuestStep(this, "Quest completed!")); - questSteps.addStep(new Conditions(req.getNewState(3), nearHopleez), returnToHopleez); - questSteps.addStep(req.getNewState(3), standNextToHopleez2); - questSteps.addStep(req.getNewState(2), grabCabbage); - questSteps.addStep(new Conditions(req.getNewState(1), nearHopleez), talkToHopleez); - questSteps.addStep(req.getNewState(1), standNextToHopleez); - questSteps.addStep(nearCook, talkToCook); - - // We want something which can be added to a requirement, which - - // Don't save to config until helper closes/client closing? - - return questSteps; - } - - @Override - protected void setupRequirements() - { - // NPCs should persist through quest steps unless actively removed? Dialog should be conditional on step (sometimes) - // Hide/show NPCs/the runelite character when NPCs go on it/you go over it - // Handle cancelling dialog boxes (even just moving a tile away should remove for example) - // Properly handle removing NPC from screen when changing floors and such - // Work out how to do proper priority on the npcs being clicked - // Wandering NPCs? - // Objects + items (basically same as NPCs) - talkedToCooksCousin = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 1, Operation.GREATER_EQUAL); - talkedToHopleez = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 2, Operation.GREATER_EQUAL); - pickedCabbage = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 3, Operation.GREATER_EQUAL); - displayCabbage = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 2); - nearCook = new ZoneRequirement(new Zone(new WorldPoint(3206, 3212, 0), new WorldPoint(3212, 3218, 0))); - nearHopleez = new ZoneRequirement(new Zone(new WorldPoint(3232, 3212, 0), new WorldPoint(3238, 3218, 0))); - } - - public void setupSteps() - { - // TODO: Need a way to define the groupID of a runelite object to be a quest step without it being stuck - // Add each step's groupID as a sub-group - - talkToCook = new RuneliteObjectStep(this, cooksCousin, "Talk to the Lumbridge Cook's Cousin."); - standNextToCook = new TileStep(this, new WorldPoint(3210, 3215, 0), "Talk to the Lumbridge Cook's Cousin."); - talkToCook.addSubSteps(standNextToCook); - - talkToHopleez = new RuneliteObjectStep(this, hopleez, "Talk to Hopleez east of Lumbridge Castle."); - standNextToHopleez = new TileStep(this, new WorldPoint(3236, 3215, 0), "Talk to Hopleez east of Lumbridge Castle."); - talkToHopleez.addSubSteps(standNextToHopleez); - - grabCabbage = new RuneliteObjectStep(this, cabbage, "Get the cabbage to the north of Hopleez, outside the Sheared Ram."); - - returnToHopleez = new RuneliteObjectStep(this, hopleez, "Return to Hopleez east of Lumbridge Castle."); - standNextToHopleez2 = new DetailedQuestStep(this, new WorldPoint(3235, 3216, 0), "Return to Hopleez east of Lumbridge Castle."); - returnToHopleez.addSubSteps(standNextToHopleez2); - } - - private void setupCooksCousin() - { - // Cook's Cousin - cooksCousin = runeliteObjectManager.createFakeNpc(this.toString(), client.getNpcDefinition(NpcID.POH_SERVANT_COOK_WOMAN).getModels(), new WorldPoint(3209, 3215, 0), 808); - cooksCousin.setName("Cook's Cousin"); - cooksCousin.setFace(4626); - cooksCousin.setExamine("The Cook's cousin."); - cooksCousin.addTalkAction(runeliteObjectManager); - cooksCousin.addExamineAction(runeliteObjectManager); - - QuestRequirement hasDoneCooksAssistant = new QuestRequirement(QuestHelperQuest.COOKS_ASSISTANT, QuestState.FINISHED); - - RuneliteObjectDialogStep dontMeetReqDialog = cooksCousin.createDialogStepForNpc("Come talk to me once you've helped my cousin out."); - cooksCousin.addDialogTree(null, dontMeetReqDialog); - - RuneliteDialogStep dialog = cooksCousin.createDialogStepForNpc("Hey, you there! You helped out my cousin before right?"); - dialog.addContinueDialog(new RunelitePlayerDialogStep(client, "I have yeah, what's wrong? Does he need some more eggs? Maybe I can just get him a chicken instead?")) - .addContinueDialog(cooksCousin.createDialogStepForNpc("No no, nothing like that. Have you seen that terribly dressed person outside the courtyard?", FaceAnimationIDs.FRIENDLY_QUESTIONING)) - .addContinueDialog(cooksCousin.createDialogStepForNpc("I don't know who they are, but can you please get them to move along please?", FaceAnimationIDs.FRIENDLY_QUESTIONING)) - .addContinueDialog(cooksCousin.createDialogStepForNpc("They seem to be attracting more troublemakers....")) - .addContinueDialog(new RunelitePlayerDialogStep(client, "You mean Hatius? If so it'd be my pleasure.").setStateProgression(talkedToCooksCousin.getSetter())); - cooksCousin.addDialogTree(hasDoneCooksAssistant, dialog); - - RuneliteObjectDialogStep dialogV2 = cooksCousin.createDialogStepForNpc("That terribly dressed person is still outside the castle, go talk to them!"); - cooksCousin.addDialogTree(talkedToCooksCousin, dialogV2); - } - - private void setupHopleez() - { - // Hopleez - hopleez = runeliteObjectManager.createFakeNpc(this.toString(), client.getNpcDefinition(NpcID.ZEAH_DEFENCE_PURE).getModels(), new WorldPoint(3235, 3215, 0), 808); - hopleez.setName("Hopleez"); - hopleez.setFace(7481); - hopleez.setExamine("He was here first."); - hopleez.addTalkAction(runeliteObjectManager); - hopleez.addExamineAction(runeliteObjectManager); - - // Dialog - RuneliteDialogStep hopleezDialogPreQuest = hopleez.createDialogStepForNpc("Hop noob."); - hopleezDialogPreQuest.addContinueDialog(new RunelitePlayerDialogStep(client, "What? Also, what are you wearing?")) - .addContinueDialog(hopleez.createDialogStepForNpc("Hop NOOB.")); - hopleez.addDialogTree(null, hopleezDialogPreQuest); - - RuneliteDialogStep hopleezDialog1 = hopleez.createDialogStepForNpc("Hop noob.", FaceAnimationIDs.ANNOYED); - hopleezDialog1.addContinueDialog(new RunelitePlayerDialogStep(client, "What? The Cook's Cousin sent me to see what you were doing here.", FaceAnimationIDs.QUIZZICAL)) - .addContinueDialog(hopleez.createDialogStepForNpc("One moment I was relaxing in Zeah killing some crabs. I closed my eyes for a second, and suddenly I'm here.")) - .addContinueDialog(hopleez.createDialogStepForNpc("People would always try to steal my spot in Zeah, and it seems it's no different here!", FaceAnimationIDs.ANNOYED)) - .addContinueDialog(hopleez.createDialogStepForNpc("Not only is this guy crashing me, but he's trying to outdress me too!", FaceAnimationIDs.ANNOYED_2)) - .addContinueDialog(new RunelitePlayerDialogStep(client, "Hatius? I'm pretty sure he's been here much longer than you....", FaceAnimationIDs.QUESTIONING)) - .addContinueDialog(hopleez.createDialogStepForNpc("I swear he wasn't here when I first arrived, I went away for a second and suddenly he's here!", FaceAnimationIDs.ANNOYED_2)) - .addContinueDialog(hopleez.createDialogStepForNpc("Help me teach him a lesson, get me that old cabbage from outside the The Sheared Ram.")) - .addContinueDialog(new RunelitePlayerDialogStep(client, "Umm, sure....", talkedToHopleez.getSetter())); - hopleez.addDialogTree(talkedToCooksCousin, hopleezDialog1); - - - RuneliteDialogStep hopleezWaitingForCabbageDialog = hopleez.createDialogStepForNpc("Get me that cabbage!"); - hopleez.addDialogTree(talkedToHopleez, hopleezWaitingForCabbageDialog); - - RuneliteConfigSetter endQuest = new RuneliteConfigSetter(configManager, getQuest().getPlayerQuests().getConfigValue(), "4"); - RuneliteDialogStep hopleezGiveCabbageDialog = hopleez.createDialogStepForNpc("Have you got the cabbage?"); - hopleezGiveCabbageDialog - .addContinueDialog(new RunelitePlayerDialogStep(client, "I have! Here you go, why do you need it?")) - .addContinueDialog(hopleez.createDialogStepForNpc("Nice! Now let's sort out this crasher...")) - .addContinueDialog(hopleez.createDialogStepForNpc("Oi noob, take this!")) - .addContinueDialog(new RuneliteObjectDialogStep("Hatius Cosaintus", "What on earth?", NpcID.HATIUS_LUMBRIDGE_DIARY).setStateProgression(endQuest)); - hopleez.addDialogTree(pickedCabbage, hopleezGiveCabbageDialog); - } - - private void setupCabbage() - { - // Old cabbage - cabbage = runeliteObjectManager.createFakeItem(this.toString(), new int[]{ 8196 }, new WorldPoint(3231, 3235, 0), -1); - cabbage.setName("Old cabbage"); - cabbage.setExamine("A mouldy looking cabbage."); - cabbage.addExamineAction(runeliteObjectManager); - cabbage.setDisplayRequirement(displayCabbage); - cabbage.addTakeAction(runeliteObjectManager, new RuneliteConfigSetter(configManager, getQuest().getPlayerQuests().getConfigValue(), "3"), - "You pick up the old cabbage."); - - cabbage.setObjectToRemove(new ReplacedObject(ObjectID.AP_INDICATOR, new WorldPoint(3231, 3235, 0))); - } - - private void createRuneliteObjects() - { - setupCooksCousin(); - setupHopleez(); - setupCabbage(); - } - - @Override - public List getGeneralRequirements() - { - return Collections.singletonList(new QuestRequirement(QuestHelperQuest.COOKS_ASSISTANT, QuestState.FINISHED)); - } - - @Override - public List getUnlockRewards() - { - return Collections.singletonList( - new UnlockReward("A replacement for Hatius Cosaintus") - ); - } - - @Override - public List getPanels() - { - List allSteps = new ArrayList<>(); - PanelDetails helpingTheCousinSteps = new PanelDetails("Helping the Cook's Cousin", Arrays.asList(talkToCook, talkToHopleez, grabCabbage, returnToHopleez)); - allSteps.add(helpingTheCousinSteps); - - return allSteps; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java index 18a590d939a..37e5a9a6878 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java @@ -24,12 +24,14 @@ */ package net.runelite.client.plugins.microbot.questhelper.questhelpers; +import com.google.gson.Gson; import com.google.inject.Binder; import com.google.inject.CreationException; import com.google.inject.Injector; import com.google.inject.Module; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.panel.ManualStepSkipStore; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questinfo.ExternalQuestResources; import net.runelite.client.plugins.microbot.questhelper.questinfo.HelperConfig; @@ -77,6 +79,9 @@ public abstract class QuestHelper implements Module, QuestDebugRenderer @Inject private EventBus eventBus; + @Inject + public Gson gson; + @Getter private QuestStep currentStep; @@ -84,6 +89,14 @@ public abstract class QuestHelper implements Module, QuestDebugRenderer @Setter private QuestHelperQuest quest; + /** + * When set (e.g. construct preview / imported player guides), used for sidebar and step overlays + * instead of {@link QuestHelperQuest#getName()} from {@link #quest}. + */ + @Getter + @Setter + private String playerFacingQuestName; + @Setter private Injector injector; @@ -118,6 +131,49 @@ public void removeRuneliteObjects() runeliteObjectManager.removeGroupAndSubgroups(toString()); } + /** + * Human-readable quest title for UI (sidebar, overlays). Uses {@link #playerFacingQuestName} when set, + * otherwise the linked {@link QuestHelperQuest} name, otherwise a generic label. + */ + public String getDisplayedQuestName() + { + if (playerFacingQuestName != null && !playerFacingQuestName.isBlank()) + { + return playerFacingQuestName.trim(); + } + if (quest != null) + { + return quest.getName(); + } + return "Quest Helper"; + } + + /** + * Persists a manual skip flag for one step (sidebar checkbox) and notifies the helper to refresh branch logic. + */ + public void notifyManualSidebarSkipChanged(String persistenceKey, boolean skipped) + { + if (persistenceKey == null || persistenceKey.isBlank()) + { + return; + } + ManualStepSkipStore.put(configManager, gson, getDisplayedQuestName(), persistenceKey, skipped); + onManualSidebarSkipsPersistedChanged(); + } + + public void resetAllManualSidebarSkips() + { + ManualStepSkipStore.clearAll(configManager, getDisplayedQuestName()); + onManualSidebarSkipsPersistedChanged(); + } + + /** + * Hook for helpers that merge persisted skips with runtime state (e.g. maker preview). + */ + protected void onManualSidebarSkipsPersistedChanged() + { + } + public abstract boolean updateQuest(); public void debugStartup(QuestHelperConfig config) @@ -218,9 +274,9 @@ public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, Pane .build() ); panelComponent.getChildren().add(LineComponent.builder() - .left(getQuest().getName()) + .left(getDisplayedQuestName()) .leftColor(getConfig().debugColor()) - .right(getVar() + "") + .right(getQuest() != null ? String.valueOf(getVar()) : "—") .rightColor(getConfig().debugColor()) .build() ); @@ -228,6 +284,10 @@ public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, Pane public int getVar() { + if (quest == null) + { + return 0; + } return quest.getVar(client); } @@ -240,11 +300,6 @@ public boolean hasQuestStateBecomeFinished() return questStateEnteredFinished; } - public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) - { - - } - protected void setupZones() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java index 17b6e155644..e20412742ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java @@ -28,6 +28,7 @@ public enum ExternalQuestResources SHEEP_SHEARER("https://oldschool.runescape.wiki/w/Sheep_Shearer"), SHIELD_OF_ARRAV_PHOENIX_GANG("https://oldschool.runescape.wiki/w/Shield_of_Arrav"), SHIELD_OF_ARRAV_BLACK_ARM_GANG("https://oldschool.runescape.wiki/w/Shield_of_Arrav"), + THE_IDES_OF_MILK("https://oldschool.runescape.wiki/w/The_Ides_of_Milk"), VAMPYRE_SLAYER("https://oldschool.runescape.wiki/w/Vampyre_Slayer"), WITCHS_POTION("https://oldschool.runescape.wiki/w/Witch%27s_Potion"), X_MARKS_THE_SPOT("https://oldschool.runescape.wiki/w/X_Marks_the_Spot"), @@ -192,6 +193,7 @@ public enum ExternalQuestResources PRYING_TIMES("https://oldschool.runescape.wiki/w/Prying_Times"), CURRENT_AFFAIRS("https://oldschool.runescape.wiki/w/Current_Affairs"), TROUBLED_TORTUGANS("https://oldschool.runescape.wiki/w/Troubled_Tortugans"), + THE_RED_REEF("https://oldschool.runescape.wiki/w/The_Red_Reef"), //Miniquests ENTER_THE_ABYSS("https://oldschool.runescape.wiki/w/Enter_the_Abyss"), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueQuestRegions.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueQuestRegions.java new file mode 100644 index 00000000000..44243f9b90b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueQuestRegions.java @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2026, Syrif + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.questinfo; + +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.Map; + +import static net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueRegion.*; +import static net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest.*; + +/** + * Maps quests to the league regions required to complete them. + * TODO: Quests with no mapping require manual curation. + * Unmapped quests always pass the league filter. + * Update this class per league season. + */ +public class LeagueQuestRegions +{ + private static final Map> QUEST_REGIONS = new EnumMap<>(QuestHelperQuest.class); + + static + { + // F2P quests + put(X_MARKS_THE_SPOT, ASGARNIA); + put(THE_CORSAIR_CURSE, ASGARNIA, KANDARIN); + put(MISTHALIN_MYSTERY, MISTHALIN); + put(PIRATES_TREASURE, ASGARNIA); + put(GOBLIN_DIPLOMACY, ASGARNIA); + put(THE_KNIGHTS_SWORD, ASGARNIA); + put(WITCHS_POTION, ASGARNIA); + put(BLACK_KNIGHTS_FORTRESS, ASGARNIA); + put(DORICS_QUEST, ASGARNIA); + put(PRINCE_ALI_RESCUE, DESERT); + put(IMP_CATCHER, MISTHALIN); + put(VAMPYRE_SLAYER, MISTHALIN); + put(ERNEST_THE_CHICKEN, MISTHALIN); + put(THE_RESTLESS_GHOST, MISTHALIN); + put(SHEEP_SHEARER, MISTHALIN); + put(SHIELD_OF_ARRAV_PHOENIX_GANG, MISTHALIN); + put(SHIELD_OF_ARRAV_BLACK_ARM_GANG, MISTHALIN); + put(DEMON_SLAYER, MISTHALIN); + put(ROMEO__JULIET, MISTHALIN); + put(COOKS_ASSISTANT, MISTHALIN); + + // Members quests + put(WITCHS_HOUSE, ASGARNIA); + put(HEROES_QUEST, ASGARNIA); + put(SCORPION_CATCHER, ASGARNIA, KANDARIN, MISTHALIN); + put(FISHING_CONTEST, KANDARIN); + put(TRIBAL_TOTEM, KARAMJA, KANDARIN); + put(MONKS_FRIEND, KANDARIN); + put(TEMPLE_OF_IKOV, KANDARIN, MISTHALIN); + put(CLOCK_TOWER, KANDARIN); + put(FIGHT_ARENA, KANDARIN); + put(HAZEEL_CULT, KANDARIN); + put(SHEEP_HERDER, KANDARIN); + put(PLAGUE_CITY, KANDARIN); + put(SEA_SLUG, KANDARIN); + put(WATERFALL_QUEST, KANDARIN); + put(OBSERVATORY_QUEST, KANDARIN); + put(DWARF_CANNON, ASGARNIA, KANDARIN); + put(GERTRUDES_CAT, MISTHALIN); + put(BIG_CHOMPY_BIRD_HUNTING, KANDARIN); + put(TAI_BWO_WANNAI_TRIO, KARAMJA); + put(SHADES_OF_MORTTON, MORYTANIA); + put(THRONE_OF_MISCELLANIA, FREMENNIK); + put(HAUNTED_MINE, MORYTANIA); + put(TROLL_ROMANCE, ASGARNIA, KANDARIN); + put(GHOSTS_AHOY, MORYTANIA); + put(BETWEEN_A_ROCK, ASGARNIA, FREMENNIK, KANDARIN); + put(THE_GOLEM, DESERT); + put(THE_GIANT_DWARF, ASGARNIA, FREMENNIK); + put(RECRUITMENT_DRIVE, ASGARNIA); + put(FORGETTABLE_TALE, ASGARNIA, FREMENNIK, KANDARIN); + put(A_TAIL_OF_TWO_CATS, ASGARNIA, DESERT); + put(WANTED, ASGARNIA, MORYTANIA, WILDERNESS); + put(SHADOW_OF_THE_STORM, DESERT); + put(MAKING_HISTORY, FREMENNIK, KANDARIN, MORYTANIA); + put(SPIRITS_OF_THE_ELID, DESERT); + put(DEVIOUS_MINDS, ASGARNIA, MORYTANIA, WILDERNESS); + put(THE_HAND_IN_THE_SAND, ASGARNIA, KANDARIN); + put(THE_SLUG_MENACE, ASGARNIA, KANDARIN); // also needs Misthalin OR Desert OR Wilderness for altars + put(ELEMENTAL_WORKSHOP_II, MISTHALIN, KANDARIN); + put(ENLIGHTENED_JOURNEY, ASGARNIA); + put(EAGLES_PEAK, KANDARIN); + put(ANIMAL_MAGNETISM, ASGARNIA, MORYTANIA); + put(CONTACT, DESERT); + put(THE_FREMENNIK_ISLES, FREMENNIK); + put(WHAT_LIES_BELOW, DESERT, WILDERNESS); + put(OLAFS_QUEST, FREMENNIK); + put(ANOTHER_SLICE_OF_HAM, ASGARNIA, FREMENNIK); + put(GRIM_TALES, ASGARNIA); + put(BIOHAZARD, ASGARNIA, KANDARIN); + put(TOWER_OF_LIFE, KANDARIN); + put(LAND_OF_THE_GOBLINS, ASGARNIA, FREMENNIK, KANDARIN); + put(ZOGRE_FLESH_EATERS, KANDARIN); + put(CLIENT_OF_KOUREND, KOUREND); + put(THE_QUEEN_OF_THIEVES, KOUREND); + put(THE_DEPTHS_OF_DESPAIR, KOUREND); + put(A_TASTE_OF_HOPE, MORYTANIA); + put(TALE_OF_THE_RIGHTEOUS, KOUREND); + put(THE_ASCENT_OF_ARCEUUS, KOUREND); + put(THE_FORSAKEN_TOWER, KOUREND); + put(THE_FREMENNIK_EXILES, FREMENNIK); + put(SINS_OF_THE_FATHER, MORYTANIA); + put(A_PORCINE_OF_INTEREST, ASGARNIA); + put(GETTING_AHEAD, KOUREND); + put(A_NIGHT_AT_THE_THEATRE, MORYTANIA); + put(A_KINGDOM_DIVIDED, KOUREND); + put(BENEATH_CURSED_SANDS, DESERT); + put(SLEEPING_GIANTS, DESERT); + put(THE_GARDEN_OF_DEATH, KOUREND); + put(THE_PATH_OF_GLOUPHRIE, KANDARIN); + put(CHILDREN_OF_THE_SUN, MISTHALIN); + put(AT_FIRST_LIGHT, VARLAMORE); + put(PERILOUS_MOON, VARLAMORE); + put(THE_RIBBITING_TALE_OF_A_LILY_PAD_LABOUR_DISPUTE, VARLAMORE); + put(THE_HEART_OF_DARKNESS, VARLAMORE); + put(DEATH_ON_THE_ISLE, VARLAMORE); + put(MEAT_AND_GREET, VARLAMORE); + put(ETHICALLY_ACQUIRED_ANTIQUITIES, ASGARNIA, VARLAMORE); + put(THE_FINAL_DAWN, VARLAMORE); + put(SHADOWS_OF_CUSTODIA, VARLAMORE); + put(SCRAMBLED, VARLAMORE); + put(A_SOULS_BANE, MISTHALIN); + put(RAG_AND_BONE_MAN_I, MISTHALIN, KARAMJA); + put(ROYAL_TROUBLE, FREMENNIK); + put(DEATH_TO_THE_DORGESHUUN, MISTHALIN); + + put(BELOW_ICE_MOUNTAIN, ASGARNIA, MISTHALIN); + put(BIG_CHOMPY_BIRD_HUNTING, KANDARIN); + put(CABIN_FEVER, MORYTANIA); + put(COLD_WAR, KANDARIN, FREMENNIK); + put(THE_CURSE_OF_ARRAV, DESERT, MISTHALIN, ASGARNIA); + put(DARKNESS_OF_HALLOWVALE, MISTHALIN, MORYTANIA); + put(DEFENDER_OF_VARROCK, MISTHALIN); + put(DESERT_TREASURE, DESERT, MISTHALIN, KANDARIN, ASGARNIA, MORYTANIA); + put(ENAKHRAS_LAMENT, DESERT); + put(THE_FEUD, DESERT); + put(THE_GREAT_BRAIN_ROBBERY, MORYTANIA, ASGARNIA); + put(HORROR_FROM_THE_DEEP, FREMENNIK, KANDARIN); + put(THE_IDES_OF_MILK, MISTHALIN); + put(IN_AID_OF_THE_MYREQUE, MISTHALIN, MORYTANIA); + put(IN_SEARCH_OF_THE_MYREQUE, MORYTANIA); + put(THE_LOST_TRIBE, MISTHALIN, ASGARNIA); + put(MAKING_FRIENDS_WITH_MY_ARM, MISTHALIN, FREMENNIK); + put(MOUNTAIN_DAUGHTER, FREMENNIK, KANDARIN); + put(MOURNINGS_END_PART_I, KANDARIN, TIRANNWN, ASGARNIA); + put(MOURNINGS_END_PART_II, KANDARIN, TIRANNWN); + put(MY_ARMS_BIG_ADVENTURE, ASGARNIA, KARAMJA); + put(RAG_AND_BONE_MAN_II, MISTHALIN, KARAMJA, KANDARIN, ASGARNIA, MORYTANIA, DESERT); + put(RATCATCHERS, MISTHALIN, KANDARIN, FREMENNIK, ASGARNIA, DESERT); + put(REGICIDE, KANDARIN, TIRANNWN, ASGARNIA); + put(ROVING_ELVES, KANDARIN, TIRANNWN); + put(RUM_DEAL, MORYTANIA); + put(SECRETS_OF_THE_NORTH, KANDARIN, FREMENNIK); + put(SONG_OF_THE_ELVES, TIRANNWN, KANDARIN); + put(TEARS_OF_GUTHIX, MISTHALIN); + // Possibly Wilderness, but only if the abyss rcing area when tele'd there counts as wildy? + put(TEMPLE_OF_THE_EYE, DESERT, MISTHALIN); + put(THE_TOURIST_TRAP, DESERT); + put(WHILE_GUTHIX_SLEEPS, MISTHALIN, ASGARNIA, KANDARIN); + + // put(TROUBLED_TORTUGANS, SEA); + // put(PRYING_TIMES, SEA); + // put(PANDEMONIUM, ASGARNIA, SEA); + // put(CURRENT_AFFAIRS, KANDARIN, SEA); + + // RFD subquests + put(RECIPE_FOR_DISASTER_START, MISTHALIN, FREMENNIK, VARLAMORE); + put(RECIPE_FOR_DISASTER_WARTFACE_AND_BENTNOZE, MISTHALIN, ASGARNIA); + put(RECIPE_FOR_DISASTER_DWARF, MISTHALIN, ASGARNIA, KANDARIN); + put(RECIPE_FOR_DISASTER_EVIL_DAVE, MISTHALIN, DESERT); + put(RECIPE_FOR_DISASTER_PIRATE_PETE, MISTHALIN, KANDARIN); + put(RECIPE_FOR_DISASTER_LUMBRIDGE_GUIDE, MISTHALIN, ASGARNIA, KANDARIN); + put(RECIPE_FOR_DISASTER_SIR_AMIK_VARZE, MISTHALIN, ASGARNIA, FREMENNIK); + put(RECIPE_FOR_DISASTER_MONKEY_AMBASSADOR, MISTHALIN, KANDARIN); + put(RECIPE_FOR_DISASTER_SKRACH_UGLOGWEE, MISTHALIN, KANDARIN); + + // Miniquests + put(ALFRED_GRIMHANDS_BARCRAWL, KANDARIN); + put(BARBARIAN_TRAINING, KARAMJA, KANDARIN); + put(SKIPPY_AND_THE_MOGRES, ASGARNIA); + put(LAIR_OF_TARN_RAZORLOR, MORYTANIA); + put(BEAR_YOUR_SOUL, ASGARNIA, KOUREND); + put(THE_MAGE_ARENA, WILDERNESS); + put(FAMILY_PEST, DESERT, FREMENNIK, KANDARIN); + put(THE_MAGE_ARENA_II, WILDERNESS); + put(IN_SEARCH_OF_KNOWLEDGE, KOUREND); + put(DADDYS_HOME, MISTHALIN); + // THE_FROZEN_DOOR and INTO_THE_TOMBS don't have QuestHelperQuest entries yet + put(HIS_FAITHFUL_SERVANTS, MORYTANIA); + put(VALE_TOTEMS, VARLAMORE); + + // Diaries + put(DESERT_EASY, DESERT); + put(DESERT_MEDIUM, DESERT); + put(DESERT_HARD, DESERT); + put(DESERT_ELITE, DESERT); + + put(FALADOR_EASY, ASGARNIA); + put(FALADOR_MEDIUM, ASGARNIA); + put(FALADOR_HARD, ASGARNIA); + put(FALADOR_ELITE, ASGARNIA); + + put(FREMENNIK_EASY, FREMENNIK); + put(FREMENNIK_MEDIUM, FREMENNIK); + put(FREMENNIK_HARD, FREMENNIK); + put(FREMENNIK_ELITE, FREMENNIK); + + put(ARDOUGNE_EASY, KANDARIN); + put(ARDOUGNE_MEDIUM, KANDARIN); + put(ARDOUGNE_HARD, KANDARIN); + put(ARDOUGNE_ELITE, KANDARIN); + + put(KANDARIN_EASY, KANDARIN); + put(KANDARIN_MEDIUM, KANDARIN); + put(KANDARIN_HARD, KANDARIN); + put(KANDARIN_ELITE, KANDARIN); + + put(KARAMJA_EASY, KARAMJA); + put(KARAMJA_MEDIUM, KARAMJA); + put(KARAMJA_HARD, KARAMJA); + put(KARAMJA_ELITE, KARAMJA); + + put(KOUREND_EASY, KOUREND); + put(KOUREND_MEDIUM, KOUREND); + put(KOUREND_HARD, KOUREND); + put(KOUREND_ELITE, KOUREND); + + put(LUMBRIDGE_EASY, MISTHALIN); + put(LUMBRIDGE_MEDIUM, MISTHALIN); + put(LUMBRIDGE_HARD, MISTHALIN); + put(LUMBRIDGE_ELITE, MISTHALIN); + + put(MORYTANIA_EASY, MORYTANIA); + put(MORYTANIA_MEDIUM, MORYTANIA); + put(MORYTANIA_HARD, MORYTANIA); + put(MORYTANIA_ELITE, MORYTANIA); + + put(VARROCK_EASY, MISTHALIN); + put(VARROCK_MEDIUM, MISTHALIN); + put(VARROCK_HARD, MISTHALIN); + put(VARROCK_ELITE, MISTHALIN); + + put(WESTERN_EASY, KANDARIN, TIRANNWN); + put(WESTERN_MEDIUM, KANDARIN, TIRANNWN); + put(WESTERN_HARD, KANDARIN, TIRANNWN); + put(WESTERN_ELITE, KANDARIN, TIRANNWN); + + put(WILDERNESS_EASY, WILDERNESS); + put(WILDERNESS_MEDIUM, WILDERNESS); + put(WILDERNESS_HARD, WILDERNESS); + put(WILDERNESS_ELITE, WILDERNESS); + } + + private static void put(QuestHelperQuest quest, LeagueRegion... regions) + { + QUEST_REGIONS.put(quest, EnumSet.of(regions[0], regions)); + } + + public static boolean isCompletableWith(QuestHelperQuest quest, EnumSet playerRegions) + { + EnumSet required = QUEST_REGIONS.get(quest); + if (required == null) + { + return false; + } + return playerRegions.containsAll(required); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueRegion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueRegion.java new file mode 100644 index 00000000000..c0109417256 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueRegion.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2026, Syrif + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.questinfo; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.gameval.SpriteID; + +/** + * Regions available in OSRS leagues. Area codes match param 1017 values from the game cache. + */ +@AllArgsConstructor +@Getter +public enum LeagueRegion +{ + MISTHALIN("Misthalin", 1, SpriteID.TrailblazerMapShields._0), + KARAMJA("Karamja", 2, SpriteID.TrailblazerMapShields._1), + ASGARNIA("Asgarnia", 3, SpriteID.TrailblazerMapShields._2), + KANDARIN("Kandarin", 4, SpriteID.TrailblazerMapShields._6), + MORYTANIA("Morytania", 5, SpriteID.TrailblazerMapShields._4), + DESERT("Desert", 6, SpriteID.TrailblazerMapShields._3), + TIRANNWN("Tirannwn", 7, SpriteID.TrailblazerMapShields._8), + FREMENNIK("Fremennik Province", 8, SpriteID.TrailblazerMapShields._7), + KOUREND("Kourend & Kebos", 10, SpriteID.League4MapShields01._9), + WILDERNESS("Wilderness", 11, SpriteID.TrailblazerMapShields._5), + VARLAMORE("Varlamore", 21, SpriteID.League5MapShields01._10); + + private final String displayName; + private final int areaCode; + private final int spriteId; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java index 6c18daca5b0..597ab3a83bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.microbot.questhelper.questinfo; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.ChartingHelper; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.ardougne.ArdougneEasy; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.ardougne.ArdougneElite; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.ardougne.ArdougneHard; @@ -70,7 +71,6 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.wilderness.WildernessElite; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.wilderness.WildernessHard; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.wilderness.WildernessMedium; -import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.ChartingHelper; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.alfredgrimhandsbarcrawl.AlfredGrimhandsBarcrawl; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.barbariantraining.BarbarianTraining; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.curseoftheemptylord.CurseOfTheEmptyLord; @@ -88,10 +88,10 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.themagearenaii.TheMageArenaII; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.valetotems.ValeTotems; import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.allneededitems.AllNeededItems; -import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.HerbRun; -import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.TreeRun; import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.knightswaves.KnightWaves; import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.strongholdofsecurity.StrongholdOfSecurity; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.HerbRun; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.TreeRun; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.akingdomdivided.AKingdomDivided; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.anightatthetheatre.ANightAtTheTheatre; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.animalmagnetism.AnimalMagnetism; @@ -246,10 +246,12 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thegreatbrainrobbery.TheGreatBrainRobbery; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thehandinthesand.TheHandInTheSand; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theheartofdarkness.TheHeartOfDarkness; +import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theidesofmilk.TheIdesOfMilk; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theknightssword.TheKnightsSword; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thelosttribe.TheLostTribe; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thepathofglouphrie.ThePathOfGlouphrie; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thequeenofthieves.TheQueenOfThieves; +import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theredreef.TheRedReef; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.therestlessghost.TheRestlessGhost; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theribbitingtaleofalilypadlabourdispute.TheRibbitingTaleOfALilyPadLabourDispute; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theslugmenace.TheSlugMenace; @@ -303,6 +305,7 @@ public enum QuestHelperQuest ERNEST_THE_CHICKEN(new ErnestTheChicken(), Quest.ERNEST_THE_CHICKEN, QuestVarPlayer.QUEST_ERNEST_THE_CHICKEN, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), GOBLIN_DIPLOMACY(new GoblinDiplomacy(), Quest.GOBLIN_DIPLOMACY, QuestVarbits.QUEST_GOBLIN_DIPLOMACY, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), IMP_CATCHER(new ImpCatcher(), Quest.IMP_CATCHER, QuestVarPlayer.QUEST_IMP_CATCHER, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), + THE_IDES_OF_MILK(new TheIdesOfMilk(), Quest.THE_IDES_OF_MILK, QuestVarbits.QUEST_THE_IDES_OF_MILK, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), THE_KNIGHTS_SWORD(new TheKnightsSword(), Quest.THE_KNIGHTS_SWORD, QuestVarPlayer.QUEST_THE_KNIGHTS_SWORD, QuestDetails.Type.F2P, QuestDetails.Difficulty.INTERMEDIATE), MISTHALIN_MYSTERY(new MisthalinMystery(), Quest.MISTHALIN_MYSTERY, QuestVarbits.QUEST_MISTHALIN_MYSTERY, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), PIRATES_TREASURE(new PiratesTreasure(), Quest.PIRATES_TREASURE, QuestVarPlayer.QUEST_PIRATES_TREASURE, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), @@ -482,6 +485,7 @@ public enum QuestHelperQuest PRYING_TIMES(new PryingTimes(), Quest.PRYING_TIMES, QuestVarbits.QUEST_PRYING_TIMES, QuestDetails.Type.P2P, QuestDetails.Difficulty.INTERMEDIATE), CURRENT_AFFAIRS(new CurrentAffairs(), Quest.CURRENT_AFFAIRS, QuestVarbits.QUEST_CURRENT_AFFAIRS, QuestDetails.Type.P2P, QuestDetails.Difficulty.NOVICE), TROUBLED_TORTUGANS(new TroubledTortugans(), Quest.TROUBLED_TORTUGANS, QuestVarbits.QUEST_TROUBLED_TORTUGANS, QuestDetails.Type.P2P, QuestDetails.Difficulty.EXPERIENCED), + THE_RED_REEF(new TheRedReef(), Quest.THE_RED_REEF, QuestVarbits.QUEST_THE_RED_REEF, QuestDetails.Type.P2P, QuestDetails.Difficulty.EXPERIENCED), //Miniquests ENTER_THE_ABYSS(new EnterTheAbyss(), Quest.ENTER_THE_ABYSS, QuestVarPlayer.QUEST_ENTER_THE_ABYSS, QuestDetails.Type.MINIQUEST, QuestDetails.Difficulty.MINIQUEST), BEAR_YOUR_SOUL(new BearYourSoul(), Quest.BEAR_YOUR_SOUL, QuestVarbits.QUEST_BEAR_YOUR_SOUL, QuestDetails.Type.MINIQUEST, QuestDetails.Difficulty.MINIQUEST), @@ -657,7 +661,6 @@ public enum QuestHelperQuest WOODCUTTING(new Woodcutting(), "Woodcutting", Skill.WOODCUTTING, 99, QuestDetails.Type.SKILL_F2P, QuestDetails.Difficulty.SKILL), MINING(new Mining(), "Mining", Skill.MINING, 99, QuestDetails.Type.SKILL_F2P, QuestDetails.Difficulty.SKILL), - // Player Quests BIKE_SHEDDER(new BikeShedder(), "Bike Shedder", PlayerQuests.BIKE_SHEDDER, 4, true); @@ -675,9 +678,11 @@ public enum QuestHelperQuest @Getter private final QuestDetails.Difficulty difficulty; + @Getter private final QuestVarbits varbit; + @Getter private final QuestVarPlayer varPlayer; private Skill skill; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java index d6ce0c95361..e87cfd43407 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java @@ -18,6 +18,7 @@ public enum QuestVarbits QUEST_GOBLIN_DIPLOMACY(VarbitID.GOBDIP_MAIN), QUEST_MISTHALIN_MYSTERY(VarbitID.MISTMYST_PROGRESS), QUEST_THE_CORSAIR_CURSE(VarbitID.CORSCURS_PROGRESS), + QUEST_THE_IDES_OF_MILK(VarbitID.COWQUEST), QUEST_X_MARKS_THE_SPOT(VarbitID.CLUEQUEST), /** @@ -127,7 +128,8 @@ public enum QuestVarbits QUEST_PANDEMONIUM(VarbitID.SAILING_INTRO), QUEST_PRYING_TIMES(VarbitID.QUEST_PRY), QUEST_CURRENT_AFFAIRS(VarbitID.CURRENT_AFFAIRS), - QUEST_TROUBLED_TORTUGANS(VarbitID.TT), + QUEST_TROUBLED_TORTUGANS(VarbitID.TT), + QUEST_THE_RED_REEF(VarbitID.TRR), /** * mini-quest varbits, these don't hold the completion value. */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java index b1f02da01fb..e4480df65e2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java @@ -24,8 +24,8 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements; -import net.runelite.api.Client; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.api.Client; import net.runelite.client.ui.overlay.components.LineComponent; import javax.annotation.Nonnull; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java index 7bef5083ecd..1f15f19c2e6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java @@ -26,11 +26,11 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ConditionForStep; import lombok.Setter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.events.ChatMessage; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ConditionForStep; import java.util.Arrays; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java index 343a8b16c8b..0384ec86310 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java @@ -26,9 +26,9 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.api.Client; import net.runelite.client.config.ConfigManager; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.ui.overlay.components.LineComponent; import javax.annotation.Nonnull; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java index a8d6dbc232c..cea3370279e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java @@ -26,7 +26,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.api.Client; -import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; public class StepIsActiveRequirement extends AbstractRequirement { @@ -43,7 +43,7 @@ public boolean check(Client client) return questStep.isStarted(); } - @NotNull + @Nonnull @Override public String getDisplayText() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java index cb767e0181e..ac054d69b06 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java @@ -40,6 +40,7 @@ public abstract class ConditionForStep implements InitializableRequirement @Getter protected boolean hasPassed; protected boolean onlyNeedToPassOnce; + @Getter protected LogicType logicType; @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java index 2931517683d..9faf5edac89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java @@ -36,6 +36,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Set; public class Conditions extends ConditionForStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java index 2117c649a11..edf7ff1d66d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java @@ -24,13 +24,13 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.conditional; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import lombok.Setter; import net.runelite.api.Client; import net.runelite.api.GameObject; import net.runelite.api.Tile; import net.runelite.api.TileObject; import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import java.util.Objects; import java.util.Set; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java index 0c6e999b09a..4885ee8542d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java @@ -43,13 +43,13 @@ import net.runelite.api.Item; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.util.Text; -import org.jetbrains.annotations.Nullable; +import javax.annotation.Nullable; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -93,7 +93,6 @@ public class ItemRequirement extends AbstractRequirement * Indicates whether the item must be equipped. */ @Setter - @Getter protected boolean mustBeEquipped; public boolean mustBeEquipped() { @@ -647,11 +646,11 @@ public void setAdditionalOptions(Requirement additionalOptions) public String getWikiUrl() { if (getUrlSuffix() != null) { - return "https://oldschool.runescape.wiki/w/" + getUrlSuffix(); + return "https://oldschool.runescape.wiki/w/" + getUrlSuffix() + "#Item_sources"; } if (getId() != -1) { - return "https://oldschool.runescape.wiki/w/Special:Lookup?type=item&id=" + getId(); + return "https://oldschool.runescape.wiki/w/Special:Lookup?type=item&id=" + getId() + "#Item_sources"; } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java index 6b7c039a108..8ff3696cfe0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java @@ -36,8 +36,8 @@ import net.runelite.api.Item; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java index 0326f47b07e..7b0567b28da 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java @@ -24,115 +24,26 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.item; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.collections.KeyringCollection; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.gameval.ItemID; -import net.runelite.client.config.ConfigManager; -import java.awt.*; -import java.util.Set; - -// TODO: Convert this to be a TrackedContainer instead? +/// A requirement of a key that can be found on a key ring. +/// +/// This requirement helps the bank tag service show the keyring if the key can be found in the player's key ring. public class KeyringRequirement extends ItemRequirement { - RuneliteRequirement runeliteRequirement; - @Getter KeyringCollection keyringCollection; - ConfigManager configManager; - - ItemRequirement keyring; - - public KeyringRequirement(String name, ConfigManager configManager, KeyringCollection key) + public KeyringRequirement(String name, KeyringCollection key) { super(name, key.getItemID()); - keyring = new ItemRequirement("Steel key ring", ItemID.FAVOUR_KEY_RING); - runeliteRequirement = new RuneliteRequirement(configManager, key.runeliteName(), - "true", key.toChatText()); this.keyringCollection = key; - this.configManager = configManager; - } - - public KeyringRequirement(ConfigManager configManager, KeyringCollection key) - { - super(key.toChatText(), key.getItemID()); - keyring = new ItemRequirement("Steel key ring", ItemID.FAVOUR_KEY_RING); - runeliteRequirement = new RuneliteRequirement(configManager, key.runeliteName(), - "true", key.toChatText()); - this.keyringCollection = key; - this.configManager = configManager; - } - - public String chatboxText() - { - return keyringCollection.toChatText(); - } - - public void setConfigValue(String value) - { - runeliteRequirement.setConfigValue(value); - } - - @Override - public ItemRequirement copy() - { - KeyringRequirement newItem = new KeyringRequirement(getName(), configManager, keyringCollection); - newItem.addAlternates(alternateItems); - newItem.setDisplayItemId(getDisplayItemId()); - newItem.setHighlightInInventory(highlightInInventory); - newItem.setDisplayMatchedItemName(isDisplayMatchedItemName()); - newItem.setConditionToHide(getConditionToHide()); - newItem.setShouldCheckBank(isShouldCheckBank()); - newItem.setTooltip(getTooltip()); - newItem.setUrlSuffix(getUrlSuffix()); - - return newItem; - } - - @Override - public boolean check(Client client) - {; - if (hasKeyOnKeyRing() && keyring.check(client)) - { - return true; - } - - return super.check(client); - } - - public boolean hasKeyOnKeyRing() - { - return runeliteRequirement.check(); - } - - @Override - public Color getColor(Client client, QuestHelperConfig config) - { - if (hasKeyOnKeyRing()) - { - return keyring.getColor(client, config); - } - - return this.check(client) ? config.passColour() : config.failColour(); - } - - protected String getTooltipFromEnumSet(Set containers) - { - String basicTooltip = super.getTooltipFromEnumSet(containers); - if (hasKeyOnKeyRing()) - { - return basicTooltip + " on your key ring."; - } - return basicTooltip; } @Override protected KeyringRequirement copyOfClass() { - return new KeyringRequirement(getName(), configManager, keyringCollection); + return new KeyringRequirement(getName(), keyringCollection); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java index aefce2c64b0..21abbb41d17 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java @@ -32,5 +32,6 @@ public enum TrackedContainers POTION_STORAGE, GROUP_STORAGE, RUNE_POUCH, + KEY_RING, UNDEFINED } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java index 97f66bb0172..d27e7602f70 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java @@ -29,6 +29,7 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.events.ChatMessage; +import net.runelite.api.gameval.InterfaceID; import net.runelite.client.util.Text; import java.util.ArrayList; @@ -40,16 +41,23 @@ public class DialogRequirement extends SimpleRequirement @Setter String talkerName; final List text = new ArrayList<>(); - final boolean mustBeActive; + + @Setter + boolean mustBeActive; boolean hasSeenDialog = false; + /// Also allow the dialog message to check MESBOX messages + @Setter + boolean allowMesbox = false; + public DialogRequirement(String... text) { this.talkerName = null; this.text.addAll(Arrays.asList(text)); this.mustBeActive = false; } + public DialogRequirement(String talkerName, String text, boolean mustBeActive) { this.talkerName = talkerName; @@ -75,9 +83,35 @@ public boolean check(Client client) return hasSeenDialog; } + public void validateActiveWidget(Client client) + { + if (!mustBeActive) return; + + var chatModal = client.getWidget(InterfaceID.Chatbox.CHATMODAL); + + if (chatModal == null || chatModal.isHidden()) + { + hasSeenDialog = false; + } + } + public void validateCondition(ChatMessage chatMessage) { - if (chatMessage.getType() != ChatMessageType.DIALOG) return; + if (chatMessage.getType() != ChatMessageType.DIALOG) + { + if (allowMesbox) + { + // This requirement also allows validating the condition against MESBOX entries + if (chatMessage.getType() != ChatMessageType.MESBOX) + { + return; + } + } + else + { + return; + } + } String dialogMessage = chatMessage.getMessage(); if (!hasSeenDialog) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java index 5538b4c3249..c1dace149c7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java @@ -27,11 +27,10 @@ package net.runelite.client.plugins.microbot.questhelper.requirements.npc; import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; +import javax.annotation.Nonnull; import net.runelite.api.Client; import net.runelite.api.gameval.VarPlayerID; -import javax.annotation.Nonnull; - public class NoFollowerRequirement extends AbstractRequirement { String text; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java index 8ccdf7e21b3..1e6efe0a983 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java @@ -131,7 +131,13 @@ public NpcRequirement(int npcID, String npcName) @Override public boolean check(Client client) { - List found = client.getTopLevelWorldView().npcs().stream() + var localPlayer = client.getLocalPlayer(); + if (localPlayer == null) + { + return false; + } + + List found = localPlayer.getWorldView().npcs().stream() .filter(npc -> npc.getId() == npcID || npc.getComposition().getId() == npcID) .filter(npc -> npcName == null || (npc.getName() != null && npc.getName().equals(npcName))) .collect(Collectors.toList()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java index f4f56b6e00d..1eff7f8781e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java @@ -38,11 +38,11 @@ public enum Boosts DEFENCE("Defence",21), FARMING("Farming",3), FIREMAKING("Firemaking",1), - FISHING("Fishing",5), + FISHING("Fishing",6), FLETCHING("Fletching",4), HERBLORE("Herblore",4), HITPOINTS("Hitpoints",22), - HUNTER("Hunter",3), + HUNTER("Hunter",6), MAGIC("Magic",19), MINING("Mining",3), PRAYER("Prayer",0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java index 79d1b132f3d..f5dc54956a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java @@ -36,6 +36,7 @@ import net.runelite.api.gameval.InventoryID; import javax.annotation.Nonnull; +import java.util.Locale; /** * Requirement that checks if a player has a required number of slots free in a given diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java index 9340e324b9f..4fa1229998b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java @@ -27,12 +27,13 @@ package net.runelite.client.plugins.microbot.questhelper.requirements.player; import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; -import lombok.Getter; import net.runelite.api.Client; -import net.runelite.api.gameval.VarbitID; import javax.annotation.Nonnull; +import lombok.Getter; +import net.runelite.api.gameval.VarbitID; + /** * Requirement that checks if a player has a required number of Port Task slots free. */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java index 3fd9c191767..5853612f557 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java @@ -28,11 +28,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Port; -import lombok.Getter; import net.runelite.api.Client; -import net.runelite.api.gameval.VarbitID; import javax.annotation.Nonnull; + +import lombok.Getter; +import net.runelite.api.gameval.VarbitID; import java.util.stream.IntStream; /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java index 5ec4ff42616..c12783702fa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java @@ -24,10 +24,10 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.sailing; +import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.gameval.VarbitID; -import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; import javax.annotation.Nonnull; import java.util.Objects; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java index 3de13dd1040..a83d855c33e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java @@ -27,9 +27,9 @@ package net.runelite.client.plugins.microbot.questhelper.requirements.util; import net.runelite.api.Client; +import net.runelite.api.gameval.InventoryID; import net.runelite.api.Item; import net.runelite.api.ItemContainer; -import net.runelite.api.gameval.InventoryID; import java.util.Arrays; import java.util.Objects; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java index e693900f061..f6fc9481bfc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java @@ -26,6 +26,8 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.util; +import java.util.ArrayList; +import java.util.List; import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.Item; @@ -38,34 +40,38 @@ @Getter public enum ItemSlots { - ANY_EQUIPPED_AND_INVENTORY(-3, "inventory or equipped", InventorySlots.EQUIPMENT_AND_INVENTORY_SLOTS), - ANY_INVENTORY(-2, "inventory slots", InventorySlots.INVENTORY_SLOTS), - ANY_EQUIPPED(-1, "equipped slots", InventorySlots.EQUIPMENT_SLOTS), - HEAD(0, "head slot"), - CAPE(1, "cape slot"), - AMULET(2, "amulet slot"), - WEAPON(3, "weapon slot"), - BODY(4, "body slot"), - SHIELD(5, "shield slot"), - LEGS(7, "legs slot"), - GLOVES(9, "gloves slot"), - BOOTS(10, "boots slot"), - RING(12, "ring slot"), - AMMO(13, "ammo slot"); + ANY_EQUIPPED_AND_INVENTORY("inventory or equipped", InventorySlots.EQUIPMENT_AND_INVENTORY_SLOTS, -3), + ANY_INVENTORY("inventory slots", InventorySlots.INVENTORY_SLOTS, -2), + ANY_EQUIPPED("equipped slots", InventorySlots.EQUIPMENT_SLOTS, -1), - private final int slotIdx; + EMPTY_HANDS("weapons and shield slot", 3, 5), + BARE_HANDS("weapon, shield and gloves slot", 3, 5, 9), + + HEAD("head slot", 0), + CAPE("cape slot", 1), + AMULET("amulet slot", 2), + WEAPON("weapon slot", 3), + BODY("body slot", 4), + SHIELD("shield slot", 5), + LEGS("legs slot", 7), + GLOVES("gloves slot", 9), + BOOTS("boots slot", 10), + RING("ring slot", 12), + AMMO("ammo slot", 13); + + private final int[] slotIdxs; private final String name; private final InventorySlots inventorySlots; - ItemSlots(int slotIdx, String name) + ItemSlots(String name, int... slotIdx) { - this.slotIdx = slotIdx; + this.slotIdxs = slotIdx; this.name = name; this.inventorySlots = null; } - ItemSlots(int slotIdx, String name, InventorySlots slots) + ItemSlots(String name, InventorySlots slots, int... slotIdx) { - this.slotIdx = slotIdx; + this.slotIdxs = slotIdx; this.name = name; this.inventorySlots = slots; } @@ -90,14 +96,7 @@ public boolean checkInventory(Client client, Predicate predicate) { return false; } - ItemContainer equipment = client.getItemContainer(InventoryID.WORN); - if (equipment == null || getSlotIdx() < 0) // unknown slot - { - return false; - } - Item item = equipment.getItem(getSlotIdx()); - - return predicate.test(item); + return getItems(client).allMatch(predicate); } /** @@ -120,17 +119,21 @@ public boolean contains(Client client, Predicate predicate) { return false; } + return getItems(client).anyMatch(predicate); + } + + private Stream getItems(Client client){ ItemContainer equipment = client.getItemContainer(InventoryID.WORN); - if (equipment == null || getSlotIdx() < 0) // unknown slot - { - return false; - } - Item item = equipment.getItem(getSlotIdx()); - if (item == null) + + List items = new ArrayList<>(); + for(int slotIdx: getSlotIdxs()) { - return false; + if (equipment == null || slotIdx < 0) // unknown slot + { + continue; + } + items.add(equipment.getItem(slotIdx)); } - - return predicate.test(item); + return items.stream(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java index b6ec18cdea8..6284c137c2a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java @@ -36,37 +36,37 @@ @Getter public enum Port { - PORT_SARIM(0, "Port Sarim", ObjectID.SAILING_DOCKING_BUOY_PORT_SARIM, new WorldPoint(3048, 3186, 0), new Zone(new WorldPoint(3045, 3183, 0), new WorldPoint(3061, 3208, 0)), new WorldPoint(3051, 3193, 0), new WorldPoint(3028, 3194, 0), ObjectID.PORT_TASK_BOARD_PORT_SARIM, new WorldPoint(3030, 3197, 0)) - , PANDEMONIUM(1, "the Pandemonium", ObjectID.SAILING_DOCKING_BUOY_THE_PANDEMONIUM, new WorldPoint(3069, 2981, 0), new Zone(new WorldPoint(3065, 2974, 0), new WorldPoint(3084, 2998, 0)), new WorldPoint(3070, 2987, 0), new WorldPoint(3061,2985, 0), ObjectID.PORT_TASK_BOARD_PANDEMONIUM, new WorldPoint(3058, 2958, 0)) -// , LANDS_END(2, "Land's End", ObjectID.SAILING_DOCKING_BUOY_LANDS_END, null, null, null, null, ObjectID.PORT_TASK_BOARD_LANDS_END, null) - , MUSA_POINT(3, "Musa Point", ObjectID.SAILING_DOCKING_BUOY_MUSA_POINT, new WorldPoint(2961, 3152, 0), new Zone(new WorldPoint(2974, 3156, 0), new WorldPoint(2956, 3144, 0)), new WorldPoint(2961, 3146, 0), new WorldPoint(2952, 3150, 0), ObjectID.PORT_TASK_BOARD_MUSA_POINT, new WorldPoint(2956, 3144, 0)) -// , HOSIDIUS(4, "Hosidius", ObjectID.SAILING_DOCKING_BUOY_HOSIDIUS, null, null, null, null, -1, null) -// , PORT_PISCARILIUS(-1, "Port Piscarilius", ObjectID.SAILING_DOCKING_BUOY_PORT_PISCARILIUS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_PISCARILIUS, null) -// , RIMMINGTON(-1, "Rimmington", ObjectID.SAILING_DOCKING_BUOY_RIMMINGTON, null, null, null, null, -1, null) - , CATHERBY(6, "Catherby", ObjectID.SAILING_DOCKING_BUOY_CATHERBY, new WorldPoint(2788, 3409, 0), new Zone(new WorldPoint(2804, 3401, 0), new WorldPoint(2786, 3413, 0)), new WorldPoint(2796, 3412, 0), new WorldPoint(2799, 3413, 0), ObjectID.PORT_TASK_BOARD_CATHERBY, new WorldPoint(2803, 3418, 0)) -// , BRIMHAVEN(-1, "Brimhaven", ObjectID.SAILING_DOCKING_BUOY_BRIMHAVEN, null, null, null, null, ObjectID.PORT_TASK_BOARD_BRIMHAVEN, null) -// , ARDOUGNE(-1, "Ardougne", ObjectID.SAILING_DOCKING_BUOY_ARDOUGNE, null, null, null, null, ObjectID.PORT_TASK_BOARD_ARDOUGNE, null) -// , PORT_KHAZARD(-1, "Port Khazard", ObjectID.SAILING_DOCKING_BUOY_PORT_KHAZARD, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_KHAZARD, null) -// , WITCHAVEN(-1, "Witchaven", ObjectID.SAILING_DOCKING_BUOY_WITCHAVEN, null, null, null, null, -1, null) -// , ENTRANA(-1, "Entrana", ObjectID.SAILING_DOCKING_BUOY_ENTRANA, null, null, null, null, -1, null) -// , CIVITAS_ILLA_FORTIS(-1, "Civitas illa Fortis", ObjectID.SAILING_DOCKING_BUOY_CIVITAS_ILLA_FORTIS, null, null, null, null, ObjectID.PORT_TASK_BOARD_CIVITAS_ILLA_FORTIS, null) -// , CORSAIR_COVE(-1, "Corsair Cove", ObjectID.SAILING_DOCKING_BUOY_CORSAIR_COVE, null, null, null, null, ObjectID.PORT_TASK_BOARD_CORSAIR_COVE, null) -// , CAIRN_ISLE(-1, "Cairn Isle", ObjectID.SAILING_DOCKING_BUOY_CAIRN_ISLE, null, null, null, null, -1, null) -// , THE_SUMMER_SHORE(-1, "the Summer Shore", ObjectID.SAILING_DOCKING_BUOY_THE_SUMMER_SHORE, null, null, null, null, ObjectID.PORT_TASK_BOARD_THE_SUMMER_SHORE, null) -// , ALDARIN(-1, "Aldarin", ObjectID.SAILING_DOCKING_BUOY_ALDARIN, null, null, null, null, ObjectID.PORT_TASK_BOARD_ALDARIN, null) -// , RUINS_OF_UNKAH(-1, "Ruins of Unkah", ObjectID.SAILING_DOCKING_BUOY_RUINS_OF_UNKAH, null, null, null, null, ObjectID.PORT_TASK_BOARD_RUINS_OF_UNKAH, null) -// , VOID_KNIGHTS_OUTPOST(-1, "Void Knights Outpost", ObjectID.SAILING_DOCKING_BUOY_VOID_KNIGHTS_OUTPOST, null, null, null, null, ObjectID.PORT_TASK_BOARD_VOID_KNIGHTS_OUTPOST, null) -// , PORT_ROBERTS(-1, "Port Roberts", ObjectID.SAILING_DOCKING_BUOY_PORT_ROBERTS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_ROBERTS, null) -// , RELLEKKA(-1, "Rellekka", ObjectID.SAILING_DOCKING_BUOY_RELLEKKA, null, null, null, null, ObjectID.PORT_TASK_BOARD_RELLEKKA, null) -// , ETCETERIA(-1, "Etceteria", ObjectID.SAILING_DOCKING_BUOY_ETCETERIA, null, null, null, null, ObjectID.PORT_TASK_BOARD_ETCETERIA, null) -// , PORT_TYRAS(-1, "Port Tyras", ObjectID.SAILING_DOCKING_BUOY_PORT_TYRAS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_TYRAS, null) -// , DEEPFIN_POINT(-1, "Deepfin Point", ObjectID.SAILING_DOCKING_BUOY_DEEPFIN_POINT, null, null, null, null, ObjectID.PORT_TASK_BOARD_DEEPFIN_POINT, null) -// , JATIZSO(-1, "Jatizso", ObjectID.SAILING_DOCKING_BUOY_JATIZSO, null, null, null, null, -1, null) -// , NEITIZNOT(-1, "Neitiznot", ObjectID.SAILING_DOCKING_BUOY_NEITIZNOT, null, null, null, null, -1, null) -// , PRIFDDINAS(-1, "Prifddinas", ObjectID.SAILING_DOCKING_BUOY_PRIFDDINAS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PRIFDDINAS, null) -// , PISCATORIS(-1, "Piscatoris", ObjectID.SAILING_DOCKING_BUOY_PISCATORIS, null, null, null, null, -1, null) -// , LUNAR_ISLE(-1, "Lunar Isle", ObjectID.SAILING_DOCKING_BUOY_LUNAR_ISLE, null, null, null, null, ObjectID.PORT_TASK_BOARD_LUNAR_ISLE, null) - ; + PORT_SARIM(0, "Port Sarim", ObjectID.SAILING_DOCKING_BUOY_PORT_SARIM, new WorldPoint(3048, 3186, 0), new Zone(new WorldPoint(3045, 3183, 0), new WorldPoint(3061, 3208, 0)), new WorldPoint(3051, 3193, 0), new WorldPoint(3028, 3194, 0), ObjectID.PORT_TASK_BOARD_PORT_SARIM, new WorldPoint(3030, 3197, 0)), + PANDEMONIUM(1, "the Pandemonium", ObjectID.SAILING_DOCKING_BUOY_THE_PANDEMONIUM, new WorldPoint(3069, 2981, 0), new Zone(new WorldPoint(3065, 2974, 0), new WorldPoint(3084, 2998, 0)), new WorldPoint(3070, 2987, 0), new WorldPoint(3061,2985, 0), ObjectID.PORT_TASK_BOARD_PANDEMONIUM, new WorldPoint(3058, 2958, 0)), + LANDS_END(2, "Land's End", ObjectID.SAILING_DOCKING_BUOY_LANDS_END, new WorldPoint(1515, 3405, 0), new Zone( new WorldPoint(1520, 3408, 0), new WorldPoint(1507, 3393, 0)), new WorldPoint(1507, 3403, 0), new WorldPoint(1506, 3407, 0), ObjectID.PORT_TASK_BOARD_LANDS_END, new WorldPoint(1502, 3407, 0)), + MUSA_POINT(3, "Musa Point", ObjectID.SAILING_DOCKING_BUOY_MUSA_POINT, new WorldPoint(2961, 3152, 0), new Zone(new WorldPoint(2974, 3156, 0), new WorldPoint(2956, 3144, 0)), new WorldPoint(2961, 3146, 0), new WorldPoint(2952, 3150, 0), ObjectID.PORT_TASK_BOARD_MUSA_POINT, new WorldPoint(2956, 3144, 0)), + HOSIDIUS(4, "Hosidius", ObjectID.SAILING_DOCKING_BUOY_HOSIDIUS, new WorldPoint(1719, 3450, 0), null, new WorldPoint(1726, 3452, 0), new WorldPoint(1725, 3460, 0), -1, null), + PORT_PISCARILIUS(-1, "Port Piscarilius", ObjectID.SAILING_DOCKING_BUOY_PORT_PISCARILIUS, new WorldPoint(1840, 3681, 0), new Zone( new WorldPoint(1854, 3686, 0), new WorldPoint(1836, 3674, 0)), new WorldPoint(1845, 3687, 0), new WorldPoint(1837, 3691, 0), ObjectID.PORT_TASK_BOARD_PORT_PISCARILIUS, new WorldPoint(1839, 3691, 0)), + RIMMINGTON(-1, "Rimmington", ObjectID.SAILING_DOCKING_BUOY_RIMMINGTON, new WorldPoint(2908, 3216, 0), null, new WorldPoint(3906, 3225, 0), null, -1, null), + CATHERBY(6, "Catherby", ObjectID.SAILING_DOCKING_BUOY_CATHERBY, new WorldPoint(2788, 3409, 0), new Zone(new WorldPoint(2804, 3401, 0), new WorldPoint(2786, 3413, 0)), new WorldPoint(2796, 3412, 0), new WorldPoint(2799, 3413, 0), ObjectID.PORT_TASK_BOARD_CATHERBY, new WorldPoint(2803, 3418, 0)), + BRIMHAVEN(-1, "Brimhaven", ObjectID.SAILING_DOCKING_BUOY_BRIMHAVEN, new WorldPoint(2755, 3223, 0), new Zone( new WorldPoint(2746, 3219, 0), new WorldPoint(2758, 3239, 0)), new WorldPoint(2758, 3230, 0), new WorldPoint(2769, 3225, 0), ObjectID.PORT_TASK_BOARD_BRIMHAVEN, new WorldPoint(2764, 3227, 0)), + ARDOUGNE(-1, "Ardougne", ObjectID.SAILING_DOCKING_BUOY_ARDOUGNE, new WorldPoint(2663, 3261, 0), null, new WorldPoint(2671, 3265, 0), new WorldPoint(2674, 3269, 0), ObjectID.PORT_TASK_BOARD_ARDOUGNE, new WorldPoint(2676, 3276, 0)), + PORT_KHAZARD(-1, "Port Khazard", ObjectID.SAILING_DOCKING_BUOY_PORT_KHAZARD, new WorldPoint(2663, 3261, 0), new Zone( new WorldPoint(2694, 3171, 0), new WorldPoint(2682, 3153, 0)), new WorldPoint(2686, 3162, 0), new WorldPoint(2684, 3164, 0), ObjectID.PORT_TASK_BOARD_PORT_KHAZARD, new WorldPoint(2678, 3162, 0)), + WITCHAVEN(-1, "Witchaven", ObjectID.SAILING_DOCKING_BUOY_WITCHAVEN, new WorldPoint(2746, 3297, 0), new Zone( new WorldPoint(2759, 3312, 0), new WorldPoint(2741, 3294, 0)), new WorldPoint(2747, 3305, 0), null, -1, null), + ENTRANA(-1, "Entrana", ObjectID.SAILING_DOCKING_BUOY_ENTRANA, new WorldPoint(2880, 3330, 0), new Zone( new WorldPoint(2874, 3322, 0), new WorldPoint(2892, 3340, 0)), new WorldPoint(2879, 3336, 0), new WorldPoint(2874, 3339, 0), -1, null), + CIVITAS_ILLA_FORTIS(-1, "Civitas illa Fortis", ObjectID.SAILING_DOCKING_BUOY_CIVITAS_ILLA_FORTIS, new WorldPoint(1768, 3147, 0), new Zone( new WorldPoint(1764, 3129, 0), new WorldPoint(1774, 3149, 0)), new WorldPoint(1775, 3142, 0), new WorldPoint(1781, 3147, 0), ObjectID.PORT_TASK_BOARD_CIVITAS_ILLA_FORTIS, new WorldPoint(1782, 3142, 0)), + CORSAIR_COVE(-1, "Corsair Cove", ObjectID.SAILING_DOCKING_BUOY_CORSAIR_COVE, new WorldPoint(2585, 3847, 0), new Zone( new WorldPoint(2581, 2834, 0), new WorldPoint(2593, 2847, 0)), new WorldPoint(2580, 2844, 0), new WorldPoint(2581, 2848, 0), ObjectID.PORT_TASK_BOARD_CORSAIR_COVE, new WorldPoint(2579, 2853, 0)), + CAIRN_ISLE(-1, "Cairn Isle", ObjectID.SAILING_DOCKING_BUOY_CAIRN_ISLE, new WorldPoint(2748, 2944, 0), null, new WorldPoint(2750, 2952, 0), new WorldPoint(2756, 2949, 0), -1, null), + SUNSET_COAST(-1, "the Sunset Coast", ObjectID.SAILING_DOCKING_BUOY_SUNSET_COAST, new WorldPoint(1505, 2977, 0), new Zone( new WorldPoint(1500, 2958, 0), new WorldPoint(1511, 2979, 0)), new WorldPoint(1512, 2974, 0), new WorldPoint(1515, 2977, 0), -1, null), + THE_SUMMER_SHORE(-1, "the Summer Shore", ObjectID.SAILING_DOCKING_BUOY_THE_SUMMER_SHORE, new WorldPoint(3168, 2364, 0), new Zone( new WorldPoint(3200, 2353, 0), new WorldPoint(3160, 2372, 0)), new WorldPoint(3174, 2367, 0), new WorldPoint(3173, 2370, 0), ObjectID.PORT_TASK_BOARD_THE_SUMMER_SHORE, new WorldPoint(3183, 2368, 0)), + ALDARIN(-1, "Aldarin", ObjectID.SAILING_DOCKING_BUOY_ALDARIN, new WorldPoint(1457, 2975, 0), new Zone( new WorldPoint(1444, 2970, 0), new WorldPoint(1461, 2984, 0)), new WorldPoint(1452, 2970, 0), new WorldPoint(1449, 2969, 0), ObjectID.PORT_TASK_BOARD_ALDARIN, new WorldPoint(1438, 2939, 0)), + RUINS_OF_UNKAH(-1, "Ruins of Unkah", ObjectID.SAILING_DOCKING_BUOY_RUINS_OF_UNKAH, new WorldPoint(3144, 2818, 0), new Zone( new WorldPoint(3136, 2813, 0), new WorldPoint(3146, 2831, 0)), new WorldPoint(3144, 2825, 0), new WorldPoint(3148, 2826, 0), ObjectID.PORT_TASK_BOARD_RUINS_OF_UNKAH, new WorldPoint(3146, 2828, 0)), + VOID_KNIGHTS_OUTPOST(-1, "Void Knights Outpost", ObjectID.SAILING_DOCKING_BUOY_VOID_KNIGHTS_OUTPOST, new WorldPoint(2643, 2678, 0), new Zone( new WorldPoint(2641, 2675, 0), new WorldPoint(2659, 2687, 0)), new WorldPoint(2651, 2678, 0), new WorldPoint(2652, 2673, 0), ObjectID.PORT_TASK_BOARD_VOID_KNIGHTS_OUTPOST, new WorldPoint(2659, 2672, 0)), + PORT_ROBERTS(-1, "Port Roberts", ObjectID.SAILING_DOCKING_BUOY_PORT_ROBERTS, new WorldPoint(1859, 3302, 0), new Zone( new WorldPoint(1850, 3297, 0), new WorldPoint(1862, 3317, 0)), new WorldPoint(1861, 3307, 0), new WorldPoint(1867, 3306, 0), ObjectID.PORT_TASK_BOARD_PORT_ROBERTS, new WorldPoint(1872, 3303, 0)), + RELLEKKA(-1, "Rellekka", ObjectID.SAILING_DOCKING_BUOY_RELLEKKA, new WorldPoint(2633, 3711, 0), new Zone( new WorldPoint(2624, 3704, 0), new WorldPoint(2636, 3716, 0)), new WorldPoint(2630, 3705, 0), new WorldPoint(2629, 3699, 0), ObjectID.PORT_TASK_BOARD_RELLEKKA, new WorldPoint(2629, 3685, 0)), + ETCETERIA(-1, "Etceteria", ObjectID.SAILING_DOCKING_BUOY_ETCETERIA, new WorldPoint(2618, 3836, 0), new Zone( new WorldPoint(2607, 3833, 0), new WorldPoint(2619, 3839, 0)), new WorldPoint(2613, 2840, 0), new WorldPoint(2612, 3846, 0), ObjectID.PORT_TASK_BOARD_ETCETERIA, new WorldPoint(2617, 3849, 0)), + PORT_TYRAS(-1, "Port Tyras", ObjectID.SAILING_DOCKING_BUOY_PORT_TYRAS, new WorldPoint(2149, 3117, 0), new Zone( new WorldPoint(2132, 3109, 0), new WorldPoint(2152, 3120, 0)), new WorldPoint(2144, 3120, 0), new WorldPoint(2151, 3123, 0), ObjectID.PORT_TASK_BOARD_PORT_TYRAS, new WorldPoint(2146, 3123, 0)), + DEEPFIN_POINT(-1, "Deepfin Point", ObjectID.SAILING_DOCKING_BUOY_DEEPFIN_POINT, new WorldPoint(1930, 2755, 0), new Zone( new WorldPoint(1935, 2743, 0), new WorldPoint(1914, 2759, 0)), new WorldPoint(1923, 2758, 0), new WorldPoint(1928, 2761, 0), ObjectID.PORT_TASK_BOARD_DEEPFIN_POINT, new WorldPoint(1931, 2761, 0)), + JATIZSO(-1, "Jatizso", ObjectID.SAILING_DOCKING_BUOY_JATIZSO, new WorldPoint(2405, 3776, 0), new Zone( new WorldPoint(2404, 3770, 0), new WorldPoint(2422, 3779, 0)), new WorldPoint(2412, 3780, 0), new WorldPoint(2401, 3788, 0), -1, null), + NEITIZNOT(-1, "Neitiznot", ObjectID.SAILING_DOCKING_BUOY_NEITIZNOT, new WorldPoint(2304, 3786, 0), new Zone( new WorldPoint(2298, 3771, 0), new WorldPoint(2307, 3789, 0)), new WorldPoint(2309, 3782, 0), new WorldPoint(2308, 3775, 0), -1, null), + PRIFDDINAS(-1, "Prifddinas", ObjectID.SAILING_DOCKING_BUOY_PRIFDDINAS, new WorldPoint(2165, 3321, 0), new Zone( new WorldPoint(2165, 3307, 0), new WorldPoint(2141, 3325, 0)), new WorldPoint(2158, 3324, 0), new WorldPoint(2170, 3328, 0), ObjectID.PORT_TASK_BOARD_PRIFDDINAS, new WorldPoint(2163, 3326, 0)), + PISCATORIS(-1, "Piscatoris", ObjectID.SAILING_DOCKING_BUOY_PISCATORIS, new WorldPoint(2304, 3696, 0), new Zone( new WorldPoint(2293, 3682, 0), new WorldPoint(2306, 3700, 0)), new WorldPoint(2304, 3689, 0), new WorldPoint(2313, 3693, 0), -1, null), + LUNAR_ISLE(-1, "Lunar Isle", ObjectID.SAILING_DOCKING_BUOY_LUNAR_ISLE, new WorldPoint(2154, 3886, 0), new Zone( new WorldPoint(2151, 3875, 0), new WorldPoint(2163, 3887, 0)), new WorldPoint(2152, 3881, 0), new WorldPoint(2146, 3879, 0), ObjectID.PORT_TASK_BOARD_LUNAR_ISLE, new WorldPoint(2139, 3884, 0));; private final int id; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java index 77aeda7457e..ae6267d7730 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java @@ -53,7 +53,8 @@ public class VarbitRequirement extends AbstractRequirement @Setter private int requiredValue; private final Operation operation; - private final String displayText; + @Setter + private String displayText; // bit positions private boolean bitIsSet = false; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java index c0e6e8fc095..bcd7013b597 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java @@ -33,6 +33,8 @@ import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.Player; +import net.runelite.api.WorldEntity; +import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import javax.annotation.Nonnull; @@ -46,6 +48,13 @@ public class ZoneRequirement extends AbstractRequirement private final boolean checkInZone; private String displayText; + /// Contains the value of the most recent successful zone check. + /// null = no check has succeeded + /// true = the last check was deemed a success (check returned true) + /// false = the last check was deemed a failure (check returned false) + @Getter + private Boolean matchedZoneLastCheck = null; + /** * Check if the player is either in the specified zone. * @@ -107,7 +116,8 @@ public boolean check(Client client) if (player != null && zones != null) { boolean inZone = zones.stream().anyMatch(z -> z.contains(client, player.getLocalLocation())); - return inZone == checkInZone; + matchedZoneLastCheck = inZone == checkInZone; + return matchedZoneLastCheck; } return false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java index b1a1726aaa0..a16a67e1fee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java @@ -45,19 +45,16 @@ public class Cheerer public static void createCheerers(RuneliteObjectManager runeliteObjectManager, Client client, ConfigManager configManager) { cheerers.clear(); - if (client.getLocalPlayer() == null) - { - return; - } createWOM(runeliteObjectManager, client); createZoinkwiz(runeliteObjectManager, client); } private static void createWOM(RuneliteObjectManager runeliteObjectManager, Client client) { - WorldPoint playerPos = client.getLocalPlayer().getWorldLocation(); - WorldPoint pointAbovePlayer = new WorldPoint(playerPos.getX(), playerPos.getY() + 1, playerPos.getPlane()); - FakeNpc wiseOldMan = runeliteObjectManager.createFakeNpc("global", wiseOldManOutfit(client), pointAbovePlayer, 862); + // Spawn the initial NPC in lumbridge. + // When the NPC is activated from the player completing a quest, we will always update the position anyway. + var spawnPos = new WorldPoint(3223, 3218, 0); + FakeNpc wiseOldMan = runeliteObjectManager.createFakeNpc("global", wiseOldManOutfit(client), spawnPos, 862); wiseOldMan.setName("Wise Old Man"); wiseOldMan.setExamine("Loves questing."); wiseOldMan.addExamineAction(runeliteObjectManager); @@ -86,9 +83,10 @@ private static Model wiseOldManOutfit(Client client) private static void createZoinkwiz(RuneliteObjectManager runeliteObjectManager, Client client) { - WorldPoint playerPos = client.getLocalPlayer().getWorldLocation(); - WorldPoint pointAbovePlayer = new WorldPoint(playerPos.getX(), playerPos.getY() + 1, playerPos.getPlane()); - FakeNpc zoinkwiz = runeliteObjectManager.createFakeNpc("global", zoinkwizOutfit(client), pointAbovePlayer, 862); + // Spawn the initial NPC in lumbridge. + // When the NPC is activated from the player completing a quest, we will always update the position anyway. + var spawnPos = new WorldPoint(3223, 3218, 0); + FakeNpc zoinkwiz = runeliteObjectManager.createFakeNpc("global", zoinkwizOutfit(client), spawnPos, 862); zoinkwiz.setName("Zoinkwiz"); zoinkwiz.setExamine("Loves questing."); zoinkwiz.addExamineAction(runeliteObjectManager); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java index ef91ce9c5cf..ed1ffbdc2d3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java @@ -25,9 +25,18 @@ package net.runelite.client.plugins.microbot.questhelper.runeliteobjects; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.plugins.microbot.questhelper.questinfo.PlayerQuests; +import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.PlayerQuestStateRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; +import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.ReplacedNpc; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.RuneliteObjectManager; +import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.WidgetReplacement; +import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetDetails; import lombok.Setter; import net.runelite.api.Client; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.NpcID; import net.runelite.client.config.ConfigManager; public class GlobalFakeObjects diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java index 0e315b7445a..2f940912e64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java @@ -45,8 +45,8 @@ import net.runelite.client.game.chatbox.ChatboxPanelManager; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java index 68e1af5f9f5..e9d2200bdf4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java @@ -29,15 +29,15 @@ import com.google.inject.Singleton; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetDetails; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.*; import net.runelite.api.Menu; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.*; import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.SpriteID; import net.runelite.api.widgets.Widget; +import net.runelite.api.gameval.SpriteID; import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.Hooks; import net.runelite.client.chat.ChatColorType; @@ -54,8 +54,8 @@ import java.awt.*; import java.awt.image.BufferedImage; -import java.util.*; import java.util.List; +import java.util.*; import java.util.function.Consumer; // This will hold all RuneliteObjects @@ -817,15 +817,18 @@ public void onGameTick(GameTick event) @Subscribe public void onClientTick(ClientTick event) { + var localPlayer = client.getLocalPlayer(); + + if (localPlayer == null) + { + return; + } + bufferRedClickAnimation = Math.floorMod(bufferRedClickAnimation + 1, ANIMATION_PERIOD); if (bufferRedClickAnimation == 0) { redClickAnimationFrame++; } - if (client.getLocalPlayer() == null) - { - return; - } WorldPoint playerPosition = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()); runeliteObjectGroups.forEach((groupID, extendedRuneliteObjectGroup) -> { for (ExtendedRuneliteObject extendedRuneliteObject : extendedRuneliteObjectGroup.extendedRuneliteObjects) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java index f14f066e137..588eb47c9c2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java @@ -36,6 +36,7 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.NpcLootReceived; +import net.runelite.client.events.ServerNpcLoot; import javax.inject.Singleton; @@ -46,7 +47,7 @@ public class AchievementDiaryStepManager static Zone workshop; @Getter - static Requirement inWorkshop; + static ZoneRequirement inWorkshop; @Getter static RuneliteRequirement killedFire, killedEarth, killedWater, killedAir; @@ -68,7 +69,7 @@ private static void setupKandarin(ConfigManager configManager) public static void check(Client client) { - if (!inWorkshop.check(client)) + if (!Boolean.FALSE.equals(inWorkshop.getMatchedZoneLastCheck()) && !inWorkshop.check(client)) { killedFire.setConfigValue("false"); killedEarth.setConfigValue("false"); @@ -78,14 +79,27 @@ public static void check(Client client) } @Subscribe - public void onNpcLootReceived(final NpcLootReceived npcLootReceived) + public static void onServerNpcLoot(final ServerNpcLoot npcLootReceived) { - final NPC npc = npcLootReceived.getNpc(); + final var npc = npcLootReceived.getComposition(); - final int id = npc.getId(); - if (id == NpcID.ELEMENTAL_FIRE) killedFire.setConfigValue("true"); - if (id == NpcID.ELEMENTAL_EARTH) killedEarth.setConfigValue("true"); - if (id == NpcID.ELEMENTAL_WATER) killedWater.setConfigValue("true"); - if (id == NpcID.ELEMENTAL_AIR) killedAir.setConfigValue("true"); + switch (npc.getId()) + { + case NpcID.ELEMENTAL_FIRE: + killedFire.setConfigValue("true"); + break; + + case NpcID.ELEMENTAL_EARTH: + killedEarth.setConfigValue("true"); + break; + + case NpcID.ELEMENTAL_WATER: + killedWater.setConfigValue("true"); + break; + + case NpcID.ELEMENTAL_AIR: + killedAir.setConfigValue("true"); + break; + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/BarbarianTrainingStateTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/BarbarianTrainingStateTracker.java deleted file mode 100644 index f8820c67613..00000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/BarbarianTrainingStateTracker.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2024, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.statemanagement; - -import net.runelite.client.plugins.microbot.questhelper.config.ConfigKeys; -import net.runelite.client.plugins.microbot.questhelper.requirements.*; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; -import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; -import net.runelite.api.Client; -import net.runelite.api.gameval.InterfaceID; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class BarbarianTrainingStateTracker -{ - @Inject - Client client; - - Requirement taskedWithFishing, taskedWithHarpooning, taskedWithFarming, taskedWithBowFiremaking, taskedWithPyre, taskedWithPotSmashing, - taskedWithSpears, taskedWithHastae, taskedWithHerblore, plantedSeed, smashedPot, litFireWithBow, sacrificedRemains, caughtBarbarianFish, - caughtFishWithoutHarpoon, madePotion, madeSpear, madeHasta, finishedFishing, finishedHarpoon, finishedSeedPlanting, finishedPotSmashing, - finishedFiremaking, finishedPyre, finishedSpear, finishedHasta, finishedHerblore; - - RequirementValidator reqs; - - - public void startUp(ConfigManager configManager, EventBus eventBus) - { - taskedWithFishing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Certainly. Take the rod from under my bed and fish in the lake. When you have caught a few fish, I am sure you will be ready to talk more with me."), - new DialogRequirement("Alas, I do not sense that you have been successful in your fishing yet. The look in your eyes is not that of the osprey."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with a new") - ) - ); - - taskedWithHarpooning = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("... and I thought fishing was a safe way to pass the time."), - new DialogRequirement("I see you need encouragement in learning the ways of fishing without a harpoon."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with my") - ) - ); - - taskedWithFarming = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Remember to be calm, and good luck."), - new DialogRequirement("I see you have yet to be successful in planting a seed with your fists."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "plant a seed with") - ) - ); - - taskedWithPotSmashing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("May the spirits guide you into success."), - new DialogRequirement("You have not yet attempted to plant a tree. Why not?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smash pots after") - ) - ); - - taskedWithBowFiremaking = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The spirits will aid you. The power they supply will guide your hands. Go and benefit from their guidance upon oak logs."), - new DialogRequirement("By now you know my response."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "light a fire with") - ) - ); - - taskedWithPyre = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Dive into the whirlpool in the lake to the east. The spirits will use their abilities to ensure you arrive in the correct location. Be warned, their influence fades, so you must find y"), - new DialogRequirement("I will repeat myself fully, since this is quite complex. Listen well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to create pyre ships") - ) - ); - - taskedWithHerblore = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Have I become so predictable? But yes, I do indeed require a potion. It is of the highest importance that you bring me a lesser attack potion combined with fish roe."), - new DialogRequirement("Do you have my potion?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to make a new type") - ) - ); - - taskedWithSpears = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Note well that you will require wood for the spear shafts. The quality of wood must be similar to that of the metal involved."), - new DialogRequirement("You do not exude the presence of one who has poured his soul into manufacturing spears."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smith spears") - ) - ); - - taskedWithHastae = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Indeed. You may use our special anvil for this spear type too. The ways of black and dragon hastae are beyond our knowledge, however."), - new DialogRequirement("Take some wood and metal and make a spear upon the
nearby anvil, then you may return to me. As an
example, you may use bronze bars with normal logs or
iron bars with oak logs."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, " has tasked me with learning how to smith a hasta") - ) - ); - - // Finished tasks - finishedFishing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Patience young one. These are fish which are fat with eggs rather than fat of flesh. It is these eggs that are the thing to make use of."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to catch a fish with the new rod!") - ), - "Finished Barbarian Fishing" - ); - - finishedHarpoon = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I mean that when you eventually die and find peace, at least the spirits you encounter will be your friends. Alas for you adventurous sort, the natural ways of passing are close to imp"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to fish with my hands!") - ), - "Finished Barbarian Harpooning" - ); - - finishedSeedPlanting = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("No child, but we all have potential to improve our strength."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to plant a seed with my fists!") - ), - "Finished Barbarian Seed Planting" - ); - - finishedPotSmashing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("It will become more natural with practice."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smash a plant pot without littering!") - ), - "Finished Barbarian Pot Smashing" - ); - - finishedFiremaking = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Fine news indeed!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to light a fire with a bow!") - ), - "Finished Barbarian Firemaking" - ); - - finishedPyre = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("On this great day you have my eternal thanks. May you find riches while rescuing my spiritual ancestors in the caverns for many moons to come."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a pyre ship!") - ), - "Finished Barbarian Pyremaking" - ); - - finishedSpear = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The manufacture of spears is now yours as a speciality. Use your skill well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smith a spear!") - ), - "Finished Barbarian Spear Smithing" - ); - - finishedHasta = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("To live life to it's fullest of course - that you may be a peaceful spirit when your time ends."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a hasta!") - ), - "Finished Barbarian Hasta Smithing" - ); - - finishedHerblore = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I will take that off your hands now. I will say no more than that I am eternally grateful."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a new potion!") - ), - "Finished Barbarian Herblore" - ); - - // Mid-conditions - plantedSeed = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_PLANTED_SEED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to plant a seed with my fists!") - ) - ); - - smashedPot = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_SMASHED_POT.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement(" sapling"), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smash a pot without littering!") - ) - ); - - litFireWithBow = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_BOW_FIRE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The fire catches and the logs begin to burn."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to light a fire with a bow!") - ) - ); - - sacrificedRemains = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_PYRE_MADE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The ancient barbarian is laid to rest."), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to create a pyre ship! I should let") - ) - ); - - caughtBarbarianFish = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_BARBFISHED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a leaping trout.", "You catch a leaping salmon.", "You catch a leaping sturgeon."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to catch a fish with the new rod! I should let") - ) - ); - - caughtFishWithoutHarpoon = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_HARPOONED_FISH.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a raw tuna.", "You catch a swordfish.", "You catch a shark.", "You catch a shark!"), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to fish with my hands! I should let Otto know") - ) - ); - - madePotion = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_MADE_POTION.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You combine your potion with the fish eggs."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to make a new type of potion! I should let") - ) - ); - - madeSpear = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_MADE_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" spear."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a spear!") - ) - ); - - madeHasta = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_MADE_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" hasta."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a hasta!") - ) - ); - - - reqs = new RequirementValidator(client, eventBus, - taskedWithFishing, taskedWithHarpooning, taskedWithFarming, taskedWithBowFiremaking, taskedWithPyre, taskedWithPotSmashing, - taskedWithSpears, taskedWithHastae, taskedWithHerblore, plantedSeed, smashedPot, litFireWithBow, sacrificedRemains, caughtBarbarianFish, - caughtFishWithoutHarpoon, madePotion, madeSpear, madeHasta, finishedFishing, finishedHarpoon, finishedSeedPlanting, finishedPotSmashing, - finishedFiremaking, finishedPyre, finishedSpear, finishedHasta, finishedHerblore - ); - - eventBus.register(reqs); - reqs.startUp(); - } - - - public void shutDown(EventBus eventBus) - { - eventBus.unregister(reqs); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java index de991b8078b..4844da0f1c2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java @@ -26,12 +26,13 @@ import net.runelite.client.plugins.microbot.questhelper.collections.KeyringCollection; import net.runelite.client.plugins.microbot.questhelper.domain.AccountType; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; +import net.runelite.client.plugins.microbot.questhelper.managers.QuestContainerManager; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.QuestCompletedWidget; import lombok.Getter; import lombok.NonNull; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.Item; import net.runelite.api.Player; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; @@ -39,36 +40,33 @@ import net.runelite.api.events.VarbitChanged; import net.runelite.api.gameval.VarbitID; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.EventBus; +import net.runelite.client.config.RuneScapeProfileType; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; +import net.runelite.client.events.ServerNpcLoot; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.List; +import java.util.ArrayList; @Singleton public class PlayerStateManager { + private final KeyringCollection[] keyringKeys = KeyringCollection.values(); + @Inject Client client; @Inject ConfigManager configManager; - @Inject - EventBus eventBus; - @Inject QuestCompletedWidget playerQuestCompleteWidget; - @Inject - BarbarianTrainingStateTracker barbarianTrainingStateTracker; - - List keyringKeys; - WorldPoint lastPlayerPos = null; + private boolean loggedInStateKnown = false; + private RuneScapeProfileType worldType; + /** * The type of the logged in account (e.g. ironman, hardcore ironman) * Quest helpers should use this value when building their requirements instead of fetching the value themselves. @@ -78,42 +76,44 @@ public class PlayerStateManager public void startUp() { - keyringKeys = KeyringCollection.allKeyRequirements(configManager); AchievementDiaryStepManager.setup(configManager); - barbarianTrainingStateTracker.startUp(configManager, eventBus); } public void shutDown() { - barbarianTrainingStateTracker.shutDown(eventBus); } @Subscribe public void onChatMessage(ChatMessage chatMessage) { - if (keyringKeys == null || chatMessage.getType() != ChatMessageType.GAMEMESSAGE) return; + if (chatMessage.getType() != ChatMessageType.GAMEMESSAGE) return; if (chatMessage.getMessage().contains("to your key ring.")) { - for (KeyringRequirement keyringKey : keyringKeys) + for (var keyringKey : keyringKeys) { if (chatMessage.getMessage().contains("You add the " + keyringKey.chatboxText())) { - keyringKey.setConfigValue("true"); + keyringKey.setHasKeyOnKeyRing(configManager, true); + + QuestContainerManager.getKeyRingData().add(client.getTickCount(), keyringKey.getItemID(), 1); + break; } } } - if (chatMessage.getMessage().contains("from your key ring.")) + else if (chatMessage.getMessage().contains("from your key ring.")) { - for (KeyringRequirement keyringKey : keyringKeys) + for (var keyringKey : keyringKeys) { if (chatMessage.getMessage().contains("You remove the " + keyringKey.chatboxText())) { - keyringKey.setConfigValue("false"); + keyringKey.setHasKeyOnKeyRing(configManager, false); + + QuestContainerManager.getKeyRingData().removeByItemID(client.getTickCount(), keyringKey.getItemID()); + break; } } } - - if (chatMessage.getMessage().contains("Achievement Diary Stage Task - ")) + else if (chatMessage.getMessage().contains("Achievement Diary Stage Task - ")) { AchievementDiaryStepManager.check(client); } @@ -125,7 +125,7 @@ public void onGameTick(GameTick gameTick) Player player = client.getLocalPlayer(); if (player != null) { - WorldPoint newPos = Rs2Player.getWorldLocation(); + WorldPoint newPos = player.getWorldLocation(); if (newPos != null && lastPlayerPos != null) { if (newPos.distanceTo(lastPlayerPos) != 0) @@ -134,6 +134,8 @@ public void onGameTick(GameTick gameTick) } } lastPlayerPos = newPos; + + AchievementDiaryStepManager.check(client); } } @@ -160,4 +162,60 @@ public String getPlayerName() } return client.getLocalPlayer().getName(); } + + public void loadInitialStateFromConfig() + { + if (loggedInStateKnown) + { + return; + } + + var localPlayer = client.getLocalPlayer(); + if (localPlayer != null && localPlayer.getName() != null) + { + loggedInStateKnown = true; + loadState(); + } + } + + private void loadState() + { + // Only re-load from config if loading from a new profile + if (!RuneScapeProfileType.getCurrent(client).equals(worldType)) + { + // Load key ring state from config + loadKeyRingFromConfig(); + } + } + + private void loadKeyRingFromConfig() + { + var keys = new ArrayList(); + + for (var keyringKey : keyringKeys) + { + if (keyringKey.hasKeyOnKeyRing(configManager)) + { + keys.add(new Item(keyringKey.getItemID(), 1)); + } + } + + QuestContainerManager.getKeyRingData().update(client.getTickCount(), keys.toArray(new Item[0])); + } + + public void emptyState() + { + worldType = null; + } + + public void setUnknownInitialState() + { + loggedInStateKnown = false; + } + + @Subscribe + public void onServerNpcLoot(ServerNpcLoot event) + { + AchievementDiaryStepManager.onServerNpcLoot(event); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java index ef3e8947284..c3b19d18ed3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java @@ -8,7 +8,6 @@ import lombok.NonNull; import net.runelite.api.gameval.ObjectID; import net.runelite.client.ui.overlay.components.PanelComponent; - import java.util.ArrayList; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java index 9802adc2c3a..e4033952d61 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java @@ -30,7 +30,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.ChatMessageRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.MultiChatMessageRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.InitializableRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; @@ -41,13 +43,14 @@ import lombok.Setter; import net.runelite.api.GameState; import net.runelite.api.events.*; +import net.runelite.api.gameval.InterfaceID; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.components.PanelComponent; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -107,9 +110,16 @@ public ConditionalStep(QuestHelper questHelper, Integer id, QuestStep step, Stri this.id = id; } + public void addStep(ConditionalStep step) + { + var newSet = new HashSet<>(step.steps.keySet()); + newSet.remove(null); + addStep(passOnceCompleted(new Conditions(LogicType.OR, new ArrayList<>(newSet)), step), step, false); + } + public void addStep(Requirement requirement, QuestStep step) { - addStep(requirement, step, false); + addStep(passOnceCompleted(requirement, step), step, false); } // Each addStep can have an ID. When you add an ID, it keeps a separate ID to Steps OrderedHashSet. @@ -119,11 +129,49 @@ public void addStep(Requirement requirement, QuestStep step) public void addStep(Requirement requirement, QuestStep step, boolean isLockable) { step.setLockable(isLockable); - this.steps.put(requirement, step); + this.steps.put(passOnceCompleted(requirement, step), step); checkForConditions(requirement); } + private Requirement passOnceCompleted(Requirement completion, QuestStep step) + { + return completion; +// var manualOverride = step.getSidebarManualSkipRequirement(); +// if (completion == null || manualOverride == null) +// { +// return completion; +// } +// // Only auto-tick the sidebar when completion becomes true (rising edge). If we setShouldPass every +// // tick while the game still reports the step complete, an explicit untick is overwritten immediately. +// final boolean[] completionWasPassingLastCheck = { false }; +// return not(new Requirement() +// { +// @Override +// public boolean check(Client client) +// { +// if (manualOverride.check(client)) +// { +// completionWasPassingLastCheck[0] = true; +// return true; +// } +// boolean passed = completion.check(client); +// if (passed && !completionWasPassingLastCheck[0]) +// { +// manualOverride.setShouldPass(true); +// } +// completionWasPassingLastCheck[0] = passed; +// return passed; +// } +// +// @Override +// public @NotNull String getDisplayText() +// { +// return completion.getDisplayText(); +// } +// }); + } + private void checkForConditions(Requirement requirement) { checkForChatConditions(requirement); @@ -269,6 +317,17 @@ public void handleChatMessage(ChatMessage chatMessage, boolean parentDefinedRecu handleChildRequirementValidation(step -> step.handleChatMessage(chatMessage, parentDefinedRecursion), parentDefinedRecursion); } + @Subscribe + public void onWidgetClosed(WidgetClosed event) + { + final var DIALOG_GROUP_IDS = List.of(InterfaceID.CHAT_LEFT, InterfaceID.CHAT_RIGHT, InterfaceID.OBJECTBOX); + if (!DIALOG_GROUP_IDS.contains(event.getGroupId())) return; + + clientThread.invokeAtTickEnd(() -> { + dialogConditions.forEach(requirement -> requirement.validateActiveWidget(client)); + }); + } + @Subscribe public void onNpcSpawned(NpcSpawned event) { @@ -428,6 +487,7 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) .map(ItemRequirement.class::cast) .collect(Collectors.toList()); renderInventory(graphics, activeDp, itemRequirements, false); + renderBank(graphics, requirements); for (AbstractWidgetHighlight widgetHighlights : widgetsToHighlight) { widgetHighlights.highlightChoices(graphics, client, plugin); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java index 106aaf186eb..ee85486802e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java @@ -43,17 +43,17 @@ import lombok.Getter; import lombok.NonNull; import lombok.Setter; -import net.runelite.api.*; import net.runelite.api.Menu; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemDespawned; import net.runelite.api.events.ItemSpawned; -import net.runelite.api.gameval.SpriteID; import net.runelite.api.widgets.Widget; +import net.runelite.api.gameval.SpriteID; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.PluginMessage; @@ -65,8 +65,8 @@ import java.awt.*; import java.awt.image.BufferedImage; -import java.util.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -304,11 +304,6 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) return; } - if (inCutscene) - { - return; - } - if (!markedTiles.isEmpty()) { for (QuestTile location : markedTiles) @@ -359,11 +354,6 @@ public void makeWorldArrowOverlayHint(Graphics2D graphics, QuestHelperPlugin plu return; } - if (inCutscene) - { - return; - } - if (currentRender < (MAX_RENDER_SIZE / 2)) { renderArrow(graphics); @@ -378,11 +368,6 @@ public void makeWorldLineOverlayHint(Graphics2D graphics, QuestHelperPlugin plug return; } - if (inCutscene) - { - return; - } - if (linePoints != null && linePoints.size() > 1) { WorldLines.drawLinesOnWorld(graphics, client, linePoints, getQuestHelper().getConfig().targetOverlayColor()); @@ -468,6 +453,13 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) .collect(Collectors.toList()); renderInventory(graphics, definedPoint, itemRequirements, false); renderInventory(graphics, definedPoint, teleportRequirements, true); + + // TODO: Add a config to turn off as well? + if (!questHelper.getQuestHelperPlugin().isBankTabOpen()) + { + renderBank(graphics, requirements); + } + for (AbstractWidgetHighlight widgetHighlights : widgetsToHighlight) { widgetHighlights.highlightChoices(graphics, client, plugin); @@ -494,11 +486,6 @@ public void renderMapArrows(Graphics2D graphics) return; } - if (inCutscene) - { - return; - } - WorldPoint point = mapPoint.getWorldPoint(); if (currentRender < MAX_RENDER_SIZE / 2 || !getQuestHelper().getConfig().haveMinimapArrowFlash()) @@ -559,7 +546,7 @@ public void makeOverlayHint(PanelComponent panelComponent, QuestHelperPlugin plu { super.makeOverlayHint(panelComponent, plugin, additionalText, new ArrayList<>()); - if (inCutscene || hideRequirements) + if (hideRequirements) { return; } @@ -688,10 +675,6 @@ private boolean requirementContainsID(ItemRequirement requirement, Collection ids, Graphics2D graphics) { - if (inCutscene) - { - return; - } Player player = client.getLocalPlayer(); if (player == null) @@ -812,7 +795,7 @@ protected void renderHoveredMenuEntryPanel(PanelComponent panelComponent, String if (currentMenuEntries != null) { - Point mousePosition = client.getMouseCanvasPosition(); + net.runelite.api.Point mousePosition = client.getMouseCanvasPosition(); int menuX = menu.getMenuX(); int menuY = menu.getMenuY(); int menuWidth = menu.getMenuWidth(); @@ -881,7 +864,14 @@ public void setShortestPath() { return; } - var playerWp = client.getLocalPlayer().getWorldLocation(); + + var localPlayer = client.getLocalPlayer(); + if (localPlayer == null) + { + return; + } + + var playerWp = localPlayer.getWorldLocation(); if (playerWp == null) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java index 26e40a76388..048f6aec1fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java @@ -29,6 +29,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import java.awt.*; +import java.awt.image.BufferedImage; import lombok.Setter; import net.runelite.api.Player; import net.runelite.api.coords.LocalPoint; @@ -38,9 +40,6 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.OverlayUtil; -import java.awt.*; -import java.awt.image.BufferedImage; - public class DigStep extends DetailedQuestStep { private final ItemRequirement spade; @@ -97,11 +96,6 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) { super.makeWorldOverlayHint(graphics, plugin); - if (inCutscene) - { - return; - } - LocalPoint localLocation = definedPoint.resolveLocalPoint(client); if (localLocation == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java index 8eecf548eed..367ad426a6d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java @@ -98,24 +98,30 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) void scrollToWidget(Widget widget) { - final Widget parent = client.getWidget(InterfaceID.Emote.CONTENTS); + final Widget parent = client.getWidget(InterfaceID.Emote.SCROLLABLE); if (widget == null || parent == null) { return; } + int averageCentralY = 0; + int nonnullCount = 0; + averageCentralY += widget.getRelativeY() + widget.getHeight() / 2; + nonnullCount += 1; + averageCentralY /= nonnullCount; final int newScroll = Math.max(0, Math.min(parent.getScrollHeight(), - (widget.getRelativeY() + widget.getHeight() / 2) - parent.getHeight() / 2)); + averageCentralY - parent.getHeight() / 2)); client.runScript( ScriptID.UPDATE_SCROLLBAR, - InterfaceID.Emote.SCROLLBAR, - InterfaceID.Emote.CONTENTS, + InterfaceID.Emote.SCROLLBAR, + InterfaceID.Emote.SCROLLABLE, newScroll ); } + @Override protected void setupIcon() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java index 8c32b29a11a..ed3219f6ac7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java @@ -24,12 +24,12 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.steps.emote.QuestEmote; import net.runelite.client.plugins.microbot.questhelper.steps.overlay.IconOverlay; +import lombok.Getter; import net.runelite.api.ScriptID; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java index f68d90fd5e0..10610b0ed3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java @@ -25,7 +25,6 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; @@ -33,9 +32,10 @@ import net.runelite.client.plugins.microbot.questhelper.steps.overlay.DirectionArrow; import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import lombok.Getter; import lombok.Setter; -import net.runelite.api.*; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.NpcChanged; @@ -63,8 +63,8 @@ public class NpcStep extends DetailedQuestStep protected final int npcID; protected final List alternateNpcIDs = new ArrayList<>(); - @Setter @Getter + @Setter protected boolean allowMultipleHighlights; @Getter @@ -210,6 +210,19 @@ public void scanForNpcs() { addNpcToListGivenMatchingID(npc, this::npcPassesChecks, npcs); } + + /* TODO: Configurable boolean per NpcStep for whether to consider all world views + This is as you're likely to want to only highlight stuff on your own ship, not on others' + */ + for (WorldView worldView : client.getTopLevelWorldView().worldViews()) + { + if (worldView == playerWorldView) continue; + + for (NPC npc : worldView.npcs()) + { + addNpcToListGivenMatchingID(npc, this::npcPassesChecks, npcs); + } + } } public NpcStep addAlternateNpcs(Integer... alternateNpcIDs) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java index 9cf33dfdd94..36e74b78004 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; @@ -33,9 +32,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.overlay.DirectionArrow; import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import lombok.Getter; +import lombok.NonNull; import lombok.Setter; -import net.runelite.api.*; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.*; @@ -67,6 +68,11 @@ public class ObjectStep extends DetailedQuestStep @Setter private boolean revalidateObjects; + /// Force the highlight to use the clickbox highlight, regardless of the user's setting. + /// This is useful if the object you're trying to highlight is technically visible but cannot feasibly be outline-highlighted. + @Setter + private boolean forceClickboxHighlight = false; + public ObjectStep(QuestHelper questHelper, int objectID, WorldPoint worldPoint, String text, Requirement... requirements) { super(questHelper, worldPoint, text, requirements); @@ -147,11 +153,9 @@ protected void loadObjects() { // TODO: This needs to be tested in Shadow of the Storm's Demon Room objects.clear(); - loadObjectsInWorldView(client.getTopLevelWorldView()); - var playerWorldView = client.getLocalPlayer().getWorldView(); - if (playerWorldView != client.getTopLevelWorldView()) + for (WorldView worldView : client.getTopLevelWorldView().worldViews()) { - loadObjectsInWorldView(client.getLocalPlayer().getWorldView()); + loadObjectsInWorldView(worldView); } } @@ -308,11 +312,6 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) return; } - if (inCutscene) - { - return; - } - Point mousePosition = client.getMouseCanvasPosition(); if (client.getLocalPlayer() == null) @@ -352,10 +351,15 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) Color configColor = getQuestHelper().getConfig().targetOverlayColor(); - QuestHelperConfig.ObjectHighlightStyle highlightStyle = visibilityHelper.isObjectVisible(tileObject) + var isObjectVisible = visibilityHelper.isObjectVisible(tileObject); + var highlightStyle = isObjectVisible ? questHelper.getConfig().highlightStyleObjects() : CLICK_BOX; + if (highlightStyle == QuestHelperConfig.ObjectHighlightStyle.OUTLINE && forceClickboxHighlight) { + highlightStyle = QuestHelperConfig.ObjectHighlightStyle.CLICK_BOX; + } + switch (highlightStyle) { case CLICK_BOX: @@ -385,7 +389,7 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) if (iconItemID != -1 && closestObject != null && questHelper.getConfig().showSymbolOverlay()) { Shape clickbox = closestObject.getClickbox(); - if (clickbox != null && !inCutscene) + if (clickbox != null) { Rectangle2D boundingBox = clickbox.getBounds2D(); graphics.drawImage(icon, (int) boundingBox.getCenterX() - 15, (int) boundingBox.getCenterY() - 10, @@ -465,12 +469,6 @@ protected void handleObjects(TileObject object) return; } - var worldViewsToConsider = List.of(client.getTopLevelWorldView(), client.getLocalPlayer().getWorldView()); - if (!worldViewsToConsider.contains(object.getWorldView())) - { - return; - } - if (object.getId() == objectID || alternateObjectIDs.contains(object.getId())) { setObjects(object); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java index cadd9f9aa30..c1b4f4c0e76 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java @@ -9,12 +9,10 @@ import lombok.Getter; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java index 61a81e980ab..8ae37997ac2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java @@ -1,6 +1,5 @@ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; @@ -8,6 +7,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; +import lombok.Getter; import java.awt.*; import java.util.HashSet; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java index b2f10303d9e..3b42bf606c6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java @@ -32,11 +32,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.steps.choice.DialogChoiceStep; import lombok.Getter; +import net.runelite.client.plugins.microbot.questhelper.steps.choice.DialogChoiceStep; import lombok.NonNull; import net.runelite.client.ui.overlay.components.PanelComponent; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java index c5f9068481a..7102a406288 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestUtil; +import net.runelite.client.plugins.microbot.questhelper.requirements.ManualRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.choice.*; @@ -65,10 +66,11 @@ import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ImageUtil; +import javax.annotation.Nullable; import java.awt.*; import java.awt.image.BufferedImage; -import java.util.*; import java.util.List; +import java.util.*; import java.util.regex.Pattern; import static net.runelite.client.plugins.microbot.questhelper.overlays.QuestHelperOverlay.TITLED_CONTENT_COLOR; @@ -126,9 +128,7 @@ public abstract class QuestStep implements Module @Setter private Requirement lockingCondition; - private int currentCutsceneStatus = 0; - protected boolean inCutscene; - + @Getter @Setter protected boolean allowInCutscene = false; @@ -161,6 +161,24 @@ public abstract class QuestStep implements Module @Setter private boolean showInSidebar = true; + /** + * When set, the Quest Helper sidebar can show a small skip control that toggles this requirement and persists per helper. + */ + @Nullable + @Getter + @Setter + private ManualRequirement sidebarManualSkipRequirement; + + /** + * Stable id for {@link #sidebarManualSkipRequirement} persistence (e.g. maker order slot id). + */ + @Nullable + @Getter + @Setter + private String sidebarManualSkipPersistenceKey; + + + protected String lastDialogSeen = ""; @Setter @@ -248,19 +266,6 @@ public void addSubSteps(Collection substeps) @Subscribe public void onVarbitChanged(VarbitChanged event) { - if (!allowInCutscene) - { - int newCutsceneStatus = client.getVarbitValue(VarbitID.CUTSCENE_STATUS); - if (currentCutsceneStatus == 0 && newCutsceneStatus == 1) - { - enteredCutscene(); - } - else if (currentCutsceneStatus == 1 && newCutsceneStatus == 0) - { - leftCutscene(); - } - currentCutsceneStatus = newCutsceneStatus; - } } @Subscribe @@ -290,16 +295,6 @@ public void addText(String newLine) text.add(newLine); } - public void enteredCutscene() - { - inCutscene = true; - } - - public void leftCutscene() - { - inCutscene = false; - } - public void highlightChoice() { choices.checkChoices(client, lastDialogSeen); @@ -623,6 +618,45 @@ protected Widget getInventoryWidget() return client.getWidget(InterfaceID.Inventory.ITEMS); } + protected Widget getBankWidget() + { + return client.getWidget(InterfaceID.Bankmain.ITEMS); + } + + protected void renderBank(Graphics2D graphics, List passedRequirements) + { + Widget bankWidget = getBankWidget(); + if (bankWidget == null || bankWidget.isHidden()) + { + return; + } + Color baseColor = questHelper.getConfig().targetOverlayColor(); + + if (bankWidget.getDynamicChildren() == null) return; + + + for (Widget item : bankWidget.getDynamicChildren()) + { + for (Requirement requirement : passedRequirements) + { + if (isValidRequirementForRenderInBank(requirement, item)) + { + highlightItem(item, baseColor, graphics); + } + } + } + } + + private boolean isValidRequirementForRenderInBank(Requirement requirement, Widget item) + { + return requirement instanceof ItemRequirement && isValidRenderRequirementInBank((ItemRequirement) requirement, item); + } + + protected boolean isValidRenderRequirementInBank(ItemRequirement requirement, Widget item) + { + return (item.getItemId() > 0 && !item.isHidden() && requirement.getAllIds().contains(item.getItemId())); + } + protected void renderInventory(Graphics2D graphics, DefinedPoint definedPoint, List passedRequirements, boolean distanceLimit) { Widget inventoryWidget = getInventoryWidget(); @@ -649,13 +683,13 @@ protected void renderInventory(Graphics2D graphics, DefinedPoint definedPoint, L if (isValidRequirementForRenderInInventory(requirement, item)) { - highlightInventoryItem(item, baseColor, graphics); + highlightItem(item, baseColor, graphics); } } } } - private void highlightInventoryItem(Widget item, Color color, Graphics2D graphics) + private void highlightItem(Widget item, Color color, Graphics2D graphics) { Rectangle slotBounds = item.getBounds(); switch (questHelper.getConfig().highlightStyleInventoryItems()) @@ -740,4 +774,14 @@ public PuzzleWrapperStep puzzleWrapStep(boolean hiddenInSidebar) { return new PuzzleWrapperStep(getQuestHelper(), this).withNoHelpHiddenInSidebar(hiddenInSidebar); } + + public void withPersistedManualSkip(String persistenceKey) { + setSidebarManualSkipWithPersistenceKey(new ManualRequirement(), persistenceKey); + } + + public void setSidebarManualSkipWithPersistenceKey(ManualRequirement requirement, String persistenceKey) + { + setSidebarManualSkipRequirement(requirement); + setSidebarManualSkipPersistenceKey(persistenceKey); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java index bb9179ff237..23c03336cd1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java @@ -24,10 +24,10 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetDetails; +import lombok.Getter; import lombok.Setter; import net.runelite.api.widgets.Widget; @@ -39,8 +39,8 @@ public class WidgetStep extends DetailedQuestStep { - @Setter @Getter + @Setter protected List widgetDetails = new ArrayList<>(); protected List> extraWidgetOverlayHintFunctions = new ArrayList<>(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WorldEntityStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WorldEntityStep.java new file mode 100644 index 00000000000..158ea87c3dc --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WorldEntityStep.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2026, Zoinkwiz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.steps; + +import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.steps.overlay.DirectionArrow; +import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; +import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import net.runelite.api.WorldEntity; +import net.runelite.api.WorldEntityConfig; +import net.runelite.api.WorldView; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.NpcID; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.ColorUtil; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; +import java.util.Arrays; + +public class WorldEntityStep extends DetailedQuestStep +{ + public final int worldEntityConfigID; + + // Used to know where to put the hint arrow + private Shape lastFrameStructure; + + public WorldEntityStep(QuestHelper questHelper, int worldEntityConfigID, DefinedPoint definedPoint, String text, Requirement... requirements) + { + super(questHelper, definedPoint, text, requirements); + this.worldEntityConfigID = worldEntityConfigID; + } + + public WorldEntityStep(QuestHelper questHelper, int worldEntityConfigID, WorldPoint worldPoint, String text, Requirement... requirements) + { + this(questHelper, worldEntityConfigID, DefinedPoint.of(worldPoint), text, requirements); + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) + { + super.makeWorldOverlayHint(graphics, plugin); + + lastFrameStructure = null; + + WorldEntity worldEntity = findWorldEntity(); + if (worldEntity == null) return; + + // Currently fine as only one boat per world view. Perhaps in the future an issue where multiple things exist in a world view? + Shape structure = QuestPerspective.getAreaFromWorldView(client, worldEntity.getWorldView()); + if (structure == null) return; + + lastFrameStructure = structure; + + Color configColor = getQuestHelper().getConfig().targetOverlayColor(); + OverlayUtil.renderHoverableArea( + graphics, + structure, + client.getMouseCanvasPosition(), + ColorUtil.colorWithAlpha(configColor, 20), + configColor.darker(), + configColor + ); + } + + + @Override + public void renderArrow(Graphics2D graphics) + { + if (hideWorldArrow || !questHelper.getConfig().showMiniMapArrow()) + { + return; + } + + Shape structure = lastFrameStructure; + if (structure == null) + { + super.renderArrow(graphics); + return; + } + + Rectangle bounds = structure.getBounds(); + if (bounds.width <= 0 || bounds.height <= 0) + { + super.renderArrow(graphics); + return; + } + + int tipX = bounds.x + bounds.width / 2; + int tipY = bounds.y; + DirectionArrow.drawWorldArrow(graphics, getQuestHelper().getConfig().targetOverlayColor(), tipX, tipY); + } + + + private WorldEntity findWorldEntity() + { + WorldEntity worldEntity = findWorldEntityInWorldView(client.getTopLevelWorldView(), worldEntityConfigID); + if (worldEntity != null) + { + return worldEntity; + } + + for (WorldView worldView : client.getTopLevelWorldView().worldViews()) + { + worldEntity = findWorldEntityInWorldView(worldView, worldEntityConfigID); + if (worldEntity != null) + { + return worldEntity; + } + } + + return null; + } + + public static WorldEntity findWorldEntityInWorldView(WorldView worldView, int configId) + { + if (worldView == null) + { + return null; + } + + for (WorldEntity worldEntity : worldView.worldEntities()) + { + WorldEntityConfig config = worldEntity.getConfig(); + if (config != null && config.getId() == configId) + { + return worldEntity; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java index 4d291340f87..61a259381ef 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java @@ -1,10 +1,10 @@ package net.runelite.client.plugins.microbot.questhelper.steps.choice; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import java.util.Map; import lombok.Getter; import lombok.Setter; -import java.util.Map; import java.util.regex.Pattern; public class DialogChoiceStep extends WidgetChoiceStep diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java index 35f30184193..2ed8a0c4f8f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.microbot.questhelper.steps.choice; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import java.util.Map; import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; @@ -34,7 +35,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.regex.Pattern; public class WidgetChoiceStep @@ -54,6 +54,7 @@ public class WidgetChoiceStep protected int excludedGroupId; protected int excludedChildId; + @Getter private final int choiceById; @Getter @@ -64,6 +65,7 @@ public class WidgetChoiceStep protected int varbitValue = -1; protected final Map varbitValueToAnswer; + @Getter protected boolean shouldNumber = false; @Setter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java index 67cd6f540fa..b7f64b0a278 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java @@ -44,7 +44,9 @@ public enum QuestEmote STAMP("Stamp", SpriteID.Emotes.STAMP), FLAP("Flap", SpriteID.Emotes.FLAP), SLAP_HEAD("Slap Head", SpriteID.Emotes.SLAP_HEAD), - SPIN("Spin", SpriteID.Emotes.SPIN); + SALUTE("Salute", SpriteID.Emotes.SALUTE), + SPIN("Spin", SpriteID.Emotes.SPIN), + SIT("Sit", 5248); private String name; private int spriteId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java index c76e78aa950..19b56fbad7a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java @@ -33,8 +33,8 @@ import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; -import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; @@ -193,7 +193,7 @@ protected static void createMinimapDirectionArrow(Graphics2D graphics, Client cl drawMinimapArrow(graphics, line, color); } - @NotNull + @Nonnull private static Line2D.Double getLine(Point playerPosOnMinimap, Point destinationPosOnMinimap) { double xDiff = playerPosOnMinimap.getX() - destinationPosOnMinimap.getX(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java index 158e0f611eb..7794b12f2eb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java @@ -32,7 +32,6 @@ import net.runelite.api.WorldView; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; - import javax.annotation.Nullable; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java index d758cfce979..a140ee668ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java @@ -25,8 +25,16 @@ package net.runelite.client.plugins.microbot.questhelper.steps.tools; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.api.*; +import net.runelite.api.Client; +import net.runelite.api.DecorativeObject; +import net.runelite.api.GameObject; +import net.runelite.api.GroundObject; +import net.runelite.api.Perspective; import net.runelite.api.Point; +import net.runelite.api.Tile; +import net.runelite.api.WallObject; +import net.runelite.api.WorldView; +import net.runelite.api.Player; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; @@ -34,8 +42,8 @@ import net.runelite.api.widgets.Widget; import java.awt.*; -import java.util.ArrayList; -import java.util.LinkedHashSet; +import java.awt.geom.Area; +import java.util.*; import java.util.List; public class QuestPerspective @@ -77,8 +85,7 @@ public static WorldPoint getWorldPointConsideringWorldView(Client client, LocalP } var mainLocal = worldEntity.transformToMainWorld(localPoint); - return WorldPoint.fromLocal(client.getTopLevelWorldView(), - mainLocal.getX(), mainLocal.getY(), client.getTopLevelWorldView().getPlane()); + return WorldPoint.fromLocalInstance(client, mainLocal, client.getTopLevelWorldView().getPlane()); } else { @@ -123,8 +130,7 @@ public static WorldPoint getWorldPointConsideringWorldView(Client client, WorldV } var mainLocal = worldEntity.transformToMainWorld(localPoint); - return WorldPoint.fromLocal(client.getTopLevelWorldView(), - mainLocal.getX(), mainLocal.getY(), client.getTopLevelWorldView().getPlane()); + return WorldPoint.fromLocalInstance(client, mainLocal, client.getTopLevelWorldView().getPlane()); } else { @@ -266,10 +272,10 @@ public static Point getMinimapPoint(Client client, WorldPoint start, WorldPoint return null; } - final int angle = client.getCameraYawTarget() & 0x7FF; + final int angle = client.getCameraYawTarget() & 0x3FFF; - final int sin = Perspective.SINE[angle]; - final int cos = Perspective.COSINE[angle]; + final int sin = Perspective.SINE14[angle]; + final int cos = Perspective.COSINE14[angle]; final int xx = y * sin + cos * x >> 16; final int yy = sin * x - y * cos >> 16; @@ -359,6 +365,73 @@ private static void addToPoly(Client client, Polygon areaPoly, LocalPoint localP } } + public static Shape getAreaFromWorldView(Client client, WorldView view) + { + if (view == null || view.getScene() == null) + { + return null; + } + + Tile[][][] tiles = view.getScene().getTiles(); + + Area area = new Area(); + for (Tile[][] planeTiles : tiles) + { + if (planeTiles == null) continue; + for (Tile[] column : planeTiles) + { + if (column == null) continue; + for (Tile tile : column) + { + if (tile == null) continue; + addTileHulls(area, client, tile); + } + } + } + + return area.isEmpty() ? null : area; + } + + private static void addTileHulls(Area area, Client client, Tile tile) + { + GameObject[] gameObjects = tile.getGameObjects(); + if (gameObjects != null) + { + for (GameObject go : gameObjects) + { + if (go == null || !isUnnamedScenery(client, go.getId())) continue; + addHull(area, go.getConvexHull()); + } + } + + WallObject wall = tile.getWallObject(); + if (wall != null && isUnnamedScenery(client, wall.getId())) + { + addHull(area, wall.getConvexHull()); + addHull(area, wall.getConvexHull2()); + } + + GroundObject ground = tile.getGroundObject(); + if (ground != null && isUnnamedScenery(client, ground.getId())) + { + addHull(area, ground.getConvexHull()); + } + } + + private static void addHull(Area target, Shape hull) + { + if (hull != null) + { + target.add(new Area(hull)); + } + } + + private static boolean isUnnamedScenery(Client client, int objectId) + { + var def = client.getObjectDefinition(objectId); + return def != null && Objects.equals(def.getName(), "null"); + } + /** * Compares a quest-defined {@link WorldPoint} with a runtime {@link LocalPoint}, normalizing * both into the top-level world space so they can be compared safely across WorldViews. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java index 90e9ad5b2fe..2229e47193d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.microbot.questhelper.steps.widget; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.domain.QuetzalDestination; import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; @@ -38,6 +39,7 @@ public class WidgetHighlight extends AbstractWidgetHighlight { @Getter protected final int interfaceID; + @Getter protected final int childChildId; @@ -138,6 +140,18 @@ public static WidgetHighlight createShopItemHighlight(int itemIdRequirement) return w; } + /** + * Create a widget highlight that highlights the given destination in the quetzal interface + * @param quetzalDestination The quetzal destination to highlight + * @return a fully built WidgetHighlight + */ + public static WidgetHighlight createQuetzalHighlight(QuetzalDestination quetzalDestination) + { + var w = new WidgetHighlight(InterfaceID.QuetzalMenu.ICONS, true); + w.modelIdRequirement = quetzalDestination.modelID; + return w; + } + @Override public void highlightChoices(Graphics2D graphics, Client client, QuestHelperPlugin questHelper) { @@ -154,6 +168,7 @@ private void highlightChoices(Widget parentWidget, Graphics2D graphics, QuestHel Widget[] widgets = parentWidget.getChildren(); Widget[] staticWidgets = parentWidget.getStaticChildren(); + var dynamicWidgets = parentWidget.getDynamicChildren(); if (childChildId != -1 && widgets != null) { @@ -171,6 +186,10 @@ private void highlightChoices(Widget parentWidget, Graphics2D graphics, QuestHel { highlightChoices(widget, graphics, questHelper); } + for (var widget : dynamicWidgets) + { + highlightChoices(widget, graphics, questHelper); + } } highlightWidget(graphics, questHelper, parentWidget); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java index 11b51401499..5dfacb00f89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java @@ -36,7 +36,6 @@ import net.runelite.api.gameval.VarbitID; import net.runelite.client.util.ColorUtil; import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import java.awt.*; @@ -52,7 +51,7 @@ public class Utils * @return {@link AccountType} * @apiNote This function should only be called from the client thread. */ - public AccountType getAccountType(@NotNull Client client) + public AccountType getAccountType(@Nonnull Client client) { if (client.getGameState() != GameState.LOGGED_IN) {