Merge pull request #376 from Dreyri/projectiles
Projectiles Dev Tool and Additions to the AoE plugin
This commit is contained in:
@@ -154,6 +154,8 @@ public interface Client
|
||||
|
||||
IndexedSprite[] getMapScene();
|
||||
|
||||
int getGameCycle();
|
||||
|
||||
SpritePixels[] getMapIcons();
|
||||
|
||||
IndexedSprite[] getModIcons();
|
||||
@@ -169,4 +171,7 @@ public interface Client
|
||||
boolean isClanMember(String name);
|
||||
|
||||
Point getSceneDestinationLocation();
|
||||
|
||||
List<Projectile> getProjectiles();
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,55 @@
|
||||
*/
|
||||
package net.runelite.api;
|
||||
|
||||
public interface Projectile
|
||||
import java.time.Duration;
|
||||
|
||||
public interface Projectile extends Renderable
|
||||
{
|
||||
int getId();
|
||||
|
||||
Actor getInteracting();
|
||||
|
||||
Point getTarget();
|
||||
|
||||
int getTargetZ();
|
||||
|
||||
int getX1();
|
||||
|
||||
int getY1();
|
||||
|
||||
int getFloor();
|
||||
|
||||
int getHeight();
|
||||
|
||||
int getEndHeight();
|
||||
|
||||
int getStartMovementCycle();
|
||||
|
||||
int getSpawnCycle();
|
||||
|
||||
int getCycleLength();
|
||||
|
||||
Duration getLength();
|
||||
|
||||
int getEndCycle();
|
||||
|
||||
int getRemainingCycles();
|
||||
|
||||
int getSlope();
|
||||
|
||||
int getStartHeight();
|
||||
|
||||
double getX();
|
||||
|
||||
double getY();
|
||||
|
||||
double getZ();
|
||||
|
||||
double getScalar();
|
||||
|
||||
double getVelocityX();
|
||||
|
||||
double getVelocityY();
|
||||
|
||||
double getVelocityZ();
|
||||
}
|
||||
|
||||
@@ -33,4 +33,36 @@ public class ProjectileID
|
||||
public static final int VASA_AWAKEN_AOE = 1327;
|
||||
public static final int VASA_RANGED_AOE = 1329;
|
||||
public static final int TEKTON_METEOR_AOE = 660;
|
||||
|
||||
public static final int OLM_FALLING_CRYSTAL_AOE = -1; //please help
|
||||
public static final int OLM_BURNING_AOE = -1;
|
||||
|
||||
public static final int VORKATH_BOMB_AOE = 1481;
|
||||
public static final int VORKATH_POISON_POOL_AOE = 1483;
|
||||
public static final int VORKATH_TICK_FIRE_AOE = 1482;
|
||||
public static final int VORKATH_SPAWN_AOE = 1484;
|
||||
|
||||
public static final int GALVEK_MINE = 1495;
|
||||
public static final int GALVEK_BOMB = 1491;
|
||||
|
||||
public static final int VETION_LIGHTNING = 280;
|
||||
|
||||
public static final int CHAOS_FANATIC_AOE = 551; //for lack of a better word
|
||||
|
||||
public static final int CORPOREAL_BEAST_AOE = 315;
|
||||
public static final int CORPOREAL_BEAST_DARK_CORE_AOE = 319;
|
||||
|
||||
/**
|
||||
* missing: marble gargoyle, superior dark beast
|
||||
*/
|
||||
|
||||
/**
|
||||
* non AOE, regular projectiles
|
||||
*/
|
||||
public static final int VORKATH_DRAGONBREATH = 393;
|
||||
public static final int VORKATH_RANGED = 1477;
|
||||
public static final int VORKATH_MAGIC = 1479;
|
||||
public static final int VORKATH_PRAYER_DISABLE = 1471;
|
||||
public static final int VORKATH_VENOM = 1470;
|
||||
public static final int VORKATH_ICE = 350;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.api.ProjectileID;
|
||||
|
||||
public enum AoeProjectileInfo
|
||||
@@ -41,7 +43,46 @@ public enum AoeProjectileInfo
|
||||
*/
|
||||
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);
|
||||
TEKTON_METEOR_AOE(ProjectileID.TEKTON_METEOR_AOE, 4000, 3),
|
||||
|
||||
/**
|
||||
* The AOEs of Vorkath
|
||||
*/
|
||||
VORKATH_BOMB(ProjectileID.VORKATH_BOMB_AOE, 2400, 3),
|
||||
VORKATH_POISON_POOL(ProjectileID.VORKATH_POISON_POOL_AOE, 1800, 1),
|
||||
VORKATH_SPAWN(ProjectileID.VORKATH_SPAWN_AOE, 3000, 1), //extra tick because hard to see otherwise
|
||||
VORKATH_TICK_FIRE(ProjectileID.VORKATH_TICK_FIRE_AOE, 600, 1),
|
||||
|
||||
/**
|
||||
* the AOEs of Galvek
|
||||
*/
|
||||
GALVEK_MINE(ProjectileID.GALVEK_MINE, 3600, 3),
|
||||
GALVEK_BOMB(ProjectileID.GALVEK_BOMB, 2400, 3),
|
||||
|
||||
/**
|
||||
* the AOE of Vet'ion
|
||||
*/
|
||||
VETION_LIGHTNING(ProjectileID.VETION_LIGHTNING, 3000, 1),
|
||||
|
||||
/**
|
||||
* the AOE of Chaos Fanatic
|
||||
*/
|
||||
CHAOS_FANATIC(ProjectileID.CHAOS_FANATIC_AOE, 3000, 1),
|
||||
|
||||
/**
|
||||
* the AOE of the Corporeal Beast
|
||||
*/
|
||||
|
||||
CORPOREAL_BEAST(ProjectileID.CORPOREAL_BEAST_AOE, 3000, 1),
|
||||
CORPOREAL_BEAST_DARK_CORE(ProjectileID.CORPOREAL_BEAST_DARK_CORE_AOE, 3000, 3),
|
||||
|
||||
/**
|
||||
* the AOEs of The Great Olm
|
||||
* missing ids and length, please help
|
||||
*/
|
||||
OLM_FALLING_CRYSTAL(ProjectileID.OLM_FALLING_CRYSTAL_AOE, 2400, 3),
|
||||
OLM_BURNING(ProjectileID.OLM_BURNING_AOE, 2400, 3);
|
||||
|
||||
|
||||
/**
|
||||
* The id of the projectile to trigger this AoE warning
|
||||
@@ -61,6 +102,16 @@ public enum AoeProjectileInfo
|
||||
*/
|
||||
private final int aoeSize;
|
||||
|
||||
private static final Map<Integer, AoeProjectileInfo> map = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
for (AoeProjectileInfo aoe : values())
|
||||
{
|
||||
map.put(aoe.id, aoe);
|
||||
}
|
||||
}
|
||||
|
||||
AoeProjectileInfo(int id, int lifeTimeMillis, int aoeSize)
|
||||
{
|
||||
this.id = id;
|
||||
@@ -85,13 +136,6 @@ public enum AoeProjectileInfo
|
||||
|
||||
public static AoeProjectileInfo getById(int id)
|
||||
{
|
||||
for (AoeProjectileInfo aoeProjectileInfo : values())
|
||||
{
|
||||
if (id == aoeProjectileInfo.getId())
|
||||
{
|
||||
return aoeProjectileInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return map.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,66 @@ public interface AoeWarningConfig extends Config
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vorkath",
|
||||
name = "Vorkath",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vorkath are displayed"
|
||||
)
|
||||
default boolean isVorkathEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "galvek",
|
||||
name = "Galvek",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Galvek are displayed"
|
||||
)
|
||||
default boolean isGalvekEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vetion",
|
||||
name = "Vet'ion",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vet'ion are displayed"
|
||||
)
|
||||
default boolean isVetionEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "chaosfanatic",
|
||||
name = "Chaos Fanatic",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Chaos Fanatic are displayed"
|
||||
)
|
||||
default boolean isChaosFanaticEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "olm",
|
||||
name = "Great Olm",
|
||||
description = "Configures whether or not AoE Projectile Warnings for The Great Olm are displayed"
|
||||
)
|
||||
default boolean isOlmEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "corp",
|
||||
name = "Corporeal Beast",
|
||||
description = "Configures whether or not AoE Projectile Warnings for the Corporeal Beast are displayed"
|
||||
)
|
||||
default boolean isCorpEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "outline",
|
||||
name = "Display Outline",
|
||||
|
||||
@@ -125,6 +125,24 @@ public class AoeWarningPlugin extends Plugin
|
||||
return config.isVasaEnabled();
|
||||
case TEKTON_METEOR_AOE:
|
||||
return config.isTektonEnabled();
|
||||
case VORKATH_BOMB:
|
||||
case VORKATH_POISON_POOL:
|
||||
case VORKATH_SPAWN:
|
||||
case VORKATH_TICK_FIRE:
|
||||
return config.isVorkathEnabled();
|
||||
case VETION_LIGHTNING:
|
||||
return config.isVetionEnabled();
|
||||
case CHAOS_FANATIC:
|
||||
return config.isChaosFanaticEnabled();
|
||||
case GALVEK_BOMB:
|
||||
case GALVEK_MINE:
|
||||
return config.isGalvekEnabled();
|
||||
case OLM_FALLING_CRYSTAL:
|
||||
case OLM_BURNING:
|
||||
return config.isOlmEnabled();
|
||||
case CORPOREAL_BEAST:
|
||||
case CORPOREAL_BEAST_DARK_CORE:
|
||||
return config.isCorpEnabled();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.devtools;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
@@ -37,6 +38,7 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.DecorativeObject;
|
||||
import net.runelite.api.GameObject;
|
||||
@@ -45,7 +47,9 @@ import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemLayer;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Node;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.Region;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.WallObject;
|
||||
@@ -117,6 +121,11 @@ public class DevToolsOverlay extends Overlay
|
||||
renderInventory(graphics);
|
||||
}
|
||||
|
||||
if (plugin.isToggleProjectiles())
|
||||
{
|
||||
renderProjectiles(graphics);
|
||||
}
|
||||
|
||||
renderWidgets(graphics);
|
||||
|
||||
return null;
|
||||
@@ -325,6 +334,64 @@ public class DevToolsOverlay extends Overlay
|
||||
}
|
||||
}
|
||||
|
||||
private void renderProjectiles(Graphics2D graphics)
|
||||
{
|
||||
List<Projectile> projectiles = client.getProjectiles();
|
||||
|
||||
for (Projectile projectile : projectiles)
|
||||
{
|
||||
int originX = projectile.getX1();
|
||||
int originY = projectile.getY1();
|
||||
|
||||
net.runelite.api.Point tilePoint = new net.runelite.api.Point(originX, originY);
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, tilePoint);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, Color.RED);
|
||||
}
|
||||
|
||||
long projectileLength = projectile.getLength().toMillis();
|
||||
int projectileId = projectile.getId();
|
||||
Actor projectileInteracting = projectile.getInteracting();
|
||||
|
||||
String infoString = "";
|
||||
|
||||
if (projectileInteracting == null)
|
||||
{
|
||||
infoString += "AoE";
|
||||
}
|
||||
else
|
||||
{
|
||||
infoString += "Targeted (T: " + projectileInteracting.getName() + ")";
|
||||
}
|
||||
|
||||
infoString += " (ID: " + projectileId + ") (L: " + projectileLength + "ms)";
|
||||
|
||||
if (projectileInteracting != null)
|
||||
{
|
||||
OverlayUtil.renderActorOverlay(graphics, projectile.getInteracting(), infoString, Color.RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
net.runelite.api.Point targetPoint = projectile.getTarget();
|
||||
OverlayUtil.renderTilePointOverlay(graphics, client, targetPoint, infoString, Color.RED);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void renderProjectileOrigin(Graphics2D graphics, Projectile projectile, int floor, net.runelite.api.Point origin)
|
||||
{
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, origin);
|
||||
|
||||
graphics.setColor(Color.RED);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.drawPolygon(poly);
|
||||
graphics.setColor(Color.RED);
|
||||
graphics.fillPolygon(poly);
|
||||
}
|
||||
|
||||
public void renderWidgets(Graphics2D graphics)
|
||||
{
|
||||
Widget widget = plugin.currentWidget;
|
||||
|
||||
@@ -60,6 +60,7 @@ public class DevToolsPanel extends PluginPanel
|
||||
private JButton renderWallsBtn = new JButton();
|
||||
private JButton renderDecorBtn = new JButton();
|
||||
private JButton renderInventoryBtn = new JButton();
|
||||
private JButton renderProjectilesBtn = new JButton();
|
||||
|
||||
private JLabel textLbl = new JLabel();
|
||||
private JLabel textColorLbl = new JLabel();
|
||||
@@ -92,7 +93,7 @@ public class DevToolsPanel extends PluginPanel
|
||||
private JPanel createOptionsPanel()
|
||||
{
|
||||
JPanel container = new JPanel();
|
||||
container.setLayout(new GridLayout(5, 2, 3, 3));
|
||||
container.setLayout(new GridLayout(6, 2, 3, 3));
|
||||
|
||||
renderPlayersBtn = new JButton("Players");
|
||||
renderPlayersBtn.addActionListener(e ->
|
||||
@@ -158,6 +159,14 @@ public class DevToolsPanel extends PluginPanel
|
||||
});
|
||||
container.add(renderInventoryBtn);
|
||||
|
||||
renderProjectilesBtn = new JButton("Projectiles");
|
||||
renderProjectilesBtn.addActionListener(e ->
|
||||
{
|
||||
highlightButton(renderProjectilesBtn);
|
||||
plugin.toggleProjectiles();
|
||||
});
|
||||
container.add(renderProjectilesBtn);
|
||||
|
||||
JButton settingsSnapshotBtn = new JButton("Get Settings");
|
||||
settingsSnapshotBtn.addActionListener(settingsTracker::snapshot);
|
||||
container.add(settingsSnapshotBtn);
|
||||
|
||||
@@ -56,6 +56,7 @@ public class DevToolsPlugin extends Plugin
|
||||
private boolean toggleWalls;
|
||||
private boolean toggleDecor;
|
||||
private boolean toggleInventory;
|
||||
private boolean toggleProjectiles;
|
||||
|
||||
Widget currentWidget;
|
||||
int itemIndex = -1;
|
||||
@@ -135,6 +136,11 @@ public class DevToolsPlugin extends Plugin
|
||||
toggleInventory = !toggleInventory;
|
||||
}
|
||||
|
||||
void toggleProjectiles()
|
||||
{
|
||||
toggleProjectiles = !toggleProjectiles;
|
||||
}
|
||||
|
||||
boolean isTogglePlayers()
|
||||
{
|
||||
return togglePlayers;
|
||||
@@ -175,4 +181,8 @@ public class DevToolsPlugin extends Plugin
|
||||
return toggleInventory;
|
||||
}
|
||||
|
||||
boolean isToggleProjectiles()
|
||||
{
|
||||
return toggleProjectiles;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.SpritePixels;
|
||||
import net.runelite.api.TileObject;
|
||||
@@ -318,6 +320,28 @@ public class OverlayUtil
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderTilePointOverlay(Graphics2D graphics, Client client, Point point, String text, Color color)
|
||||
{
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, point);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
renderPolygon(graphics, poly, color);
|
||||
}
|
||||
|
||||
Point minimapLocation = Perspective.worldToMiniMap(client, point.getX(), point.getY());
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
renderMinimapLocation(graphics, minimapLocation, color);
|
||||
}
|
||||
|
||||
Point textLocation = Perspective.getCanvasTextLocation(client, graphics, point, text, 0);
|
||||
if (textLocation != null)
|
||||
{
|
||||
renderTextLocation(graphics, textLocation, text, color);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setGraphicProperties(Graphics2D graphics)
|
||||
{
|
||||
graphics.setFont(FontManager.getRunescapeFont());
|
||||
|
||||
@@ -32,17 +32,13 @@ import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Node;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.mixins.FieldHook;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.events.ClanMembersChanged;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
@@ -50,8 +46,15 @@ import net.runelite.api.events.MapRegionChanged;
|
||||
import net.runelite.api.events.PlayerMenuOptionsChanged;
|
||||
import net.runelite.api.events.ResizeableChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.mixins.FieldHook;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import static net.runelite.client.callback.Hooks.eventBus;
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import net.runelite.rs.api.RSDeque;
|
||||
import net.runelite.rs.api.RSIndexedSprite;
|
||||
import net.runelite.rs.api.RSWidget;
|
||||
|
||||
@@ -331,6 +334,33 @@ public abstract class RSClientMixin implements RSClient
|
||||
setMenuOptionCount(count);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public List<Projectile> getProjectiles()
|
||||
{
|
||||
List<Projectile> projectiles = new ArrayList<Projectile>();
|
||||
RSDeque projectileDeque = this.getProjectilesDeque();
|
||||
Node head = projectileDeque.getHead();
|
||||
Node current = head;
|
||||
|
||||
while (current != null)
|
||||
{
|
||||
if (current instanceof Projectile)
|
||||
{
|
||||
projectiles.add((Projectile) current);
|
||||
}
|
||||
|
||||
current = current.getNext();
|
||||
|
||||
if (current == head)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return projectiles;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setModIcons(IndexedSprite[] modIcons)
|
||||
|
||||
@@ -24,9 +24,13 @@
|
||||
*/
|
||||
package net.runelite.mixins;
|
||||
|
||||
import java.time.Duration;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.mixins.Copy;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.api.mixins.Replace;
|
||||
import net.runelite.api.mixins.Shadow;
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import net.runelite.rs.api.RSNPC;
|
||||
@@ -39,6 +43,74 @@ public abstract class RSProjectileMixin implements RSProjectile
|
||||
@Shadow("clientInstance")
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
private int targetX;
|
||||
|
||||
@Inject
|
||||
private int targetY;
|
||||
|
||||
@Inject
|
||||
private int targetZ;
|
||||
|
||||
@Inject
|
||||
Integer spawnCycle;
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Point getTarget()
|
||||
{
|
||||
if (targetX == -1 || targetY == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Point(targetX, targetY);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getTargetZ()
|
||||
{
|
||||
return targetZ;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getSpawnCycle()
|
||||
{
|
||||
return spawnCycle == null ? -1 : spawnCycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* the cycles returned are for the amount of time moving this works
|
||||
* better with the projectile movement event as it only gets called
|
||||
* after the projectile starts moving
|
||||
*
|
||||
* @return total time projectile will move for in gamecycles
|
||||
*/
|
||||
@Inject
|
||||
@Override
|
||||
public int getCycleLength()
|
||||
{
|
||||
return getEndCycle() - getSpawnCycle();
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Duration getLength()
|
||||
{
|
||||
return Duration.ofMillis(getCycleLength() * 20);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getRemainingCycles()
|
||||
{
|
||||
int currentGameCycle = client.getGameCycle();
|
||||
|
||||
return getEndCycle() - currentGameCycle;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Actor getInteracting()
|
||||
@@ -68,4 +140,22 @@ public abstract class RSProjectileMixin implements RSProjectile
|
||||
return players[idx];
|
||||
}
|
||||
}
|
||||
|
||||
@Copy("moveProjectile")
|
||||
abstract void moveProjectile(int targetX, int targetY, int targetZ, int gameCycle);
|
||||
|
||||
@Replace("moveProjectile")
|
||||
public void rl$moveProjectile(int targetX, int targetY, int targetZ, int gameCycle)
|
||||
{
|
||||
this.targetX = targetX;
|
||||
this.targetY = targetY;
|
||||
this.targetZ = targetZ;
|
||||
|
||||
if (spawnCycle == null)
|
||||
{
|
||||
spawnCycle = client.getGameCycle();
|
||||
}
|
||||
|
||||
moveProjectile(targetX, targetY, targetZ, gameCycle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,9 @@ public interface RSClient extends RSGameEngine, Client
|
||||
@Import("groundItemDeque")
|
||||
RSDeque[][][] getGroundItemDeque();
|
||||
|
||||
@Import("projectiles")
|
||||
RSDeque getProjectilesDeque();
|
||||
|
||||
@Import("username")
|
||||
@Override
|
||||
String getUsername();
|
||||
@@ -266,6 +269,7 @@ public interface RSClient extends RSGameEngine, Client
|
||||
boolean isMenuOpen();
|
||||
|
||||
@Import("gameCycle")
|
||||
@Override
|
||||
int getGameCycle();
|
||||
|
||||
@Import("packetHandler")
|
||||
|
||||
@@ -27,7 +27,7 @@ package net.runelite.rs.api;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.mapping.Import;
|
||||
|
||||
public interface RSProjectile extends Projectile
|
||||
public interface RSProjectile extends RSRenderable, Projectile
|
||||
{
|
||||
@Import("id")
|
||||
@Override
|
||||
@@ -35,4 +35,68 @@ public interface RSProjectile extends Projectile
|
||||
|
||||
@Import("interacting")
|
||||
int getRsInteracting();
|
||||
|
||||
@Import("height")
|
||||
@Override
|
||||
int getHeight();
|
||||
|
||||
@Import("endHeight")
|
||||
@Override
|
||||
int getEndHeight();
|
||||
|
||||
@Import("x1")
|
||||
@Override
|
||||
int getX1();
|
||||
|
||||
@Import("y1")
|
||||
@Override
|
||||
int getY1();
|
||||
|
||||
@Import("floor")
|
||||
@Override
|
||||
int getFloor();
|
||||
|
||||
@Import("startMovementCycle")
|
||||
@Override
|
||||
int getStartMovementCycle();
|
||||
|
||||
@Import("endCycle")
|
||||
@Override
|
||||
int getEndCycle();
|
||||
|
||||
@Import("slope")
|
||||
@Override
|
||||
int getSlope();
|
||||
|
||||
@Import("startHeight")
|
||||
@Override
|
||||
int getStartHeight();
|
||||
|
||||
@Import("x")
|
||||
@Override
|
||||
double getX();
|
||||
|
||||
@Import("y")
|
||||
@Override
|
||||
double getY();
|
||||
|
||||
@Import("z")
|
||||
@Override
|
||||
double getZ();
|
||||
|
||||
@Import("scalar")
|
||||
@Override
|
||||
double getScalar();
|
||||
|
||||
@Import("velocityX")
|
||||
@Override
|
||||
double getVelocityX();
|
||||
|
||||
@Import("velocityY")
|
||||
@Override
|
||||
double getVelocityY();
|
||||
|
||||
@Import("velocityZ")
|
||||
@Override
|
||||
double getVelocityZ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user