From cae15dfe5e693b0a20806e450a85c1dd49d53353 Mon Sep 17 00:00:00 2001 From: xKylee <48519776+xKylee@users.noreply.github.com> Date: Thu, 19 Sep 2019 00:28:52 +0100 Subject: [PATCH] bronzemanmode essentially restricts you to an IM, but you can use the GE for items you have already obtained. been highly requested. --- .../plugins/bronzeman/BronzeManOverlay.java | 89 ++++++ .../plugins/bronzeman/BronzemanPlugin.java | 284 ++++++++++++++++++ .../client/plugins/bronzeman/ItemUnlock.java | 47 +++ 3 files changed, 420 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzeManOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzemanPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/ItemUnlock.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzeManOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzeManOverlay.java new file mode 100644 index 0000000000..2f10fbe748 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzeManOverlay.java @@ -0,0 +1,89 @@ +package net.runelite.client.plugins.bronzeman; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import javax.inject.Inject; +import java.awt.image.BufferedImage; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + + +/** + * @author Seth Davis + * @Email + * @Discord Reminisce#1707 + */ +public class BronzeManOverlay extends Overlay +{ + + private final Client client; + private final BronzemanPlugin plugin; + private final List itemUnlockList; + private ItemUnlock currentUnlock; + @Inject + private ItemManager itemManager; + + @Inject + public BronzeManOverlay(Client client, BronzemanPlugin plugin) + { + this.client = client; + this.plugin = plugin; + this.itemUnlockList = new CopyOnWriteArrayList<>(); + setPosition(OverlayPosition.TOP_CENTER); + } + + void addItemUnlock(int itemId) + { + itemUnlockList.add(new ItemUnlock(itemId)); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return null; + } + if (itemUnlockList.isEmpty()) + { + return null; + } + if (itemManager == null) + { + System.out.println("Item-manager is null"); + return null; + } + if (currentUnlock == null) + { + currentUnlock = itemUnlockList.get(0); + currentUnlock.display(); + return null; + } + + int drawY = currentUnlock.getLocationY(); + // Drawing unlock pop-up in a static location because this is how the game-mode is. + graphics.drawImage(plugin.getUnlockImage(), -62, drawY, null); + graphics.drawImage(getImage(currentUnlock.getItemId()), -50, drawY + 7, null); + if (drawY < 10) + { + currentUnlock.setLocationY(drawY + 1); + } + if (currentUnlock.displayed()) + { + itemUnlockList.remove(currentUnlock); + currentUnlock = null; + } + return null; + } + + private BufferedImage getImage(int itemID) + { + return itemManager.getImage(itemID, 1, false); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzemanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzemanPlugin.java new file mode 100644 index 0000000000..aa966c004a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/BronzemanPlugin.java @@ -0,0 +1,284 @@ +package net.runelite.client.plugins.bronzeman; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.InputStream; +import java.io.PrintWriter; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.Item; +import net.runelite.api.ItemID; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.RuneLite; +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import javax.imageio.ImageIO; +import javax.inject.Inject; +import java.awt.image.BufferedImage; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Seth Davis + * @Email + * @Discord Reminisce#1707 + */ +@PluginDescriptor( + name = "Bronze Man Mode", + description = "Show boss spawn timer overlays", + tags = {"combat", "pve", "overlay", "pvp", "challenge", "bronzeman", "ironman"}, + enabledByDefault = false +) +@Slf4j +public class BronzemanPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private EventBus eventBus; + + @Inject + private OverlayManager overlayManager; + + @Inject + private BronzeManOverlay bronzemanOverlay; + + private List unlockedItems; + + @Getter + private BufferedImage unlockImage = null; + /** + * Loads GrandExchange widgets for further manipulation of the interface + **/ + private Widget grandExchangeWindow; + private Widget grandExchangeChatBox; + + @Override + protected void startUp() throws Exception + { + addSubscriptions(); + loadUnlockImage(); + unlockedItems = new ArrayList<>(); + overlayManager.add(bronzemanOverlay); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + unlockedItems = null; + overlayManager.remove(bronzemanOverlay); + } + + private void addSubscriptions() + { + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + + } + + /** + * Loads players unlocks on login + **/ + public void onGameStateChanged(GameStateChanged e) + { + if (e.getGameState() == GameState.LOGGED_IN) + { + loadPlayerUnlocks(); + } + } + + /** + * Unlocks all new items that are currently not unlocked + **/ + public void onItemContainerChanged(ItemContainerChanged e) + { + for (Item i : e.getItemContainer().getItems()) + { + if (i == null) + { + continue; + } + if (i.getId() <= 1) + { + continue; + } + if (i.getQuantity() <= 0) + { + continue; + } + if (!unlockedItems.contains(i.getId())) + { + queueItemUnlock(i.getId()); + } + } + } + + public void onWidgetLoaded(WidgetLoaded e) + { + switch (e.getGroupId()) + { + case WidgetID.GRAND_EXCHANGE_GROUP_ID: + grandExchangeWindow = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER); + break; + case WidgetID.CHATBOX_GROUP_ID: + grandExchangeWindow = null; + grandExchangeChatBox = client.getWidget(WidgetInfo.CHATBOX); + break; + } + } + + /** + * Handles greying out items in the GrandExchange + **/ + public void onGameTick(GameTick e) + { + if (grandExchangeWindow == null || grandExchangeChatBox == null || grandExchangeWindow.isHidden()) + { + return; + } + if (client.getWidget(162, 53) == null) + { + return; + } + Widget[] children = client.getWidget(162, 53).getChildren(); + if (children == null) + { + return; + } + for (int i = 0; i < children.length; i += 3) + { + if (children[i] == null) + { + continue; + } + if (i + 2 > children.length - 1) + { + continue; + } + if (!unlockedItems.contains(children[i + 2].getItemId())) + { + children[i].setHidden(true); + children[i + 1].setOpacity(70); + children[i + 2].setOpacity(70); + } + } + } + + /** + * Queues a new unlock to be properly displayed + **/ + public void queueItemUnlock(int itemId) + { + unlockedItems.add(itemId); + bronzemanOverlay.addItemUnlock(itemId); + savePlayerUnlocks();// Save after every item to fail-safe logging out + } + + /** + * Unlocks default items like a bond to a newly made profile + **/ + private void unlockDefaultItems() + { + queueItemUnlock(ItemID.COINS_995); + queueItemUnlock(ItemID.OLD_SCHOOL_BOND); + } + + /** + * Saves players unlocks to a .txt file every time they unlock a new item + **/ + private void savePlayerUnlocks() + { + try + { + File playerFolder = new File(RuneLite.PROFILES_DIR, client.getUsername()); + File playerFile = new File(playerFolder, "bronzeman-unlocks.txt"); + PrintWriter w = new PrintWriter(playerFile); + for (int itemId : unlockedItems) + { + w.println(itemId); + } + w.close(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Loads a players unlcoks everytime they login + **/ + private void loadPlayerUnlocks() + { + unlockedItems.clear(); + try + { + File playerFolder = new File(RuneLite.PROFILES_DIR, client.getUsername()); + if (!playerFolder.exists()) + { + playerFolder.mkdirs(); + } + File playerFile = new File(playerFolder, "bronzeman-unlocks.txt"); + if (!playerFile.exists()) + { + playerFile.createNewFile(); + unlockDefaultItems(); + } + else + { + BufferedReader r = new BufferedReader(new FileReader(playerFile)); + String l; + while ((l = r.readLine()) != null) + { + unlockedItems.add(Integer.parseInt(l)); + } + r.close(); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Downloads the item-unlock png file to display unlocks + **/ + private void loadUnlockImage() + { + try + { + File imageFile = new File(RuneLite.RUNELITE_DIR, "item-unlocked.png"); + if (!imageFile.exists()) + { + InputStream in = new URL("https://i.imgur.com/KWVNlsq.png").openStream(); + Files.copy(in, Paths.get(imageFile.getPath())); + } + unlockImage = ImageIO.read(imageFile); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/ItemUnlock.java b/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/ItemUnlock.java new file mode 100644 index 0000000000..f061bb5b9c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bronzeman/ItemUnlock.java @@ -0,0 +1,47 @@ +package net.runelite.client.plugins.bronzeman; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author Seth Davis + * @Email + * @Discord Reminisce#1707 + */ +public class ItemUnlock +{ + + @Getter + private final int itemId; + + @Getter + private long initTime; + + @Getter + @Setter + private int locationY; + + ItemUnlock(int itemId) + { + this.itemId = itemId; + this.locationY = -20; + this.initTime = -1; + } + + /** + * Starts the displaying of the item unlock + **/ + public void display() + { + this.initTime = System.currentTimeMillis(); + } + + /** + * Returns whether or not an items has been displayed as unlocked yet + **/ + public boolean displayed() + { + return System.currentTimeMillis() > initTime + (5000); + } + +}