Add AoE warning plugin

This commit is contained in:
Toocanzs
2017-11-26 11:04:09 -05:00
committed by Adam
parent d0cb93c433
commit 541cf986c5
9 changed files with 660 additions and 7 deletions

View File

@@ -244,13 +244,41 @@ public class Perspective
*/ */
public static Polygon getCanvasTilePoly(Client client, Point localLocation) public static Polygon getCanvasTilePoly(Client client, Point localLocation)
{ {
int plane = client.getPlane(); return getCanvasTileAreaPoly(client, localLocation, 1);
int halfTile = Perspective.LOCAL_TILE_SIZE / 2; }
Point p1 = Perspective.worldToCanvas(client, localLocation.getX() - halfTile, localLocation.getY() - halfTile, plane); /**
Point p2 = Perspective.worldToCanvas(client, localLocation.getX() - halfTile, localLocation.getY() + halfTile, plane); * Returns a polygon representing an area.
Point p3 = Perspective.worldToCanvas(client, localLocation.getX() + halfTile, localLocation.getY() + halfTile, plane); *
Point p4 = Perspective.worldToCanvas(client, localLocation.getX() + halfTile, localLocation.getY() - halfTile, plane); * @param client
* @param localLocation Center location of the AoE
* @param size size of the area. Ex. Lizardman Shaman AoE is a 3x3, so
* size = 3
* @return a polygon representing the tiles in the area
*/
public static Polygon getCanvasTileAreaPoly(Client client, Point localLocation, int size)
{
int plane = client.getPlane();
int halfTile = LOCAL_TILE_SIZE / 2;
// If the size is 5, we need to shift it up and left 2 units, then expand by 5 units to make a 5x5
int aoeSize = size / 2;
// Shift over one half tile as localLocation is the center point of the tile, and then shift the area size
Point topLeft = new Point(localLocation.getX() - (aoeSize * LOCAL_TILE_SIZE) - halfTile,
localLocation.getY() - (aoeSize * LOCAL_TILE_SIZE) - halfTile);
// expand by size
Point bottomRight = new Point(topLeft.getX() + size * LOCAL_TILE_SIZE,
topLeft.getY() + size * LOCAL_TILE_SIZE);
// Take the x of top left and the y of bottom right to create bottom left
Point bottomLeft = new Point(topLeft.getX(), bottomRight.getY());
// Similarly for top right
Point topRight = new Point(bottomRight.getX(), topLeft.getY());
Point p1 = worldToCanvas(client, topLeft.getX(), topLeft.getY(), plane);
Point p2 = worldToCanvas(client, topRight.getX(), topRight.getY(), plane);
Point p3 = worldToCanvas(client, bottomRight.getX(), bottomRight.getY(), plane);
Point p4 = worldToCanvas(client, bottomLeft.getX(), bottomLeft.getY(), plane);
if (p1 == null || p2 == null || p3 == null || p4 == null) if (p1 == null || p2 == null || p3 == null || p4 == null)
{ {

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.api;
public class ProjectileID
{
public static final int LIZARDMAN_SHAMAN_AOE = 1293;
public static final int ICE_DEMON_RANGED_AOE = 1324;
public static final int ICE_DEMON_ICE_BARRAGE_AOE = 366;
public static final int VASA_AWAKEN_AOE = 1327;
public static final int VASA_RANGED_AOE = 1329;
public static final int TEKTON_METEOR_AOE = 660;
}

View File

@@ -34,6 +34,8 @@ import net.runelite.api.MainBufferProvider;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MessageNode; import net.runelite.api.MessageNode;
import net.runelite.api.PacketBuffer; import net.runelite.api.PacketBuffer;
import net.runelite.api.Point;
import net.runelite.api.Projectile;
import net.runelite.api.Skill; import net.runelite.api.Skill;
import net.runelite.client.RuneLite; import net.runelite.client.RuneLite;
import net.runelite.client.events.*; import net.runelite.client.events.*;
@@ -186,7 +188,7 @@ public class Hooks
public static void menuActionHook(int var0, int widgetId, int menuAction, int id, String menuOption, String menuTarget, int var6, int var7) public static void menuActionHook(int var0, int widgetId, int menuAction, int id, String menuOption, String menuTarget, int var6, int var7)
{ {
/* Along the way, the RuneScape client may change a menuAction by incrementing it with 2000. /* Along the way, the RuneScape client may change a menuAction by incrementing it with 2000.
* I have no idea why, but it does. Their code contains the same conditional statement. * I have no idea why, but it does. Their code contains the same conditional statement.
*/ */
if (menuAction >= 2000) if (menuAction >= 2000)
{ {
@@ -231,6 +233,27 @@ public class Hooks
eventBus.post(chatMessage); eventBus.post(chatMessage);
} }
/**
* Called when a projectile is set to move towards a point. For
* projectiles that target the ground, like AoE projectiles from
* Lizardman Shamans, this is only called once
*
* @param projectile The projectile being moved
* @param targetX X position of where the projectile is being moved to
* @param targetY Y position of where the projectile is being moved to
* @param targetZ Z position of where the projectile is being moved to
* @param cycle
*/
public static void projectileMoved(Projectile projectile, int targetX, int targetY, int targetZ, int cycle)
{
Point position = new Point(targetX, targetY);
ProjectileMoved projectileMoved = new ProjectileMoved();
projectileMoved.setProjectile(projectile);
projectileMoved.setPosition(position);
projectileMoved.setPlane(targetZ);
eventBus.post(projectileMoved);
}
public static void setMessage(MessageNode messageNode, int type, String name, String sender, String value) public static void setMessage(MessageNode messageNode, int type, String name, String sender, String value)
{ {
// Hook is fired prior to actually setting these on the MessageNode, so send them // Hook is fired prior to actually setting these on the MessageNode, so send them

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.events;
import net.runelite.api.Point;
import net.runelite.api.Projectile;
public class ProjectileMoved
{
private Projectile projectile;
private Point position;
private int plane;
public Projectile getProjectile()
{
return projectile;
}
public void setProjectile(Projectile projectile)
{
this.projectile = projectile;
}
public Point getPosition()
{
return position;
}
public void setPosition(Point position)
{
this.position = position;
}
public int getPlane()
{
return plane;
}
public void setPlane(int plane)
{
this.plane = plane;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.aoewarnings;
import java.time.Instant;
import net.runelite.api.Point;
public class AoeProjectile
{
private final Instant startTime;
private final Point targetPoint;
private final AoeProjectileInfo aoeProjectileInfo;
public AoeProjectile(Instant startTime, Point targetPoint, AoeProjectileInfo aoeProjectileInfo)
{
this.startTime = startTime;
this.targetPoint = targetPoint;
this.aoeProjectileInfo = aoeProjectileInfo;
}
public Instant getStartTime()
{
return startTime;
}
public Point getTargetPoint()
{
return targetPoint;
}
public AoeProjectileInfo getAoeProjectileInfo()
{
return aoeProjectileInfo;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.aoewarnings;
import java.time.Duration;
import net.runelite.api.ProjectileID;
public enum AoeProjectileInfo
{
LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 3000, 3),
ICE_DEMON_RANGED_AOE(ProjectileID.ICE_DEMON_RANGED_AOE, 3000, 3),
/**
* When you don't have pray range on ice demon does an ice barrage
*/
ICE_DEMON_ICE_BARRAGE_AOE(ProjectileID.ICE_DEMON_ICE_BARRAGE_AOE, 3000, 3),
/**
* The AOE when vasa first starts
*/
VASA_AWAKEN_AOE(ProjectileID.VASA_AWAKEN_AOE, 4500, 3),
VASA_RANGED_AOE(ProjectileID.VASA_RANGED_AOE, 3000, 3),
TEKTON_METEOR_AOE(ProjectileID.TEKTON_METEOR_AOE, 4000, 3);
/**
* The id of the projectile to trigger this AoE warning
*/
private final int id;
/**
* How long the indicator should last for this AoE warning This might
* need to be a bit longer than the projectile actually takes to land as
* there is a fade effect on the warning
*/
private final Duration lifeTime;
/**
* The size of the splash radius of the AoE warning Ex. Lizardman shaman
* AoE is a 3x3, so aoeSize = 3
*/
private final int aoeSize;
AoeProjectileInfo(int id, int lifeTimeMillis, int aoeSize)
{
this.id = id;
this.lifeTime = Duration.ofMillis(lifeTimeMillis);
this.aoeSize = aoeSize;
}
public Duration getLifeTime()
{
return lifeTime;
}
public int getId()
{
return id;
}
public int getAoeSize()
{
return aoeSize;
}
public static AoeProjectileInfo getById(int id)
{
for (AoeProjectileInfo aoeProjectileInfo : values())
{
if (id == aoeProjectileInfo.getId())
{
return aoeProjectileInfo;
}
}
return null;
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.aoewarnings;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup(
keyName = "aoewarning",
name = "AoE Projectile Warnings",
description = "Configuration for the AoE Projectile Warnings plugin"
)
public interface AoeWarningConfig extends Config
{
@ConfigItem(
keyName = "enabled",
name = "AoE Warnings Enabled",
description = "Configures whether or not AoE Projectile Warnings plugin is displayed"
)
default boolean enabled()
{
return true;
}
@ConfigItem(
keyName = "lizardmanaoe",
name = "Lizardman Shamans",
description = "Configures whether or not AoE Projectile Warnings for Lizardman Shamans is displayed"
)
default boolean isShamansEnabled()
{
return true;
}
@ConfigItem(
keyName = "icedemon",
name = "Ice Demon",
description = "Configures whether or not AoE Projectile Warnings for Ice Demon is displayed"
)
default boolean isIceDemonEnabled()
{
return true;
}
@ConfigItem(
keyName = "vasa",
name = "Vasa",
description = "Configures whether or not AoE Projectile Warnings for Vasa is displayed"
)
default boolean isVasaEnabled()
{
return true;
}
@ConfigItem(
keyName = "tekton",
name = "Tekton",
description = "Configures whether or not AoE Projectile Warnings for Tekton is displayed"
)
default boolean isTektonEnabled()
{
return true;
}
@ConfigItem(
keyName = "outline",
name = "Display Outline",
description = "Configures whether or not AoE Projectile Warnings have an outline"
)
default boolean isOutlineEnabled()
{
return true;
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.aoewarnings;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.time.Instant;
import java.util.Iterator;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.Perspective;
import net.runelite.api.Projectile;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
public class AoeWarningOverlay extends Overlay
{
private static final int FILL_START_ALPHA = 25;
private static final int OUTLINE_START_ALPHA = 255;
private final Client client;
private final AoeWarningPlugin plugin;
private final AoeWarningConfig config;
@Inject
public AoeWarningOverlay(@Nullable Client client, AoeWarningPlugin plugin, AoeWarningConfig config)
{
super(OverlayPosition.DYNAMIC);
this.client = client;
this.plugin = plugin;
this.config = config;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (client.getGameState() != GameState.LOGGED_IN || !config.enabled())
{
return null;
}
Instant now = Instant.now();
Map<Projectile, AoeProjectile> projectiles = plugin.getProjectiles();
for (Iterator<AoeProjectile> it = projectiles.values().iterator(); it.hasNext();)
{
AoeProjectile aoeProjectile = it.next();
if (now.isAfter(aoeProjectile.getStartTime().plus(aoeProjectile.getAoeProjectileInfo().getLifeTime())))
{
it.remove();
continue;
}
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, aoeProjectile.getTargetPoint(), aoeProjectile.getAoeProjectileInfo().getAoeSize());
if (tilePoly == null)
{
continue;
}
// how far through the projectiles lifetime between 0-1.
double progress = (System.currentTimeMillis() - aoeProjectile.getStartTime().toEpochMilli()) / (double) aoeProjectile.getAoeProjectileInfo().getLifeTime().toMillis();
int fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);//alpha drop off over lifetime
int outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA);
if (fillAlpha < 0)
{
fillAlpha = 0;
}
if (outlineAlpha < 0)
{
outlineAlpha = 0;
}
if (fillAlpha > 255)
{
fillAlpha = 255;
}
if (outlineAlpha > 255)
{
outlineAlpha = 255;//Make sure we don't pass in an invalid alpha
}
if (config.isOutlineEnabled())
{
graphics.setColor(new Color(255, 0, 0, outlineAlpha));
graphics.drawPolygon(tilePoly);
}
graphics.setColor(new Color(255, 0, 0, fillAlpha));
graphics.fillPolygon(tilePoly);
}
return null;
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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.aoewarnings;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Binder;
import com.google.inject.Provides;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import net.runelite.api.Point;
import net.runelite.api.Projectile;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.ProjectileMoved;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.Overlay;
@PluginDescriptor(
name = "AoE projectile warning plugin"
)
public class AoeWarningPlugin extends Plugin
{
@Inject
AoeWarningOverlay overlay;
@Inject
AoeWarningConfig config;
private final Map<Projectile, AoeProjectile> projectiles = new HashMap<>();
@Override
public void configure(Binder binder)
{
binder.bind(AoeWarningOverlay.class);
}
@Provides
AoeWarningConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(AoeWarningConfig.class);
}
@Override
public Overlay getOverlay()
{
return overlay;
}
public Map<Projectile, AoeProjectile> getProjectiles()
{
return projectiles;
}
/**
* Called when a projectile is set to move towards a point. For
* projectiles that target the ground, like AoE projectiles from
* Lizardman Shamans, this is only called once
*
* @param event Projectile moved event
*/
@Subscribe
public void onProjectileMoved(ProjectileMoved event)
{
Projectile projectile = event.getProjectile();
// AoE projectiles do not target anything
if (projectile.getInteracting() != null)
{
return;
}
int projectileId = projectile.getId();
AoeProjectileInfo aoeProjectileInfo = AoeProjectileInfo.getById(projectileId);
if (aoeProjectileInfo != null && isConfigEnabledForProjectileId(projectileId))
{
Point targetPoint = event.getPosition();
AoeProjectile aoeProjectile = new AoeProjectile(Instant.now(), targetPoint, aoeProjectileInfo);
projectiles.put(projectile, aoeProjectile);
}
}
private boolean isConfigEnabledForProjectileId(int projectileId)
{
AoeProjectileInfo projectileInfo = AoeProjectileInfo.getById(projectileId);
if (projectileInfo == null)
{
return false;
}
switch (projectileInfo)
{
case LIZARDMAN_SHAMAN_AOE:
return config.isShamansEnabled();
case ICE_DEMON_RANGED_AOE:
case ICE_DEMON_ICE_BARRAGE_AOE:
return config.isIceDemonEnabled();
case VASA_AWAKEN_AOE:
case VASA_RANGED_AOE:
return config.isVasaEnabled();
case TEKTON_METEOR_AOE:
return config.isTektonEnabled();
}
return false;
}
}