diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsConfig.java new file mode 100644 index 0000000000..ed11f0cc5b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsConfig.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2019, gazivodag + * 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.pileindicators; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Range; + +import java.awt.*; + +@ConfigGroup("pileindicators") +public interface PileIndicatorsConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "enablePlayers", + name = "Enable Player Piling", + description = "Enable the option to highlight players when they pile.", + group = "1. Player Piles" + ) + default boolean enablePlayers() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "wildyOnlyPlayer", + name = "Wilderness Only", + description = "Show player piling only when in the Wilderness.", + group = "1. Player Piles" + ) + default boolean wildyOnlyPlayer() + { + return true; + } + + @ConfigItem( + position = 3, + keyName = "enableNPCS", + name = "Enable NPC Piling", + description = "Enable the option to highlight NPCs when they pile.", + group = "2. NPC Piles" + ) + default boolean enableNPCS() + { + return false; + } + + @ConfigItem( + position = 2, + keyName = "playerPileColor", + name = "Player Pile Color", + description = "Color used for player piles.", + group = "1. Player Piles" + ) + default Color playerPileColor() + { + return Color.RED; + } + + @ConfigItem( + position = 4, + keyName = "npcPileColor", + name = "NPC Pile Color", + description = "Color used for NPC piles.", + group = "2. NPC Piles" + ) + default Color npcPileColor() + { + return Color.BLUE; + } + + @ConfigItem( + position = 5, + keyName = "mixedPileColor", + name = "Mixed Pile Color", + description = "Color used for mixed piles.", + group = "3. Mixed Piles" + ) + default Color mixedPileColor() + { + return new Color(255, 0, 255); + } + + @Range( + min = 2 + ) + @ConfigItem( + position = 6, + keyName = "minimumPileSize", + name = "Minimum Pile Size", + description = "Any pile under this size will not show up. (Minimum: 2)", + group = "4. Pile Size" + ) + default int minimumPileSize() + { + return 2; + } + + @ConfigItem( + position = 7, + keyName = "numberOnly", + name = "Display Number Only", + description = "Shorten \"PILE SIZE: 1\" to \"1\"", + group = "5. Miscellaneous" + ) + default boolean numberOnly() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsOverlay.java new file mode 100644 index 0000000000..98bb064132 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsOverlay.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019, gazivodag + * 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.pileindicators; + +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; +import java.awt.*; +import java.util.ArrayList; + +public class PileIndicatorsOverlay extends Overlay +{ + + private final Client client; + private final PileIndicatorsPlugin plugin; + private final PileIndicatorsConfig config; + + @Inject + PileIndicatorsOverlay(final Client client, final PileIndicatorsPlugin plugin, final PileIndicatorsConfig config) + { + super(plugin); + this.client = client; + this.plugin = plugin; + this.config = config; + + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + + @Override + public Dimension render(Graphics2D graphics) + { + ArrayList> stackList = plugin.getStacks(); + + if (stackList != null) + { + for (ArrayList actorArrayList : stackList) + { + PileType pileType = plugin.getPileType(actorArrayList); + Color pileColor = plugin.getColorByPileType(pileType); + + try + { + Actor actorToRender = actorArrayList.get(0); //guaranteed to have at least two players + final String text; + if (config.numberOnly()) + { + text = "" + actorArrayList.size(); + } + else + { + text = "PILE SIZE: " + actorArrayList.size(); + } + + OverlayUtil.renderPolygon(graphics, actorToRender.getCanvasTilePoly(), pileColor); + OverlayUtil.renderTextLocation(graphics, actorToRender.getCanvasTextLocation(graphics, text, 40), text, pileColor); + } + catch (Exception ignored) + { + } + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsPlugin.java new file mode 100644 index 0000000000..00d3925d58 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsPlugin.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2019, gazivodag + * 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.pileindicators; + +import com.google.inject.Binder; +import com.google.inject.Provides; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.ui.overlay.OverlayManager; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.awt.*; +import java.util.ArrayList; + +@Singleton +@Slf4j +@PluginDescriptor( + name = "Pile Indicators", + description = "Highlight and count how many npcs/players are stacked on each other.", + tags = {"overlay", "pile", "stack", "pvp", "pvm", "pve"}, + enabledByDefault = false, + type = PluginType.UTILITY +) +public class PileIndicatorsPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private PileIndicatorsConfig config; + + @Inject + private OverlayManager overlayManager; + + @Inject + private PileIndicatorsOverlay overlay; + + @Provides + PileIndicatorsConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(PileIndicatorsConfig.class); + } + + @Override + public void configure(Binder binder) + { + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + } + + protected ArrayList> getStacks() + { + ArrayList> outerArrayList = new ArrayList<>(); + + ArrayList pileList = new ArrayList<>(); + + if (config.enableNPCS()) + { + for (NPC npc : client.getNpcs()) + { + if (npc != null) + { + pileList.add(npc); + } + } + } + + if (config.enablePlayers()) + { + if ((client.getVar(Varbits.IN_WILDERNESS) > 0 && config.wildyOnlyPlayer()) ^ (!config.wildyOnlyPlayer())) + { + for (Player player : client.getPlayers()) + { + if (player != null) + { + pileList.add(player); + } + } + } + } + + if (pileList.size() == 0) + { + return null; + } + + for (Actor actor : pileList) + { + ArrayList potentialStackArrayList = new ArrayList<>(); + for (Actor actorToCompareTo : pileList) + { + if (!potentialStackArrayList.contains(actorToCompareTo)) + { + if (actor.getWorldLocation().distanceTo(actorToCompareTo.getWorldLocation()) == 0) + { + potentialStackArrayList.add(actorToCompareTo); + } + } + } + if (potentialStackArrayList.size() >= config.minimumPileSize()) + { + outerArrayList.add(potentialStackArrayList); + } + } + + return outerArrayList.size() != 0 ? outerArrayList : null; + } + + protected Color getColorByPileType(PileType pileType) + { + switch (pileType) + { + case PLAYER_PILE: + return config.playerPileColor(); + case NPC_PILE: + return config.npcPileColor(); + case MIXED_PILE: + return config.mixedPileColor(); + } + return null; + } + + protected PileType getPileType(ArrayList pile) + { + PileType pileType = null; + + for (Actor actor : pile) + { + if (actor instanceof NPC && pileType == null) + { + pileType = PileType.NPC_PILE; + } + if (actor instanceof Player && pileType == null) + { + pileType = PileType.PLAYER_PILE; + } + if (actor instanceof Player && pileType == PileType.NPC_PILE) + { + pileType = PileType.MIXED_PILE; + } + if (actor instanceof NPC && pileType == PileType.PLAYER_PILE) + { + pileType = PileType.MIXED_PILE; + } + } + return pileType; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileType.java b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileType.java new file mode 100644 index 0000000000..78cebd9d19 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileType.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, gazivodag + * 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.pileindicators; + +public enum PileType +{ + PLAYER_PILE, + NPC_PILE, + MIXED_PILE +}