hydra: config options and useless stun timer (#1731)
hydra: config options and useless stun timer
This commit is contained in:
@@ -1819,4 +1819,24 @@ public interface Client extends GameShell
|
|||||||
void setSelectedSpellWidget(int widgetID);
|
void setSelectedSpellWidget(int widgetID);
|
||||||
|
|
||||||
void setSelectedSpellChildIndex(int index);
|
void setSelectedSpellChildIndex(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scales values from pixels onto canvas
|
||||||
|
*
|
||||||
|
* @see net.runelite.client.util.ImageUtil#resizeSprite(Client, Sprite, int, int)
|
||||||
|
*
|
||||||
|
* @param canvas the array we're writing to
|
||||||
|
* @param pixels pixels to draw
|
||||||
|
* @param color should be 0
|
||||||
|
* @param pixelX x index
|
||||||
|
* @param pixelY y index
|
||||||
|
* @param canvasIdx index in canvas (canvas[canvasIdx])
|
||||||
|
* @param canvasOffset x offset
|
||||||
|
* @param newWidth new width
|
||||||
|
* @param newHeight new height
|
||||||
|
* @param pixelWidth pretty much horizontal scale
|
||||||
|
* @param pixelHeight pretty much vertical scale
|
||||||
|
* @param oldWidth old width
|
||||||
|
*/
|
||||||
|
void scaleSprite(int[] canvas, int[] pixels, int color, int pixelX, int pixelY, int canvasIdx, int canvasOffset, int newWidth, int newHeight, int pixelWidth, int pixelHeight, int oldWidth);
|
||||||
}
|
}
|
||||||
@@ -92,4 +92,20 @@ public interface Sprite
|
|||||||
* @param color target color
|
* @param color target color
|
||||||
*/
|
*/
|
||||||
void toBufferedOutline(BufferedImage img, int color);
|
void toBufferedOutline(BufferedImage img, int color);
|
||||||
|
|
||||||
|
int getMaxWidth();
|
||||||
|
|
||||||
|
void setMaxWidth(int maxWidth);
|
||||||
|
|
||||||
|
int getMaxHeight();
|
||||||
|
|
||||||
|
void setMaxHeight(int maxHeight);
|
||||||
|
|
||||||
|
int getOffsetX();
|
||||||
|
|
||||||
|
void setOffsetX(int offsetX);
|
||||||
|
|
||||||
|
int getOffsetY();
|
||||||
|
|
||||||
|
void setOffsetY(int offsetY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1573,6 +1573,8 @@ public final class SpriteID
|
|||||||
/* Unmapped: 1709, 1710 */
|
/* Unmapped: 1709, 1710 */
|
||||||
public static final int TAB_MAGIC_SPELLBOOK_ARCEUUS = 1711;
|
public static final int TAB_MAGIC_SPELLBOOK_ARCEUUS = 1711;
|
||||||
public static final int BIG_ASS_GUTHIX_SPELL = 1774;
|
public static final int BIG_ASS_GUTHIX_SPELL = 1774;
|
||||||
|
public static final int BIG_ASS_GREY_ENTANGLE = 1788;
|
||||||
|
public static final int BIG_ASS_WHITE_ENTANGLE = 1789;
|
||||||
public static final int BIG_SUPERHEAT = 1800;
|
public static final int BIG_SUPERHEAT = 1800;
|
||||||
public static final int BIG_SPEC_TRANSFER = 1959;
|
public static final int BIG_SPEC_TRANSFER = 1959;
|
||||||
/* Unmapped: 1712~2175 */
|
/* Unmapped: 1712~2175 */
|
||||||
|
|||||||
@@ -54,6 +54,12 @@ public enum VarPlayer
|
|||||||
|
|
||||||
NMZ_REWARD_POINTS(1060),
|
NMZ_REWARD_POINTS(1060),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 11 least significant bits of this var correspond to the player
|
||||||
|
* you're currently fighting. Value is -1 when not fighting any player.
|
||||||
|
*
|
||||||
|
* Client.getVar(ATTACKING_PLAYER) & 2047 == Client.getLocalInteractingIndex();
|
||||||
|
*/
|
||||||
ATTACKING_PLAYER(1075),
|
ATTACKING_PLAYER(1075),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -688,7 +688,9 @@ public enum Varbits
|
|||||||
*/
|
*/
|
||||||
GAUNTLET_ENTERED(9178),
|
GAUNTLET_ENTERED(9178),
|
||||||
|
|
||||||
WITHDRAW_X_AMOUNT(3960);
|
WITHDRAW_X_AMOUNT(3960),
|
||||||
|
|
||||||
|
IN_PVP_AREA(8121);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The raw varbit ID.
|
* The raw varbit ID.
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||||
|
* 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.alchemicalhydra;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import net.runelite.client.config.Alpha;
|
||||||
|
import net.runelite.client.config.Config;
|
||||||
|
import net.runelite.client.config.ConfigGroup;
|
||||||
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
import net.runelite.client.config.ConfigSection;
|
||||||
|
|
||||||
|
@ConfigGroup("betterHydra")
|
||||||
|
public interface HydraConfig extends Config
|
||||||
|
{
|
||||||
|
@ConfigSection(
|
||||||
|
keyName = "features",
|
||||||
|
name = "Features",
|
||||||
|
description = "Feathers. Jk, features",
|
||||||
|
position = 0
|
||||||
|
)
|
||||||
|
default boolean features()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "counting",
|
||||||
|
name = "Prayer helper",
|
||||||
|
description = "Basically everything this plugin is known for. Also has attacks between specs and poison overlay. Shouldn't NOT use this tbh",
|
||||||
|
position = 1,
|
||||||
|
section = "features"
|
||||||
|
)
|
||||||
|
default boolean counting()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "fountain",
|
||||||
|
name = "Fountain helper",
|
||||||
|
description = "Indicates if hydra is on a fountain",
|
||||||
|
position = 2,
|
||||||
|
section = "features"
|
||||||
|
)
|
||||||
|
default boolean fountain()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "stun",
|
||||||
|
name = "Stun timer",
|
||||||
|
description = "Shows when you can walk in fire phase",
|
||||||
|
position = 3,
|
||||||
|
section = "features"
|
||||||
|
)
|
||||||
|
default boolean stun()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigSection(
|
||||||
|
keyName = "colours",
|
||||||
|
name = "Colours",
|
||||||
|
description = "colours...",
|
||||||
|
position = 2
|
||||||
|
)
|
||||||
|
default boolean colours()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alpha
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "safeCol",
|
||||||
|
name = "Safe colour",
|
||||||
|
description = "Colour overlay will be when there's >2 attacks left",
|
||||||
|
position = 1,
|
||||||
|
section = "colours"
|
||||||
|
)
|
||||||
|
default Color safeCol()
|
||||||
|
{
|
||||||
|
return new Color(0, 156, 0, 156);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alpha
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "medCol",
|
||||||
|
name = "Medium colour",
|
||||||
|
description = "Colour overlay will be when a input is coming up",
|
||||||
|
position = 2,
|
||||||
|
section = "colours"
|
||||||
|
)
|
||||||
|
default Color medCol()
|
||||||
|
{
|
||||||
|
return new Color(200, 156, 0, 156);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alpha
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "badCol",
|
||||||
|
name = "Bad colour",
|
||||||
|
description = "Colour overlay will be when you have to do something NOW",
|
||||||
|
position = 3,
|
||||||
|
section = "colours"
|
||||||
|
)
|
||||||
|
default Color badCol()
|
||||||
|
{
|
||||||
|
return new Color(156, 0, 0, 156);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alpha
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "poisonBorderCol",
|
||||||
|
name = "Poison border colour",
|
||||||
|
description = "Colour the edges of the area highlighted by poison special will be",
|
||||||
|
position = 4,
|
||||||
|
section = "colours"
|
||||||
|
)
|
||||||
|
default Color poisonBorderCol()
|
||||||
|
{
|
||||||
|
return new Color(255, 0, 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alpha
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "poisonCol",
|
||||||
|
name = "Poison colour",
|
||||||
|
description = "Colour the fill of the area highlighted by poison special will be",
|
||||||
|
position = 5,
|
||||||
|
section = "colours"
|
||||||
|
)
|
||||||
|
default Color poisonCol()
|
||||||
|
{
|
||||||
|
return new Color(255, 0, 0, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alpha
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "fountainColA",
|
||||||
|
name = "Fountain colour (not on top)",
|
||||||
|
description = "Fountain colour (not on top)",
|
||||||
|
position = 6,
|
||||||
|
section = "colours"
|
||||||
|
)
|
||||||
|
default Color fountainColA()
|
||||||
|
{
|
||||||
|
return new Color(255, 0, 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Alpha
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "fountainColB",
|
||||||
|
name = "Fountain colour (on top)",
|
||||||
|
description = "Fountain colour (on top)",
|
||||||
|
position = 7,
|
||||||
|
section = "colours"
|
||||||
|
)
|
||||||
|
default Color fountainColB()
|
||||||
|
{
|
||||||
|
return new Color(0, 255, 0, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,24 +28,27 @@ import java.awt.Color;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Setter;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.IndexDataBase;
|
||||||
import net.runelite.api.Prayer;
|
import net.runelite.api.Prayer;
|
||||||
|
import net.runelite.api.Sprite;
|
||||||
|
import net.runelite.api.SpriteID;
|
||||||
import net.runelite.client.game.SpriteManager;
|
import net.runelite.client.game.SpriteManager;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
||||||
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
||||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
import net.runelite.client.util.ImageUtil;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class HydraOverlay extends Overlay
|
class HydraOverlay extends Overlay
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final Color RED_BG_COL = new Color(156, 0, 0, 156);
|
|
||||||
private static final Color YEL_BG_COL = new Color(200, 156, 0, 156);
|
|
||||||
private static final Color GRN_BG_COL = new Color(0, 156, 0, 156);
|
|
||||||
static final int IMGSIZE = 36;
|
static final int IMGSIZE = 36;
|
||||||
|
|
||||||
private final HydraPlugin plugin;
|
private final HydraPlugin plugin;
|
||||||
@@ -53,50 +56,104 @@ class HydraOverlay extends Overlay
|
|||||||
private final SpriteManager spriteManager;
|
private final SpriteManager spriteManager;
|
||||||
private final PanelComponent panelComponent = new PanelComponent();
|
private final PanelComponent panelComponent = new PanelComponent();
|
||||||
|
|
||||||
|
private BufferedImage stunImg;
|
||||||
|
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private Color safeCol;
|
||||||
|
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private Color medCol;
|
||||||
|
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private Color badCol;
|
||||||
|
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private int stunTicks;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
HydraOverlay(final HydraPlugin plugin, final Client client, final SpriteManager spriteManager)
|
HydraOverlay(final HydraPlugin plugin, final Client client, final SpriteManager spriteManager)
|
||||||
{
|
{
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.spriteManager = spriteManager;
|
this.spriteManager = spriteManager;
|
||||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
this.setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||||
panelComponent.setOrientation(ComponentOrientation.VERTICAL);
|
panelComponent.setOrientation(ComponentOrientation.VERTICAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics2D)
|
public Dimension render(Graphics2D graphics2D)
|
||||||
{
|
{
|
||||||
Hydra hydra = plugin.getHydra();
|
final Hydra hydra = plugin.getHydra();
|
||||||
panelComponent.getChildren().clear();
|
panelComponent.getChildren().clear();
|
||||||
|
|
||||||
if (hydra == null || client == null)
|
if (hydra == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add spec overlay first, to keep it above pray
|
// First add stunned thing if needed
|
||||||
|
if (stunTicks > 0)
|
||||||
|
{
|
||||||
|
addStunOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (plugin.isCounting())
|
||||||
|
{
|
||||||
|
// Add spec box second, to keep it above pray
|
||||||
|
addSpecOverlay(hydra);
|
||||||
|
|
||||||
|
// Finally add prayer box
|
||||||
|
addPrayOverlay(hydra);
|
||||||
|
}
|
||||||
|
|
||||||
|
panelComponent.setPreferredSize(new Dimension(40, 0));
|
||||||
|
panelComponent.setBorder(new Rectangle(0, 0, 0, 0));
|
||||||
|
|
||||||
|
return panelComponent.render(graphics2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addStunOverlay()
|
||||||
|
{
|
||||||
|
final InfoBoxComponent stunComponent = new InfoBoxComponent();
|
||||||
|
|
||||||
|
stunComponent.setBackgroundColor(badCol);
|
||||||
|
stunComponent.setImage(getStunImg());
|
||||||
|
stunComponent.setText(" " + stunTicks);
|
||||||
|
stunComponent.setPreferredSize(new Dimension(40, 40));
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(stunComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSpecOverlay(final Hydra hydra)
|
||||||
|
{
|
||||||
final HydraPhase phase = hydra.getPhase();
|
final HydraPhase phase = hydra.getPhase();
|
||||||
final int nextSpec = hydra.getNextSpecialRelative();
|
final int nextSpec = hydra.getNextSpecialRelative();
|
||||||
|
|
||||||
if (nextSpec <= 3)
|
if (nextSpec > 3)
|
||||||
{
|
{
|
||||||
InfoBoxComponent specComponent = new InfoBoxComponent();
|
return;
|
||||||
|
}
|
||||||
|
final InfoBoxComponent specComponent = new InfoBoxComponent();
|
||||||
|
|
||||||
if (nextSpec == 0)
|
if (nextSpec == 0)
|
||||||
{
|
{
|
||||||
specComponent.setBackgroundColor(RED_BG_COL);
|
specComponent.setBackgroundColor(badCol);
|
||||||
}
|
}
|
||||||
else if (nextSpec == 1)
|
else if (nextSpec == 1)
|
||||||
{
|
{
|
||||||
specComponent.setBackgroundColor(YEL_BG_COL);
|
specComponent.setBackgroundColor(medCol);
|
||||||
}
|
|
||||||
|
|
||||||
specComponent.setImage(phase.getSpecImage(spriteManager));
|
|
||||||
specComponent.setText(" " + (nextSpec)); //hacky way to not have to figure out how to move text
|
|
||||||
specComponent.setPreferredSize(new Dimension(40, 40));
|
|
||||||
panelComponent.getChildren().add(specComponent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
specComponent.setImage(phase.getSpecImage(spriteManager));
|
||||||
|
specComponent.setText(" " + nextSpec); // hacky way to not have to figure out how to move text
|
||||||
|
specComponent.setPreferredSize(new Dimension(40, 40));
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(specComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPrayOverlay(final Hydra hydra)
|
||||||
|
{
|
||||||
final Prayer nextPrayer = hydra.getNextAttack().getPrayer();
|
final Prayer nextPrayer = hydra.getNextAttack().getPrayer();
|
||||||
final int nextSwitch = hydra.getNextSwitch();
|
final int nextSwitch = hydra.getNextSwitch();
|
||||||
|
|
||||||
@@ -104,21 +161,65 @@ class HydraOverlay extends Overlay
|
|||||||
|
|
||||||
if (nextSwitch == 1)
|
if (nextSwitch == 1)
|
||||||
{
|
{
|
||||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? YEL_BG_COL : RED_BG_COL);
|
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? medCol : badCol);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? GRN_BG_COL : RED_BG_COL);
|
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? safeCol : badCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
prayComponent.setImage(hydra.getNextAttack().getImage(spriteManager));
|
prayComponent.setImage(hydra.getNextAttack().getImage(spriteManager));
|
||||||
prayComponent.setText(" " + nextSwitch);
|
prayComponent.setText(" " + nextSwitch);
|
||||||
prayComponent.setColor(Color.white);
|
prayComponent.setColor(Color.white);
|
||||||
prayComponent.setPreferredSize(new Dimension(40, 40));
|
prayComponent.setPreferredSize(new Dimension(40, 40));
|
||||||
panelComponent.getChildren().add(prayComponent);
|
|
||||||
|
|
||||||
panelComponent.setPreferredSize(new Dimension(40, 0));
|
panelComponent.getChildren().add(prayComponent);
|
||||||
panelComponent.setBorder(new Rectangle(0, 0, 0, 0));
|
}
|
||||||
return panelComponent.render(graphics2D);
|
|
||||||
|
boolean onGameTick()
|
||||||
|
{
|
||||||
|
return --stunTicks <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedImage getStunImg()
|
||||||
|
{
|
||||||
|
if (stunImg == null)
|
||||||
|
{
|
||||||
|
stunImg = createStunImage(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stunImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BufferedImage createStunImage(Client client)
|
||||||
|
{
|
||||||
|
final Sprite root = getSprite(client, SpriteID.BIG_ASS_GREY_ENTANGLE);
|
||||||
|
final Sprite mark = getSprite(client, SpriteID.TRADE_EXCLAMATION_MARK_ITEM_REMOVAL_WARNING);
|
||||||
|
|
||||||
|
if (mark == null || root == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Sprite sprite = ImageUtil.mergeSprites(client, ImageUtil.resizeSprite(client, root, IMGSIZE, IMGSIZE), mark);
|
||||||
|
|
||||||
|
return sprite.toBufferedImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Sprite getSprite(Client client, int id)
|
||||||
|
{
|
||||||
|
final IndexDataBase spriteDb = client.getIndexSprites();
|
||||||
|
if (spriteDb == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Sprite[] sprites = client.getSprites(spriteDb, id, 0);
|
||||||
|
if (sprites == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprites[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.alchemicalhydra;
|
package net.runelite.client.plugins.alchemicalhydra;
|
||||||
|
|
||||||
|
import com.google.inject.Provides;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -44,9 +45,12 @@ import net.runelite.api.Projectile;
|
|||||||
import net.runelite.api.coords.LocalPoint;
|
import net.runelite.api.coords.LocalPoint;
|
||||||
import net.runelite.api.events.AnimationChanged;
|
import net.runelite.api.events.AnimationChanged;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
import net.runelite.api.events.GameStateChanged;
|
||||||
|
import net.runelite.api.events.GameTick;
|
||||||
import net.runelite.api.events.NpcSpawned;
|
import net.runelite.api.events.NpcSpawned;
|
||||||
import net.runelite.api.events.ProjectileMoved;
|
import net.runelite.api.events.ProjectileMoved;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.eventbus.EventBus;
|
import net.runelite.client.eventbus.EventBus;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
@@ -71,6 +75,15 @@ public class HydraPlugin extends Plugin
|
|||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private Hydra hydra;
|
private Hydra hydra;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean counting;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean fountain;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean stun;
|
||||||
|
|
||||||
private boolean inHydraInstance;
|
private boolean inHydraInstance;
|
||||||
private int lastAttackTick;
|
private int lastAttackTick;
|
||||||
|
|
||||||
@@ -78,26 +91,40 @@ public class HydraPlugin extends Plugin
|
|||||||
5279, 5280,
|
5279, 5280,
|
||||||
5535, 5536
|
5535, 5536
|
||||||
};
|
};
|
||||||
|
private static final int STUN_LENGTH = 7;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OverlayManager overlayManager;
|
private EventBus eventBus;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private HydraConfig config;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private HydraOverlay overlay;
|
private HydraOverlay overlay;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private HydraSceneOverlay poisonOverlay;
|
private HydraSceneOverlay sceneOverlay;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EventBus eventBus;
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
HydraConfig provideConfig(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
return configManager.getConfig(HydraConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startUp()
|
protected void startUp()
|
||||||
{
|
{
|
||||||
|
initConfig();
|
||||||
|
|
||||||
|
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||||
eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||||
|
|
||||||
inHydraInstance = checkArea();
|
inHydraInstance = checkArea();
|
||||||
lastAttackTick = -1;
|
lastAttackTick = -1;
|
||||||
poisonProjectiles.clear();
|
poisonProjectiles.clear();
|
||||||
@@ -117,6 +144,20 @@ public class HydraPlugin extends Plugin
|
|||||||
lastAttackTick = -1;
|
lastAttackTick = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initConfig()
|
||||||
|
{
|
||||||
|
this.counting = config.counting();
|
||||||
|
this.fountain = config.fountain();
|
||||||
|
this.stun = config.stun();
|
||||||
|
this.overlay.setSafeCol(config.safeCol());
|
||||||
|
this.overlay.setMedCol(config.medCol());
|
||||||
|
this.overlay.setBadCol(config.badCol());
|
||||||
|
this.sceneOverlay.setPoisonBorder(config.poisonBorderCol());
|
||||||
|
this.sceneOverlay.setPoisonFill(config.poisonCol());
|
||||||
|
this.sceneOverlay.setBadFountain(config.fountainColA());
|
||||||
|
this.sceneOverlay.setGoodFountain(config.fountainColB());
|
||||||
|
}
|
||||||
|
|
||||||
private void addFightSubscriptions()
|
private void addFightSubscriptions()
|
||||||
{
|
{
|
||||||
eventBus.subscribe(AnimationChanged.class, "fight", this::onAnimationChanged);
|
eventBus.subscribe(AnimationChanged.class, "fight", this::onAnimationChanged);
|
||||||
@@ -124,6 +165,48 @@ public class HydraPlugin extends Plugin
|
|||||||
eventBus.subscribe(ChatMessage.class, "fight", this::onChatMessage);
|
eventBus.subscribe(ChatMessage.class, "fight", this::onChatMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onConfigChanged(ConfigChanged event)
|
||||||
|
{
|
||||||
|
if (!event.getGroup().equals("betterHydra"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.getKey())
|
||||||
|
{
|
||||||
|
case "counting":
|
||||||
|
this.counting = config.counting();
|
||||||
|
break;
|
||||||
|
case "fountain":
|
||||||
|
this.fountain = config.fountain();
|
||||||
|
break;
|
||||||
|
case "stun":
|
||||||
|
this.stun = config.stun();
|
||||||
|
break;
|
||||||
|
case "safeCol":
|
||||||
|
overlay.setSafeCol(config.safeCol());
|
||||||
|
return;
|
||||||
|
case "medCol":
|
||||||
|
overlay.setMedCol(config.medCol());
|
||||||
|
return;
|
||||||
|
case "badCol":
|
||||||
|
overlay.setBadCol(config.badCol());
|
||||||
|
return;
|
||||||
|
case "poisonBorderCol":
|
||||||
|
sceneOverlay.setPoisonBorder(config.poisonBorderCol());
|
||||||
|
break;
|
||||||
|
case "poisonCol":
|
||||||
|
sceneOverlay.setPoisonFill(config.poisonCol());
|
||||||
|
break;
|
||||||
|
case "fountainColA":
|
||||||
|
sceneOverlay.setBadFountain(config.fountainColA());
|
||||||
|
break;
|
||||||
|
case "fountainColB":
|
||||||
|
sceneOverlay.setGoodFountain(config.fountainColB());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onGameStateChanged(GameStateChanged state)
|
private void onGameStateChanged(GameStateChanged state)
|
||||||
{
|
{
|
||||||
if (state.getGameState() != GameState.LOGGED_IN)
|
if (state.getGameState() != GameState.LOGGED_IN)
|
||||||
@@ -270,12 +353,27 @@ public class HydraPlugin extends Plugin
|
|||||||
|
|
||||||
private void onChatMessage(ChatMessage event)
|
private void onChatMessage(ChatMessage event)
|
||||||
{
|
{
|
||||||
if (!event.getMessage().equals("The chemicals neutralise the Alchemical Hydra's defences!"))
|
if (event.getMessage().equals("The chemicals neutralise the Alchemical Hydra's defences!"))
|
||||||
{
|
{
|
||||||
return;
|
hydra.setWeakened(true);
|
||||||
}
|
}
|
||||||
|
else if (event.getMessage().equals("The Alchemical Hydra temporarily stuns you."))
|
||||||
|
{
|
||||||
|
if (isStun())
|
||||||
|
{
|
||||||
|
overlay.setStunTicks(STUN_LENGTH);
|
||||||
|
eventBus.subscribe(GameTick.class, "hydraStun", this::onGameTick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hydra.setWeakened(true);
|
private void onGameTick(GameTick tick)
|
||||||
|
{
|
||||||
|
if (overlay.onGameTick())
|
||||||
|
{
|
||||||
|
// unregister self when 7 ticks have passed
|
||||||
|
eventBus.unregister("hydraStun");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkArea()
|
private boolean checkArea()
|
||||||
@@ -285,13 +383,20 @@ public class HydraPlugin extends Plugin
|
|||||||
|
|
||||||
private void addOverlays()
|
private void addOverlays()
|
||||||
{
|
{
|
||||||
overlayManager.add(overlay);
|
if (counting || stun)
|
||||||
overlayManager.add(poisonOverlay);
|
{
|
||||||
|
overlayManager.add(overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counting || fountain)
|
||||||
|
{
|
||||||
|
overlayManager.add(sceneOverlay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeOverlays()
|
private void removeOverlays()
|
||||||
{
|
{
|
||||||
overlayManager.remove(overlay);
|
overlayManager.remove(overlay);
|
||||||
overlayManager.remove(poisonOverlay);
|
overlayManager.remove(sceneOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import java.util.Collection;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Setter;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import static net.runelite.api.Perspective.getCanvasTileAreaPoly;
|
import static net.runelite.api.Perspective.getCanvasTileAreaPoly;
|
||||||
import net.runelite.api.Projectile;
|
import net.runelite.api.Projectile;
|
||||||
@@ -47,9 +49,17 @@ import net.runelite.client.ui.overlay.OverlayPosition;
|
|||||||
@Singleton
|
@Singleton
|
||||||
class HydraSceneOverlay extends Overlay
|
class HydraSceneOverlay extends Overlay
|
||||||
{
|
{
|
||||||
private static final Color GREEN = new Color(0, 255, 0, 100);
|
@Setter(AccessLevel.PACKAGE)
|
||||||
private static final Color RED = new Color(255, 0, 0, 100);
|
private Color poisonBorder;
|
||||||
private static final Color REDFILL = new Color(255, 0, 0, 50);
|
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private Color poisonFill;
|
||||||
|
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private Color goodFountain;
|
||||||
|
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private Color badFountain;
|
||||||
|
|
||||||
private final HydraPlugin plugin;
|
private final HydraPlugin plugin;
|
||||||
private final Client client;
|
private final Client client;
|
||||||
@@ -69,12 +79,12 @@ class HydraSceneOverlay extends Overlay
|
|||||||
Hydra hydra = plugin.getHydra();
|
Hydra hydra = plugin.getHydra();
|
||||||
final Map<LocalPoint, Projectile> poisonProjectiles = plugin.getPoisonProjectiles();
|
final Map<LocalPoint, Projectile> poisonProjectiles = plugin.getPoisonProjectiles();
|
||||||
|
|
||||||
if (!poisonProjectiles.isEmpty())
|
if (plugin.isCounting() && !poisonProjectiles.isEmpty())
|
||||||
{
|
{
|
||||||
drawPoisonArea(graphics, poisonProjectiles);
|
drawPoisonArea(graphics, poisonProjectiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hydra.getPhase().getFountain() != null)
|
if (plugin.isFountain() && hydra.getPhase().getFountain() != null)
|
||||||
{
|
{
|
||||||
drawFountain(graphics, hydra);
|
drawFountain(graphics, hydra);
|
||||||
}
|
}
|
||||||
@@ -103,9 +113,9 @@ class HydraSceneOverlay extends Overlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
graphics.setPaintMode();
|
graphics.setPaintMode();
|
||||||
graphics.setColor(RED);
|
graphics.setColor(poisonBorder);
|
||||||
graphics.draw(poisonTiles);
|
graphics.draw(poisonTiles);
|
||||||
graphics.setColor(REDFILL);
|
graphics.setColor(poisonFill);
|
||||||
graphics.fill(poisonTiles);
|
graphics.fill(poisonTiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,11 +151,11 @@ class HydraSceneOverlay extends Overlay
|
|||||||
|
|
||||||
if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
|
if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
|
||||||
{ // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE
|
{ // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE
|
||||||
color = GREEN;
|
color = goodFountain;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
color = RED;
|
color = badFountain;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.setColor(color);
|
graphics.setColor(color);
|
||||||
|
|||||||
@@ -579,4 +579,134 @@ public class ImageUtil
|
|||||||
|
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize Sprite sprite to given width (newW) and height (newH)
|
||||||
|
*/
|
||||||
|
public static Sprite resizeSprite(final Client client, final Sprite sprite, int newW, int newH)
|
||||||
|
{
|
||||||
|
assert newW > 0 && newH > 0;
|
||||||
|
|
||||||
|
final int oldW = sprite.getWidth();
|
||||||
|
final int oldH = sprite.getHeight();
|
||||||
|
|
||||||
|
if (oldW == newW && oldH == newH)
|
||||||
|
{
|
||||||
|
return sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int[] canvas = new int[newW * newH];
|
||||||
|
final int[] pixels = sprite.getPixels();
|
||||||
|
|
||||||
|
final Sprite result = client.createSprite(canvas, newW, newH);
|
||||||
|
|
||||||
|
int pixelX = 0;
|
||||||
|
int pixelY = 0;
|
||||||
|
|
||||||
|
final int oldMaxW = sprite.getMaxWidth();
|
||||||
|
final int oldMaxH = sprite.getMaxHeight();
|
||||||
|
|
||||||
|
final int pixelW = (oldMaxW << 16) / newW;
|
||||||
|
final int pixelH = (oldMaxH << 16) / newH;
|
||||||
|
|
||||||
|
int xOffset = 0;
|
||||||
|
int yOffset = 0;
|
||||||
|
|
||||||
|
int canvasIdx;
|
||||||
|
if (sprite.getOffsetX() > 0)
|
||||||
|
{
|
||||||
|
canvasIdx = (pixelW + (sprite.getOffsetX() << 16) - 1) / pixelW;
|
||||||
|
xOffset += canvasIdx;
|
||||||
|
pixelX += canvasIdx * pixelW - (sprite.getOffsetX() << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprite.getOffsetY() > 0)
|
||||||
|
{
|
||||||
|
canvasIdx = (pixelH + (sprite.getOffsetY() << 16) - 1) / pixelH;
|
||||||
|
yOffset += canvasIdx;
|
||||||
|
pixelY += canvasIdx * pixelH - (sprite.getOffsetY() << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldW < oldMaxW)
|
||||||
|
{
|
||||||
|
newW = (pixelW + ((oldW << 16) - pixelX) - 1) / pixelW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldH < oldMaxH)
|
||||||
|
{
|
||||||
|
newH = (pixelH + ((oldH << 16) - pixelY) - 1) / pixelH;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvasIdx = xOffset + yOffset * newW;
|
||||||
|
int canvasOffset = 0;
|
||||||
|
if (yOffset + newH > newH)
|
||||||
|
{
|
||||||
|
newH -= yOffset + newH - newH;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmp;
|
||||||
|
if (yOffset < 0)
|
||||||
|
{
|
||||||
|
tmp = -yOffset;
|
||||||
|
newH -= tmp;
|
||||||
|
canvasIdx += tmp * newW;
|
||||||
|
pixelY += pixelH * tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newW + xOffset > newW)
|
||||||
|
{
|
||||||
|
tmp = newW + xOffset - newW;
|
||||||
|
newW -= tmp;
|
||||||
|
canvasOffset += tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xOffset < 0)
|
||||||
|
{
|
||||||
|
tmp = -xOffset;
|
||||||
|
newW -= tmp;
|
||||||
|
canvasIdx += tmp;
|
||||||
|
pixelX += pixelW * tmp;
|
||||||
|
canvasOffset += tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.scaleSprite(canvas, pixels, 0, pixelX, pixelY, canvasIdx, canvasOffset, newW, newH, pixelW, pixelH, oldW);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw fg centered on top of bg
|
||||||
|
*/
|
||||||
|
public static Sprite mergeSprites(final Client client, final Sprite bg, final Sprite fg)
|
||||||
|
{
|
||||||
|
assert fg.getHeight() <= bg.getHeight() && fg.getWidth() <= bg.getWidth() : "Background has to be larger than foreground";
|
||||||
|
|
||||||
|
final int[] canvas = Arrays.copyOf(bg.getPixels(), bg.getWidth() * bg.getHeight());
|
||||||
|
final Sprite result = client.createSprite(canvas, bg.getWidth(), bg.getHeight());
|
||||||
|
|
||||||
|
final int bgWid = bg.getWidth();
|
||||||
|
final int fgHgt = fg.getHeight();
|
||||||
|
final int fgWid = fg.getWidth();
|
||||||
|
|
||||||
|
final int xOffset = (bgWid - fgWid) / 2;
|
||||||
|
final int yOffset = (bg.getHeight() - fgHgt) / 2;
|
||||||
|
|
||||||
|
final int[] fgPixels = fg.getPixels();
|
||||||
|
|
||||||
|
for (int y1 = yOffset, y2 = 0; y2 < fgHgt; y1++, y2++)
|
||||||
|
{
|
||||||
|
int i1 = y1 * bgWid + xOffset;
|
||||||
|
int i2 = y2 * fgWid;
|
||||||
|
|
||||||
|
for (int x = 0; x < fgWid; x++, i1++, i2++)
|
||||||
|
{
|
||||||
|
if (fgPixels[i2] > 0)
|
||||||
|
{
|
||||||
|
canvas[i1] = fgPixels[i2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1086,4 +1086,8 @@ public interface RSClient extends RSGameShell, Client
|
|||||||
@Import("selectedSpellChildIndex")
|
@Import("selectedSpellChildIndex")
|
||||||
@Override
|
@Override
|
||||||
void setSelectedSpellChildIndex(int index);
|
void setSelectedSpellChildIndex(int index);
|
||||||
|
|
||||||
|
@Import("Sprite_drawScaled")
|
||||||
|
@Override
|
||||||
|
void scaleSprite(int[] canvas, int[] pixels, int color, int pixelX, int pixelY, int canvasIdx, int canvasOffset, int newWidth, int newHeight, int pixelWidth, int pixelHeight, int oldWidth);
|
||||||
}
|
}
|
||||||
@@ -25,14 +25,34 @@ public interface RSSprite extends Sprite
|
|||||||
void setRaster();
|
void setRaster();
|
||||||
|
|
||||||
@Import("width")
|
@Import("width")
|
||||||
|
@Override
|
||||||
|
int getMaxWidth();
|
||||||
|
|
||||||
|
@Import("width")
|
||||||
|
@Override
|
||||||
void setMaxWidth(int maxWidth);
|
void setMaxWidth(int maxWidth);
|
||||||
|
|
||||||
@Import("height")
|
@Import("height")
|
||||||
|
@Override
|
||||||
|
int getMaxHeight();
|
||||||
|
|
||||||
|
@Import("height")
|
||||||
|
@Override
|
||||||
void setMaxHeight(int maxHeight);
|
void setMaxHeight(int maxHeight);
|
||||||
|
|
||||||
@Import("xOffset")
|
@Import("xOffset")
|
||||||
|
@Override
|
||||||
|
int getOffsetX(); ;
|
||||||
|
|
||||||
|
@Import("xOffset")
|
||||||
|
@Override
|
||||||
void setOffsetX(int offsetX);
|
void setOffsetX(int offsetX);
|
||||||
|
|
||||||
@Import("yOffset")
|
@Import("yOffset")
|
||||||
|
@Override
|
||||||
|
int getOffsetY(); ;
|
||||||
|
|
||||||
|
@Import("yOffset")
|
||||||
|
@Override
|
||||||
void setOffsetY(int offsetY);
|
void setOffsetY(int offsetY);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user