From 3118be0896ddce50fc9bbc7aa49e84d2401df202 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 23 Apr 2019 09:48:19 +0100 Subject: [PATCH] 1 way PVP Safespots 1 way PVP Safespots --- .../plugins/safespot/SafeSpotConfig.java | 43 ++++++ .../plugins/safespot/SafeSpotOverlay.java | 58 +++++++ .../plugins/safespot/SafeSpotPlugin.java | 141 ++++++++++++++++++ 3 files changed, 242 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java new file mode 100644 index 0000000000..bf2068863a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotConfig.java @@ -0,0 +1,43 @@ +package net.runelite.client.plugins.safespot; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("safespot") +public interface SafeSpotConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "playerSafeSpots", + name = "Render for Players", + description = "Renders 1 way safe spots vs other players" + ) + default boolean playerSafeSpots() + { + return true; + } + + @ConfigItem( + position = 2, + keyName = "npcSafeSpots", + name = "Render for NPCs", + description = "Renders 1 way safe spots vs NPCs" + ) + default boolean npcSafeSpots() + { + return false; + } + + @ConfigItem( + position = 3, + keyName = "tileColor", + name = "Tile Color", + description = "Color of safe spot tile" + ) + default Color tileColor() + { + return Color.MAGENTA; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java new file mode 100644 index 0000000000..30afe5f4a7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotOverlay.java @@ -0,0 +1,58 @@ +package net.runelite.client.plugins.safespot; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; + +public class SafeSpotOverlay extends Overlay +{ + + private final Client client; + private final SafeSpotPlugin safeSpotPlugin; + private final SafeSpotConfig config; + + @Inject + public SafeSpotOverlay(Client client, SafeSpotPlugin safeSpotPlugin, SafeSpotConfig config) + { + this.client = client; + this.safeSpotPlugin = safeSpotPlugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.LOW); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (safeSpotPlugin.isSafeSpotsRenderable()) + { + if(safeSpotPlugin.getSafeSpotList() != null) + { + if (safeSpotPlugin.getSafeSpotList().size() > 0) + { + safeSpotPlugin.getSafeSpotList().forEach(tile -> + { + if (tile != null && tile.getLocalLocation() != null) + { + final Polygon poly = Perspective.getCanvasTilePoly(client, tile.getLocalLocation()); + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, config.tileColor()); + } + } + }); + } + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java new file mode 100644 index 0000000000..e8fdd91734 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java @@ -0,0 +1,141 @@ +package net.runelite.client.plugins.safespot; + +import com.google.inject.Provides; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.api.Tile; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.InteractingChanged; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginManager; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "1 Way PVP Safe Spots", + description = "Renders tile overlays for one way safe spots", + tags = {"safe spot", "pvp", "safespots", "pklite"}, + enabledByDefault = false, + type = PluginType.PVP +) +public class SafeSpotPlugin extends Plugin +{ + + @Inject + private Client client; + @Inject + OverlayManager overlayManager; + @Inject + private SafeSpotConfig config; + + @Getter + private ArrayList safeSpotList; + @Getter + private boolean safeSpotsRenderable = false; + + private SafeSpotOverlay safeSpotOverlay; + private int tickCount = 0; + + @Provides + SafeSpotConfig config(ConfigManager configManager) + { + return configManager.getConfig(SafeSpotConfig.class); + } + + @Override + protected void startUp() throws Exception + { + safeSpotOverlay = new SafeSpotOverlay(client, this, config); + overlayManager.add(safeSpotOverlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(safeSpotOverlay); + } + + @Subscribe + private void onInteractingChanged(InteractingChanged event) + { + if (event.getSource() != client.getLocalPlayer()) + { + return; + } + if (event.getTarget() == null && (config.npcSafeSpots() || config.playerSafeSpots())) + { + tickCount = 10; + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (client.getLocalPlayer().getInteracting() != null) + { + if (client.getLocalPlayer().getInteracting() instanceof Player && config.playerSafeSpots()) + { + safeSpotsRenderable = true; + updateSafeSpots(); + } + if (client.getLocalPlayer().getInteracting() instanceof NPC && config.npcSafeSpots()) + { + safeSpotsRenderable = true; + updateSafeSpots(); + } + } + else + { + safeSpotsRenderable = false; + } + if (tickCount > 0) + { + tickCount--; + safeSpotsRenderable = true; + } + } + + private void updateSafeSpots() + { + if (client.getLocalPlayer().getInteracting() != null) + { + Actor enemy = client.getLocalPlayer().getInteracting(); + WorldArea worldArea = new WorldArea(enemy.getWorldLocation().getX() - 12, + enemy.getWorldLocation().getY() - 12, 24, 24, client.getPlane()); + List worldPoints = worldArea.toWorldPointList(); + safeSpotList = getSafeSpotList(enemy, worldPoints); + } + } + + + private ArrayList getSafeSpotList(Actor actor, List worldPoints) + { + ArrayList safeSpotList = new ArrayList<>(); + Tile[][][] tiles = client.getScene().getTiles(); + for (WorldPoint w:worldPoints) + { + LocalPoint toPoint = LocalPoint.fromWorld(client, w); + Tile fromTile = tiles[client.getPlane()][actor.getLocalLocation().getSceneX()] + [actor.getLocalLocation().getSceneY()]; + Tile toTile = tiles[client.getPlane()][toPoint.getSceneX()] + [toPoint.getSceneY()]; + if (toTile.hasLineOfSightTo(fromTile) && !fromTile.hasLineOfSightTo(toTile)) + { + safeSpotList.add(toTile); + } + } + return safeSpotList; + } +}