aoewarnings: Update, refactor, and clean up. (#1164)
* aoewarnings: Update, refactor, and clean up. * Various Code Style Fixes
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Modified by farhan1666
|
||||
*
|
||||
* 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 lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@AllArgsConstructor
|
||||
class AoeProjectile
|
||||
{
|
||||
private final Instant startTime;
|
||||
private final LocalPoint targetPoint;
|
||||
private final AoeProjectileInfo aoeProjectileInfo;
|
||||
private final int projectileLifetime;
|
||||
private final int finalTick;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public interface AoeWarningConfig extends Config
|
||||
{
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum FontStyle
|
||||
enum FontStyle
|
||||
{
|
||||
BOLD("Bold", Font.BOLD),
|
||||
ITALIC("Italic", Font.ITALIC),
|
||||
@@ -948,41 +948,4 @@ public interface AoeWarningConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "marbleGargoyleStub",
|
||||
name = "Marble Gargoyle",
|
||||
description = "",
|
||||
position = 72,
|
||||
parent = "npcStub"
|
||||
)
|
||||
default Stub marbleGarboyleStub()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "marbleGargoyle",
|
||||
name = "MarbleGargoyle",
|
||||
description = "Configures if Marble Gargoyle ranged attack tile markers are displayed",
|
||||
parent = "marbleGargoyleStub",
|
||||
position = 73
|
||||
)
|
||||
default boolean isMarbleGargoyleEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "marbleGargoyleNotify",
|
||||
name = "Marble Gargoyle Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Marble Gargoyle range attack should trigger a notification",
|
||||
parent = "marbleGargoyleStub",
|
||||
position = 73,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isMarbleGargoyleNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -34,14 +34,12 @@ import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
@@ -71,53 +69,50 @@ public class AoeWarningOverlay extends Overlay
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
WorldPoint lp = client.getLocalPlayer().getWorldLocation();
|
||||
for (WorldPoint point : plugin.getLightningTrail())
|
||||
{
|
||||
OverlayUtil.drawTiles(graphics, client, point, lp, new Color(0, 150, 200), 2, 150, 50);
|
||||
}
|
||||
|
||||
for (WorldPoint point : plugin.getAcidTrail())
|
||||
{
|
||||
OverlayUtil.drawTiles(graphics, client, point, lp, new Color(69, 241, 44), 2, 150, 50);
|
||||
}
|
||||
plugin.getLightningTrail().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o, lp, new Color(0, 150, 200), 2, 150, 50));
|
||||
|
||||
for (WorldPoint point : plugin.getCrystalSpike())
|
||||
{
|
||||
OverlayUtil.drawTiles(graphics, client, point, lp, new Color(255, 0, 84), 2, 150, 50);
|
||||
}
|
||||
plugin.getAcidTrail().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o.getWorldLocation(), lp, new Color(69, 241, 44), 2, 150, 50));
|
||||
|
||||
for (WorldPoint point : plugin.getWintertodtSnowFall())
|
||||
{
|
||||
OverlayUtil.drawTiles(graphics, client, point, lp, new Color(255, 0, 84), 2, 150, 50);
|
||||
}
|
||||
plugin.getCrystalSpike().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o.getWorldLocation(), lp, new Color(255, 0, 84), 2, 150, 50));
|
||||
|
||||
plugin.getWintertodtSnowFall().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o.getWorldLocation(), lp, new Color(255, 0, 84), 2, 150, 50));
|
||||
|
||||
Instant now = Instant.now();
|
||||
Map<Projectile, AoeProjectile> projectiles = plugin.getProjectiles();
|
||||
for (Iterator<AoeProjectile> it = projectiles.values().iterator(); it.hasNext(); )
|
||||
Set<ProjectileContainer> projectiles = plugin.getProjectiles();
|
||||
projectiles.forEach(proj ->
|
||||
{
|
||||
AoeProjectile aoeProjectile = it.next();
|
||||
Color color;
|
||||
if (now.isAfter(aoeProjectile.getStartTime().plus(Duration.ofMillis(aoeProjectile.getProjectileLifetime()))))
|
||||
if (proj.getTargetPoint() == null)
|
||||
{
|
||||
it.remove();
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, aoeProjectile.getTargetPoint(), aoeProjectile.getAoeProjectileInfo().getAoeSize());
|
||||
Color color;
|
||||
|
||||
if (now.isAfter(proj.getStartTime().plus(Duration.ofMillis(proj.getLifetime()))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, proj.getTargetPoint(), proj.getAoeProjectileInfo().getAoeSize());
|
||||
|
||||
if (tilePoly == null)
|
||||
{
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
// how far through the projectiles lifetime between 0-1.
|
||||
double progress = (System.currentTimeMillis() - aoeProjectile.getStartTime().toEpochMilli()) / (double) aoeProjectile.getProjectileLifetime();
|
||||
final double progress = (System.currentTimeMillis() - proj.getStartTime().toEpochMilli()) / (double) proj.getLifetime();
|
||||
|
||||
int tickProgress = aoeProjectile.getFinalTick() - client.getTickCount();
|
||||
final int tickProgress = proj.getFinalTick() - client.getTickCount();
|
||||
|
||||
int fillAlpha, outlineAlpha;
|
||||
if (plugin.isConfigFadeEnabled())
|
||||
{
|
||||
fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);//alpha drop off over lifetime
|
||||
fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);
|
||||
outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA);
|
||||
}
|
||||
else
|
||||
@@ -165,7 +160,8 @@ public class AoeWarningOverlay extends Overlay
|
||||
|
||||
graphics.setColor(new Color(setAlphaComponent(plugin.getOverlayColor().getRGB(), fillAlpha), true));
|
||||
graphics.fillPolygon(tilePoly);
|
||||
}
|
||||
});
|
||||
projectiles.removeIf(proj -> now.isAfter(proj.getStartTime().plus(Duration.ofMillis(proj.getLifetime()))));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,9 @@ import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
@@ -44,12 +43,9 @@ import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GraphicID;
|
||||
import net.runelite.api.GraphicsObject;
|
||||
import net.runelite.api.NullObjectID;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
@@ -57,6 +53,7 @@ import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.api.events.ProjectileSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
@@ -76,10 +73,6 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
@Slf4j
|
||||
public class AoeWarningPlugin extends Plugin
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Map<WorldPoint, CrystalBomb> bombs = new HashMap<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Map<Projectile, AoeProjectile> projectiles = new HashMap<>();
|
||||
@Inject
|
||||
public AoeWarningConfig config;
|
||||
@Inject
|
||||
@@ -95,20 +88,17 @@ public class AoeWarningPlugin extends Plugin
|
||||
@Inject
|
||||
private EventBus eventbus;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> LightningTrail = new ArrayList<>();
|
||||
private List<WorldPoint> lightningTrail = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> AcidTrail = new ArrayList<>();
|
||||
private List<GameObject> acidTrail = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> CrystalSpike = new ArrayList<>();
|
||||
private List<GameObject> crystalSpike = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> WintertodtSnowFall = new ArrayList<>();
|
||||
|
||||
@Provides
|
||||
AoeWarningConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AoeWarningConfig.class);
|
||||
}
|
||||
|
||||
private List<GameObject> wintertodtSnowFall = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<CrystalBomb> bombs = new HashSet<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<ProjectileContainer> projectiles = new HashSet<>();
|
||||
// Config values
|
||||
private boolean aoeNotifyAll;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@@ -167,28 +157,30 @@ public class AoeWarningPlugin extends Plugin
|
||||
private boolean configCerbFireNotifyEnabled;
|
||||
private boolean configDemonicGorillaEnabled;
|
||||
private boolean configDemonicGorillaNotifyEnabled;
|
||||
private boolean configMarbleGargoyleEnabled;
|
||||
private boolean configMarbleGargoyleNotifyEnabled;
|
||||
|
||||
@Provides
|
||||
AoeWarningConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AoeWarningConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
protected void startUp()
|
||||
{
|
||||
updateConfig();
|
||||
addSubscriptions();
|
||||
|
||||
overlayManager.add(coreOverlay);
|
||||
overlayManager.add(bombOverlay);
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
protected void shutDown()
|
||||
{
|
||||
eventbus.unregister(this);
|
||||
|
||||
overlayManager.remove(coreOverlay);
|
||||
overlayManager.remove(bombOverlay);
|
||||
reset();
|
||||
eventbus.unregister(this);
|
||||
}
|
||||
|
||||
private void addSubscriptions()
|
||||
@@ -199,6 +191,7 @@ public class AoeWarningPlugin extends Plugin
|
||||
eventbus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned);
|
||||
eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventbus.subscribe(GameTick.class, this, this::onGameTick);
|
||||
eventbus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
}
|
||||
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
@@ -211,42 +204,60 @@ public class AoeWarningPlugin extends Plugin
|
||||
updateConfig();
|
||||
}
|
||||
|
||||
private void onProjectileMoved(ProjectileMoved event)
|
||||
private void onProjectileSpawned(ProjectileSpawned event)
|
||||
{
|
||||
Projectile projectile = event.getProjectile();
|
||||
final Projectile projectile = event.getProjectile();
|
||||
|
||||
int projectileId = projectile.getId();
|
||||
int projectileLifetime = this.delay + (projectile.getRemainingCycles() * 20);
|
||||
if (AoeProjectileInfo.getById(projectile.getId()) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int id = projectile.getId();
|
||||
final int lifetime = this.delay + (projectile.getRemainingCycles() * 20);
|
||||
int ticksRemaining = projectile.getRemainingCycles() / 30;
|
||||
if (!isTickTimersEnabledForProjectileID(projectileId))
|
||||
if (!isTickTimersEnabledForProjectileID(id))
|
||||
{
|
||||
ticksRemaining = 0;
|
||||
}
|
||||
int tickCycle = client.getTickCount() + ticksRemaining;
|
||||
AoeProjectileInfo aoeProjectileInfo = AoeProjectileInfo.getById(projectileId);
|
||||
if (aoeProjectileInfo != null
|
||||
&& isConfigEnabledForProjectileId(projectileId, false))
|
||||
final int tickCycle = client.getTickCount() + ticksRemaining;
|
||||
if (isConfigEnabledForProjectileId(id, false))
|
||||
{
|
||||
LocalPoint targetPoint = event.getPosition();
|
||||
AoeProjectile aoeProjectile = new AoeProjectile(Instant.now(), targetPoint, aoeProjectileInfo, projectileLifetime, tickCycle);
|
||||
projectiles.put(projectile, aoeProjectile);
|
||||
projectiles.add(new ProjectileContainer(projectile, Instant.now(), lifetime, tickCycle));
|
||||
|
||||
if (this.aoeNotifyAll || isConfigEnabledForProjectileId(projectileId, true))
|
||||
if (this.aoeNotifyAll || isConfigEnabledForProjectileId(id, true))
|
||||
{
|
||||
notifier.notify("AoE attack detected!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onProjectileMoved(ProjectileMoved event)
|
||||
{
|
||||
if (projectiles.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Projectile projectile = event.getProjectile();
|
||||
|
||||
projectiles.forEach(proj ->
|
||||
{
|
||||
if (proj.getProjectile() == projectile)
|
||||
{
|
||||
proj.setTargetPoint(event.getPosition());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
final WorldPoint wp = gameObject.getWorldLocation();
|
||||
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
bombs.put(wp, new CrystalBomb(gameObject, client.getTickCount()));
|
||||
bombs.add(new CrystalBomb(gameObject, client.getTickCount()));
|
||||
|
||||
if (this.aoeNotifyAll || this.configbombDisplayNotifyEnabled)
|
||||
{
|
||||
@@ -254,16 +265,15 @@ public class AoeWarningPlugin extends Plugin
|
||||
}
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
AcidTrail.add(wp);
|
||||
acidTrail.add(gameObject);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
CrystalSpike.add(wp);
|
||||
crystalSpike.add(gameObject);
|
||||
break;
|
||||
case NullObjectID.NULL_26690:
|
||||
//Wintertodt Snowfall
|
||||
if (this.configWintertodtEnabled)
|
||||
{
|
||||
WintertodtSnowFall.add(wp);
|
||||
wintertodtSnowFall.add(gameObject);
|
||||
|
||||
if (this.aoeNotifyAll || this.configWintertodtNotifyEnabled)
|
||||
{
|
||||
@@ -276,98 +286,55 @@ public class AoeWarningPlugin extends Plugin
|
||||
|
||||
private void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
WorldPoint wp = gameObject.getWorldLocation();
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
purgeBombs(bombs);
|
||||
bombs.removeIf(o -> o.getGameObject() == gameObject);
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
AcidTrail.remove(wp);
|
||||
acidTrail.remove(gameObject);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
CrystalSpike.remove(wp);
|
||||
crystalSpike.remove(gameObject);
|
||||
break;
|
||||
case NullObjectID.NULL_26690:
|
||||
//Wintertodt Snowfall
|
||||
if (this.configWintertodtEnabled)
|
||||
{
|
||||
WintertodtSnowFall.remove(wp);
|
||||
}
|
||||
wintertodtSnowFall.remove(gameObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameStateChanged(GameStateChanged delta)
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
if (event.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
purgeBombs(bombs);
|
||||
return;
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
private void onGameTick(GameTick event)
|
||||
{
|
||||
lightningTrail.clear();
|
||||
|
||||
if (this.configLightningTrail)
|
||||
{
|
||||
LightningTrail.clear();
|
||||
for (GraphicsObject o : client.getGraphicsObjects())
|
||||
client.getGraphicsObjects().forEach(o ->
|
||||
{
|
||||
if (o.getId() == GraphicID.OLM_LIGHTNING)
|
||||
{
|
||||
LightningTrail.add(WorldPoint.fromLocal(client, o.getLocation()));
|
||||
lightningTrail.add(WorldPoint.fromLocal(client, o.getLocation()));
|
||||
|
||||
if (this.aoeNotifyAll || this.configLightningTrailNotifyEnabled)
|
||||
{
|
||||
notifier.notify("Lightning!");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (Map.Entry<WorldPoint, CrystalBomb> entry : bombs.entrySet())
|
||||
{
|
||||
CrystalBomb bomb = entry.getValue();
|
||||
bomb.bombClockUpdate();
|
||||
//bombClockUpdate smooths the shown timer; not using this results in 1.2 --> .6 vs. 1.2 --> 1.1, etc.
|
||||
}
|
||||
}
|
||||
|
||||
private void purgeBombs(Map<WorldPoint, CrystalBomb> bombs)
|
||||
{
|
||||
Iterator<Map.Entry<WorldPoint, CrystalBomb>> it = bombs.entrySet().iterator();
|
||||
Tile[][][] tiles = client.getScene().getTiles();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
Map.Entry<WorldPoint, CrystalBomb> entry = it.next();
|
||||
WorldPoint world = entry.getKey();
|
||||
LocalPoint local = LocalPoint.fromWorld(client, world);
|
||||
|
||||
if (local == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = tiles[world.getPlane()][local.getSceneX()][local.getSceneY()];
|
||||
GameObject[] objects = tile.getGameObjects();
|
||||
boolean containsObjects = false;
|
||||
|
||||
for (GameObject object : objects)
|
||||
{
|
||||
if (object != null)
|
||||
{
|
||||
containsObjects = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!containsObjects)
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
|
||||
}
|
||||
bombs.forEach(CrystalBomb::bombClockUpdate);
|
||||
}
|
||||
|
||||
private boolean isTickTimersEnabledForProjectileID(int projectileId)
|
||||
@@ -456,8 +423,6 @@ public class AoeWarningPlugin extends Plugin
|
||||
return notify ? this.configCerbFireNotifyEnabled : this.configCerbFireEnabled;
|
||||
case DEMONIC_GORILLA_BOULDER:
|
||||
return notify ? this.configDemonicGorillaNotifyEnabled : this.configDemonicGorillaEnabled;
|
||||
case MARBLE_GARGOYLE_AOE:
|
||||
return notify ? this.configMarbleGargoyleNotifyEnabled : this.configMarbleGargoyleEnabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -514,16 +479,14 @@ public class AoeWarningPlugin extends Plugin
|
||||
this.configCerbFireNotifyEnabled = config.isCerbFireNotifyEnabled();
|
||||
this.configDemonicGorillaEnabled = config.isDemonicGorillaEnabled();
|
||||
this.configDemonicGorillaNotifyEnabled = config.isDemonicGorillaNotifyEnabled();
|
||||
this.configMarbleGargoyleEnabled = config.isMarbleGargoyleEnabled();
|
||||
this.configMarbleGargoyleNotifyEnabled = config.isMarbleGargoyleNotifyEnabled();
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
LightningTrail.clear();
|
||||
AcidTrail.clear();
|
||||
CrystalSpike.clear();
|
||||
WintertodtSnowFall.clear();
|
||||
lightningTrail.clear();
|
||||
acidTrail.clear();
|
||||
crystalSpike.clear();
|
||||
wintertodtSnowFall.clear();
|
||||
bombs.clear();
|
||||
projectiles.clear();
|
||||
}
|
||||
|
||||
@@ -33,13 +33,11 @@ import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
@@ -55,24 +53,13 @@ public class BombOverlay extends Overlay
|
||||
{
|
||||
|
||||
private static final String SAFE = "#00cc00";
|
||||
//safe
|
||||
private static final String CAUTION = "#ffff00";
|
||||
//1 tile in range (minor damage)
|
||||
private static final String WARNING = "#ff9933";
|
||||
//2 tiles in range (moderate damage)
|
||||
private static final String DANGER = "#ff6600";
|
||||
//3 tiles in range/adjacent to bomb (major damage)
|
||||
private static final String LETHAL = "#cc0000";
|
||||
//On the bomb, using it as a makeshift space launch vehicle. (massive damage)
|
||||
|
||||
private static final int BOMB_AOE = 7;
|
||||
private static final int BOMB_DETONATE_TIME = 8;
|
||||
//This is in ticks. It should be 10, but it varies from 8 to 11.
|
||||
private static final double ESTIMATED_TICK_LENGTH = .6;
|
||||
//Thank you Woox & co. for this assumption. .6 seconds/tick.
|
||||
|
||||
|
||||
//Utilized from the npc highlight code for formatting text being displayed on the client canvas.
|
||||
private static final NumberFormat TIME_LEFT_FORMATTER =
|
||||
DecimalFormat.getInstance(Locale.US);
|
||||
|
||||
@@ -99,84 +86,73 @@ public class BombOverlay extends Overlay
|
||||
{
|
||||
if (plugin.isConfigbombDisplay())
|
||||
{
|
||||
drawBombs(graphics);
|
||||
drawDangerZone(graphics);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawBombs(Graphics2D graphics)
|
||||
//I can condense drawDangerZone into this. Ambivalent though.
|
||||
private void drawDangerZone(Graphics2D graphics)
|
||||
{
|
||||
for (Map.Entry<WorldPoint, CrystalBomb> entry : plugin.getBombs().entrySet())
|
||||
final WorldPoint loc = client.getLocalPlayer().getWorldLocation();
|
||||
plugin.getBombs().forEach(bomb ->
|
||||
{
|
||||
CrystalBomb bomb = entry.getValue();
|
||||
drawDangerZone(graphics, bomb);
|
||||
}
|
||||
}
|
||||
final LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation());
|
||||
final WorldPoint worldLoc = bomb.getWorldLocation();
|
||||
|
||||
private void drawDangerZone(Graphics2D graphics, CrystalBomb bomb)
|
||||
{
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation());
|
||||
if (localLoc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
double distance_x = Math.abs(bomb.getWorldLocation().getX() - localPlayer.getWorldLocation().getX());
|
||||
double distance_y = Math.abs(bomb.getWorldLocation().getY() - localPlayer.getWorldLocation().getY());
|
||||
Color color_code = Color.decode(SAFE);
|
||||
//defaults to this unless conditionals met below.
|
||||
if (localLoc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (distance_x < 1 && distance_y < 1)
|
||||
{
|
||||
color_code = Color.decode(LETHAL);
|
||||
}
|
||||
else if (distance_x < 2 && distance_y < 2)
|
||||
{
|
||||
color_code = Color.decode(DANGER);
|
||||
}
|
||||
else if (distance_x < 3 && distance_y < 3)
|
||||
{
|
||||
color_code = Color.decode(WARNING);
|
||||
}
|
||||
else if (distance_x < 4 && distance_y < 4)
|
||||
{
|
||||
color_code = Color.decode(CAUTION);
|
||||
}
|
||||
LocalPoint CenterPoint = new LocalPoint(localLoc.getX(), localLoc.getY());
|
||||
Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE);
|
||||
final double distance_x = Math.abs(worldLoc.getX() - loc.getX());
|
||||
final double distance_y = Math.abs(worldLoc.getY() - loc.getY());
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
//manually generating the polygon so as to assign a custom alpha value. Request adtl' arg for alpha maybe?
|
||||
graphics.setColor(color_code);
|
||||
graphics.setStroke(new BasicStroke(1));
|
||||
graphics.drawPolygon(poly);
|
||||
graphics.setColor(new Color(0, 0, 0, 10));
|
||||
graphics.fillPolygon(poly);
|
||||
}
|
||||
Color color_code = Color.decode(SAFE);
|
||||
|
||||
Instant now = Instant.now();
|
||||
double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() -
|
||||
bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
|
||||
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
|
||||
//divided by 1000.00 because of milliseconds :)
|
||||
if (distance_x < 1 && distance_y < 1)
|
||||
{
|
||||
color_code = Color.decode(LETHAL);
|
||||
}
|
||||
else if (distance_x < 2 && distance_y < 2)
|
||||
{
|
||||
color_code = Color.decode(DANGER);
|
||||
}
|
||||
else if (distance_x < 3 && distance_y < 3)
|
||||
{
|
||||
color_code = Color.decode(WARNING);
|
||||
}
|
||||
else if (distance_x < 4 && distance_y < 4)
|
||||
{
|
||||
color_code = Color.decode(CAUTION);
|
||||
}
|
||||
final LocalPoint CenterPoint = new LocalPoint(localLoc.getX(), localLoc.getY());
|
||||
final Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE);
|
||||
|
||||
timeLeft = Math.max(0.0, timeLeft);
|
||||
String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft);
|
||||
int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString);
|
||||
int textHeight = graphics.getFontMetrics().getAscent();
|
||||
Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(),
|
||||
localLoc.getY(), bomb.getWorldLocation().getPlane());
|
||||
if (poly != null)
|
||||
{
|
||||
graphics.setColor(color_code);
|
||||
graphics.setStroke(new BasicStroke(1));
|
||||
graphics.drawPolygon(poly);
|
||||
graphics.setColor(new Color(0, 0, 0, 10));
|
||||
graphics.fillPolygon(poly);
|
||||
}
|
||||
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX() - textWidth / 2,
|
||||
canvasPoint.getY() + textHeight / 2);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
|
||||
}
|
||||
final Instant now = Instant.now();
|
||||
double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() - bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
|
||||
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
|
||||
|
||||
timeLeft = Math.max(0.0, timeLeft);
|
||||
final String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft);
|
||||
final int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString);
|
||||
final int textHeight = graphics.getFontMetrics().getAscent();
|
||||
final Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(), localLoc.getY(), worldLoc.getPlane());
|
||||
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
Point canvasCenterPoint = new Point(canvasPoint.getX() - textWidth / 2, canvasPoint.getY() + textHeight / 2);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,28 +32,21 @@ import net.runelite.api.GameObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@Slf4j
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class CrystalBomb
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private GameObject gameObject;
|
||||
private Instant plantedOn;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Instant lastClockUpdate;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int objectId;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int tickStarted;
|
||||
//
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private WorldPoint worldLocation;
|
||||
|
||||
CrystalBomb(GameObject gameObject, int startTick)
|
||||
{
|
||||
this.plantedOn = Instant.now();
|
||||
this.gameObject = gameObject;
|
||||
this.objectId = gameObject.getId();
|
||||
this.plantedOn = Instant.now();
|
||||
this.worldLocation = gameObject.getWorldLocation();
|
||||
this.tickStarted = startTick;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class ProjectileContainer
|
||||
{
|
||||
private Projectile projectile;
|
||||
private Instant startTime;
|
||||
private AoeProjectileInfo aoeProjectileInfo;
|
||||
private int lifetime;
|
||||
private int finalTick;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private LocalPoint targetPoint;
|
||||
|
||||
ProjectileContainer(Projectile projectile, Instant startTime, int lifetime, int finalTick)
|
||||
{
|
||||
this.projectile = projectile;
|
||||
this.startTime = startTime;
|
||||
this.targetPoint = null;
|
||||
this.aoeProjectileInfo = AoeProjectileInfo.getById(projectile.getId());
|
||||
this.lifetime = lifetime;
|
||||
this.finalTick = finalTick;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user