@@ -24,9 +24,14 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.antidrag;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.KeyEvent;
|
||||
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.Keybind;
|
||||
import net.runelite.client.config.ModifierlessKeybind;
|
||||
|
||||
@ConfigGroup("antiDrag")
|
||||
public interface AntiDragConfig extends Config
|
||||
@@ -41,4 +46,49 @@ public interface AntiDragConfig extends Config
|
||||
{
|
||||
return 600 / 20; // one game tick
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "keybind",
|
||||
name = "keybind",
|
||||
description = "The keybind you want to use for antidrag",
|
||||
position = 2
|
||||
)
|
||||
default Keybind key()
|
||||
{
|
||||
return new ModifierlessKeybind(KeyEvent.VK_SHIFT, 0);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "reqfocus",
|
||||
name = "Reset on focus loss",
|
||||
description = "Disable antidrag when losing focus (like alt tabbing)",
|
||||
position = 3
|
||||
)
|
||||
default boolean reqfocus()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "overlay",
|
||||
name = "Enable overlay",
|
||||
description = "Do you really need a description?",
|
||||
position = 4
|
||||
)
|
||||
default boolean overlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "color",
|
||||
name = "Overlay color",
|
||||
description = "Change the overlay color, duh",
|
||||
position = 5
|
||||
)
|
||||
default Color color()
|
||||
{
|
||||
return new Color(255, 0, 0, 30);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.runelite.client.plugins.antidrag;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
|
||||
@Singleton
|
||||
public class AntiDragOverlay extends Overlay
|
||||
{
|
||||
private static final int RADIUS = 20;
|
||||
|
||||
private Client client;
|
||||
private AntiDragConfig config;
|
||||
|
||||
@Inject
|
||||
private AntiDragOverlay(Client client, AntiDragConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.TOOLTIP);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
final Color color = config.color();
|
||||
g.setColor(color);
|
||||
|
||||
final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
|
||||
final Point mousePosition = new Point(mouseCanvasPosition.getX() - RADIUS, mouseCanvasPosition.getY() - RADIUS);
|
||||
final Rectangle bounds = new Rectangle(mousePosition.x, mousePosition.y, 2 * RADIUS, 2 * RADIUS);
|
||||
g.fillOval(bounds.x, bounds.y, bounds.height, bounds.width);
|
||||
|
||||
return bounds.getSize();
|
||||
}
|
||||
}
|
||||
@@ -25,25 +25,26 @@
|
||||
package net.runelite.client.plugins.antidrag;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.event.KeyEvent;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.HotkeyListener;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Shift Anti Drag",
|
||||
description = "Prevent dragging an item for a specified delay",
|
||||
tags = {"antidrag", "delay", "inventory", "items"}
|
||||
)
|
||||
public class AntiDragPlugin extends Plugin implements KeyListener
|
||||
public class AntiDragPlugin extends Plugin
|
||||
{
|
||||
private static final int DEFAULT_DELAY = 5;
|
||||
private boolean toggleDrag;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
@@ -51,6 +52,12 @@ public class AntiDragPlugin extends Plugin implements KeyListener
|
||||
@Inject
|
||||
private AntiDragConfig config;
|
||||
|
||||
@Inject
|
||||
private AntiDragOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@@ -63,46 +70,50 @@ public class AntiDragPlugin extends Plugin implements KeyListener
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
keyManager.registerKeyListener(this);
|
||||
keyManager.registerKeyListener(hotkeyListener);
|
||||
toggleDrag = false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
keyManager.unregisterKeyListener(this);
|
||||
keyManager.unregisterKeyListener(hotkeyListener);
|
||||
toggleDrag = false;
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
private final HotkeyListener hotkeyListener = new HotkeyListener(() -> config.key())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
@Override
|
||||
public void hotkeyPressed()
|
||||
{
|
||||
client.setInventoryDragDelay(config.dragDelay());
|
||||
}
|
||||
}
|
||||
toggleDrag = !toggleDrag;
|
||||
if (toggleDrag)
|
||||
{
|
||||
if (config.overlay())
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
client.setInventoryDragDelay(config.dragDelay());
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Subscribe
|
||||
public void onFocusChanged(FocusChanged focusChanged)
|
||||
{
|
||||
if (!focusChanged.isFocused())
|
||||
if (!focusChanged.isFocused() && config.reqfocus())
|
||||
{
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.api.coords.LocalPoint;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class AoeProjectile
|
||||
{
|
||||
private final Instant startTime;
|
||||
private final LocalPoint targetPoint;
|
||||
private final AoeProjectileInfo aoeProjectileInfo;
|
||||
|
||||
public AoeProjectile(Instant startTime, LocalPoint targetPoint, AoeProjectileInfo aoeProjectileInfo)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
this.targetPoint = targetPoint;
|
||||
this.aoeProjectileInfo = aoeProjectileInfo;
|
||||
}
|
||||
|
||||
public Instant getStartTime()
|
||||
{
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public LocalPoint getTargetPoint()
|
||||
{
|
||||
return targetPoint;
|
||||
}
|
||||
|
||||
public AoeProjectileInfo getAoeProjectileInfo()
|
||||
{
|
||||
return aoeProjectileInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
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
|
||||
{
|
||||
LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 3000, 3),
|
||||
CRAZY_ARCHAEOLOGIST_AOE(ProjectileID.CRAZY_ARCHAEOLOGIST_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 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),
|
||||
|
||||
DAWN_FREEZE(ProjectileID.DAWN_FREEZE, 3000, 3),
|
||||
DUSK_CEILING(ProjectileID.DUSK_CEILING, 3000, 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(1357, 3000, 3),
|
||||
OLM_BURNING(1349, 2400, 1),
|
||||
OLM_FALLING_CRYSTAL_TRAIL(1352, 2400, 1),
|
||||
OLM_ACID_TRAIL(1354, 2400, 1),
|
||||
OLM_FIRE_LINE(1347, 2400, 1),
|
||||
|
||||
/**
|
||||
* the AOE of the Wintertodt snow that falls
|
||||
*/
|
||||
WINTERTODT_SNOW_FALL(1310, 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;
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
return map.get(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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("aoe")
|
||||
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 = "archaeologistaoe",
|
||||
name = "Crazy Archaeologist",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Archaeologist is displayed"
|
||||
)
|
||||
default boolean isArchaeologistEnabled()
|
||||
{
|
||||
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 = "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 = "gargboss",
|
||||
name = "Gargoyle Boss",
|
||||
description = "Configs whether or not AoE Projectile Warnings for Dawn/Dusk are displayed"
|
||||
)
|
||||
default boolean isGargBossEnabled()
|
||||
{
|
||||
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 = "bombDisplay",
|
||||
name = "Display crystal phase bomb tracker",
|
||||
description = "Display a timer and colour-coded AoE for Olm's crystal-phase bombs."
|
||||
)
|
||||
default boolean bombDisplay()
|
||||
{
|
||||
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 = "wintertodt",
|
||||
name = "Wintertodt Snow Fall",
|
||||
description = "Configures whether or not AOE Projectile Warnings for the Wintertodt snow fall are displayed"
|
||||
)
|
||||
default boolean isWintertodtEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "outline",
|
||||
name = "Display Outline",
|
||||
description = "Configures whether or not AoE Projectile Warnings have an outline"
|
||||
)
|
||||
default boolean isOutlineEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lightning",
|
||||
name = "Show Lightning Trails",
|
||||
description = "Show Lightning Trails"
|
||||
)
|
||||
default boolean LightningTrail()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fade",
|
||||
name = "Fade Warnings",
|
||||
description = "Configures whether or not AoE Projectile Warnings fade over time"
|
||||
)
|
||||
default boolean isFadeEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
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)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!config.enabled())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (WorldPoint point : plugin.getLightningTrail())
|
||||
{
|
||||
drawTile(graphics, point, new Color(0,150,200), 2, 150, 50);
|
||||
}
|
||||
for (WorldPoint point : plugin.getAcidTrail())
|
||||
{
|
||||
drawTile(graphics, point, new Color(69, 241, 44), 2, 150, 50);
|
||||
}
|
||||
for (WorldPoint point : plugin.getCrystalSpike())
|
||||
{
|
||||
drawTile(graphics, point, 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();)
|
||||
{
|
||||
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, outlineAlpha;
|
||||
if (config.isFadeEnabled())
|
||||
{
|
||||
fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);//alpha drop off over lifetime
|
||||
outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
fillAlpha = FILL_START_ALPHA;
|
||||
outlineAlpha = 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(0, 150, 200, outlineAlpha));
|
||||
graphics.drawPolygon(tilePoly);
|
||||
}
|
||||
|
||||
graphics.setColor(new Color(0, 150, 200, fillAlpha));
|
||||
graphics.fillPolygon(tilePoly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) {
|
||||
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
|
||||
if (point.distanceTo(playerLocation) >= 32) {
|
||||
return;
|
||||
}
|
||||
LocalPoint lp = LocalPoint.fromWorld(client, point);
|
||||
if (lp == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
if (poly == null) {
|
||||
return;
|
||||
}
|
||||
//OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
|
||||
graphics.setStroke(new BasicStroke(strokeWidth));
|
||||
graphics.draw(poly);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
|
||||
graphics.fill(poly);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.inject.Provides;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GraphicID;
|
||||
import net.runelite.api.GraphicsObject;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GraphicsObjectCreated;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!AoE Warnings</font>",
|
||||
description = "Shows the final destination for AoE Attack projectiles",
|
||||
tags = {"bosses", "combat", "pve", "overlay"}
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class AoeWarningPlugin extends Plugin
|
||||
{
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private AoeWarningOverlay coreOverlay;
|
||||
|
||||
@Inject
|
||||
public AoeWarningConfig config;
|
||||
|
||||
@Inject
|
||||
private BombOverlay bombOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Getter
|
||||
private final Map<WorldPoint, CrystalBomb> bombs = new HashMap<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> LightningTrail = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> AcidTrail = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> CrystalSpike = new ArrayList<>();
|
||||
|
||||
|
||||
@Provides
|
||||
AoeWarningConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AoeWarningConfig.class);
|
||||
}
|
||||
|
||||
|
||||
private final Map<Projectile, AoeProjectile> projectiles = new HashMap<>();
|
||||
|
||||
public Map<Projectile, AoeProjectile> getProjectiles()
|
||||
{
|
||||
return projectiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(coreOverlay);
|
||||
overlayManager.add(bombOverlay);
|
||||
LightningTrail.clear();
|
||||
AcidTrail.clear();
|
||||
CrystalSpike.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(coreOverlay);
|
||||
overlayManager.remove(bombOverlay);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onProjectileMoved(ProjectileMoved event)
|
||||
{
|
||||
Projectile projectile = event.getProjectile();
|
||||
|
||||
int projectileId = projectile.getId();
|
||||
AoeProjectileInfo aoeProjectileInfo = AoeProjectileInfo.getById(projectileId);
|
||||
if (aoeProjectileInfo != null && isConfigEnabledForProjectileId(projectileId))
|
||||
{
|
||||
LocalPoint targetPoint = event.getPosition();
|
||||
AoeProjectile aoeProjectile = new AoeProjectile(Instant.now(), targetPoint, aoeProjectileInfo);
|
||||
projectiles.put(projectile, aoeProjectile);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
final WorldPoint bombLocation = gameObject.getWorldLocation();
|
||||
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
bombs.put(bombLocation, new CrystalBomb(gameObject, client.getTickCount()));
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
AcidTrail.add(bombLocation);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
//todo
|
||||
CrystalSpike.add(bombLocation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
WorldPoint bombLocation = gameObject.getWorldLocation();
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
//might as well check the ObjectID to save some time.
|
||||
purgeBombs(bombs);
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
AcidTrail.remove(bombLocation);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
//todo
|
||||
CrystalSpike.remove(bombLocation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged delta)
|
||||
{
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
purgeBombs(bombs);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (config.LightningTrail())
|
||||
{
|
||||
LightningTrail.clear();
|
||||
for (GraphicsObject o : client.getGraphicsObjects())
|
||||
{
|
||||
if (o.getId() == 1356)
|
||||
{
|
||||
LightningTrail.add(WorldPoint.fromLocal(client, o.getLocation()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<WorldPoint, CrystalBomb>> it = bombs.entrySet().iterator();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
Map.Entry<WorldPoint, CrystalBomb> entry = it.next();
|
||||
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);
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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 CRAZY_ARCHAEOLOGIST_AOE:
|
||||
return config.isArchaeologistEnabled();
|
||||
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();
|
||||
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 DAWN_FREEZE:
|
||||
case DUSK_CEILING:
|
||||
return config.isGargBossEnabled();
|
||||
case OLM_FALLING_CRYSTAL:
|
||||
case OLM_BURNING:
|
||||
case OLM_FALLING_CRYSTAL_TRAIL:
|
||||
case OLM_ACID_TRAIL:
|
||||
case OLM_FIRE_LINE:
|
||||
return config.isOlmEnabled();
|
||||
case CORPOREAL_BEAST:
|
||||
case CORPOREAL_BEAST_DARK_CORE:
|
||||
return config.isCorpEnabled();
|
||||
case WINTERTODT_SNOW_FALL:
|
||||
return config.isWintertodtEnabled();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2018, PallasDieKatze (Pallas Cat)
|
||||
* 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 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;
|
||||
import net.runelite.client.plugins.aoewarnings.CrystalBomb;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import javax.inject.Inject;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Color;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.BasicStroke;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
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);
|
||||
|
||||
static
|
||||
{
|
||||
((DecimalFormat) TIME_LEFT_FORMATTER).applyPattern("#0.0");
|
||||
}
|
||||
|
||||
private final Client client;
|
||||
private final AoeWarningConfig config;
|
||||
private final AoeWarningPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public BombOverlay(Client client, AoeWarningPlugin plugin, AoeWarningConfig config)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.bombDisplay())
|
||||
{
|
||||
drawBombs(graphics);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawBombs(Graphics2D graphics)
|
||||
//I can condense drawDangerZone into this. Ambivalent though.
|
||||
{
|
||||
Iterator<Map.Entry<WorldPoint, CrystalBomb>> it = plugin.getBombs().entrySet().iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
Map.Entry<WorldPoint, CrystalBomb> entry = it.next();
|
||||
CrystalBomb bomb = entry.getValue();
|
||||
drawDangerZone(graphics, bomb);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDangerZone(Graphics2D graphics, CrystalBomb bomb)
|
||||
{
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation());
|
||||
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 (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() + 0, localLoc.getY() + 0);
|
||||
Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 :)
|
||||
|
||||
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 (canvasPoint != null)
|
||||
{
|
||||
Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX() - textWidth / 2,
|
||||
canvasPoint.getY() + textHeight / 2);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, PallasDieKatze (Pallas Cat)
|
||||
* 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 lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import java.time.Instant;
|
||||
|
||||
@Slf4j
|
||||
public class CrystalBomb
|
||||
{
|
||||
@Getter
|
||||
private Instant plantedOn;
|
||||
|
||||
@Getter
|
||||
private Instant lastClockUpdate;
|
||||
|
||||
@Getter
|
||||
private int objectId;
|
||||
|
||||
@Getter
|
||||
private int tickStarted;
|
||||
//
|
||||
|
||||
@Getter
|
||||
private WorldPoint worldLocation;
|
||||
|
||||
public CrystalBomb(GameObject gameObject, int startTick)
|
||||
{
|
||||
this.plantedOn = Instant.now();
|
||||
this.objectId = gameObject.getId();
|
||||
this.worldLocation = gameObject.getWorldLocation();
|
||||
this.tickStarted = startTick;
|
||||
}
|
||||
|
||||
public void bombClockUpdate()
|
||||
{
|
||||
lastClockUpdate = Instant.now();
|
||||
}
|
||||
}
|
||||
@@ -37,17 +37,53 @@ public interface BarbarianAssaultConfig extends Config
|
||||
name = "Show call change timer",
|
||||
description = "Show time to next call change"
|
||||
)
|
||||
default boolean showTimer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default boolean showTimer() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "waveTimes",
|
||||
name = "Show wave and game duration",
|
||||
description = "Displays wave and game duration"
|
||||
)
|
||||
default boolean waveTimes() { return true; }
|
||||
@ConfigItem(
|
||||
keyName = "showEggCountMessage",
|
||||
name = "Show count of eggs collected as collector.",
|
||||
description = "Display egg count as collector after each wave",
|
||||
position = 0
|
||||
)
|
||||
default boolean showEggCount() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showEggCountOverlay",
|
||||
name = "Overlay of eggs counted",
|
||||
description = "Display current egg count as collector",
|
||||
position = 1
|
||||
)
|
||||
default boolean showEggCountOverlay() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHpCountMessage",
|
||||
name = "Show count of Hp healed as healer.",
|
||||
description = "Display healed count as healer after each wave",
|
||||
position = 2
|
||||
)
|
||||
default boolean showHpCount() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHpCountOverlay",
|
||||
name = "Overlay of Hp counted",
|
||||
description = "Display current healed count as healer",
|
||||
position = 3
|
||||
)
|
||||
default boolean showHpCountOverlay() { return false; }
|
||||
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightCollectorEggs",
|
||||
name = "Highlight collector eggs",
|
||||
description = "Highlight called egg colors"
|
||||
)
|
||||
default boolean waveTimes()
|
||||
default boolean highlightCollectorEggs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,24 +24,37 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.barbarianassault;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Stroke;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
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;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class BarbarianAssaultOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_EGG_DISTANCE = 2500;
|
||||
|
||||
private final Client client;
|
||||
private final BarbarianAssaultPlugin plugin;
|
||||
private final BarbarianAssaultConfig config;
|
||||
@@ -82,12 +95,95 @@ class BarbarianAssaultOverlay extends Overlay
|
||||
|
||||
if (config.showTimer() && roleText != null && roleSprite != null)
|
||||
{
|
||||
roleText.setText(String.format("00:%02d", currentRound.getTimeToChange()));
|
||||
if (config.showEggCountOverlay() && role.equals(Role.COLLECTOR))
|
||||
{
|
||||
roleText.setText(String.format("(%d) 00:%02d", plugin.getCollectedEggCount(), currentRound.getTimeToChange()));
|
||||
}
|
||||
else if (config.showHpCountOverlay() && role.equals(Role.HEALER))
|
||||
{
|
||||
roleText.setText(String.format("(%d) 00:%02d", plugin.getHpHealed(), currentRound.getTimeToChange()));
|
||||
}
|
||||
else
|
||||
{
|
||||
roleText.setText(String.format("00:%02d", currentRound.getTimeToChange()));
|
||||
}
|
||||
Rectangle spriteBounds = roleSprite.getBounds();
|
||||
roleSprite.setHidden(true);
|
||||
graphics.drawImage(plugin.getClockImage(), spriteBounds.x, spriteBounds.y, null);
|
||||
}
|
||||
|
||||
if (role == Role.COLLECTOR && config.highlightCollectorEggs())
|
||||
{
|
||||
String heardCall = plugin.getCollectorHeardCall();
|
||||
Color highlightColor;
|
||||
Map<WorldPoint, Integer> calledEggMap;
|
||||
|
||||
Map<WorldPoint, Integer> yellowEggMap = plugin.getYellowEggs();
|
||||
|
||||
switch (heardCall)
|
||||
{
|
||||
case "Red eggs":
|
||||
calledEggMap = plugin.getRedEggs();
|
||||
highlightColor = Color.RED;
|
||||
break;
|
||||
case "Green eggs":
|
||||
calledEggMap = plugin.getGreenEggs();
|
||||
highlightColor = Color.GREEN;
|
||||
break;
|
||||
case "Blue eggs":
|
||||
calledEggMap = plugin.getBlueEggs();
|
||||
highlightColor = Color.BLUE;
|
||||
break;
|
||||
default:
|
||||
calledEggMap = null;
|
||||
highlightColor = null;
|
||||
}
|
||||
|
||||
if (calledEggMap != null)
|
||||
{
|
||||
for (WorldPoint worldPoint : calledEggMap.keySet())
|
||||
{
|
||||
int quantity = calledEggMap.get(worldPoint);
|
||||
renderEggLocation(graphics, worldPoint, quantity, highlightColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Always show yellow eggs
|
||||
for (WorldPoint worldPoint : yellowEggMap.keySet())
|
||||
{
|
||||
int quantity = yellowEggMap.get(worldPoint);
|
||||
renderEggLocation(graphics, worldPoint, quantity, highlightColor);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderEggLocation(Graphics2D graphics, WorldPoint location, int quantity, Color color)
|
||||
{
|
||||
LocalPoint groundPoint = LocalPoint.fromWorld(client, location);
|
||||
Player player = client.getLocalPlayer();
|
||||
|
||||
if (groundPoint == null || player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getLocalLocation().distanceTo(groundPoint) > MAX_EGG_DISTANCE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, groundPoint);
|
||||
final Stroke originalStroke = graphics.getStroke();
|
||||
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.drawPolygon(poly);
|
||||
graphics.setStroke(originalStroke);
|
||||
|
||||
String quantityText = "x" + quantity;
|
||||
Point textPoint = Perspective.getCanvasTextLocation(client, graphics, groundPoint, quantityText, 0);
|
||||
OverlayUtil.renderTextLocation(graphics, textPoint, quantityText, Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,23 @@ package net.runelite.client.plugins.barbarianassault;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Font;
|
||||
import java.awt.Image;
|
||||
import java.util.HashMap;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.kit.KitType;
|
||||
@@ -58,18 +68,38 @@ import net.runelite.client.util.ImageUtil;
|
||||
description = "Show a timer to the next call change and game/wave duration in chat.",
|
||||
tags = {"minigame", "overlay", "timer"}
|
||||
)
|
||||
public class BarbarianAssaultPlugin extends Plugin
|
||||
{
|
||||
public class BarbarianAssaultPlugin extends Plugin {
|
||||
private static final int BA_WAVE_NUM_INDEX = 2;
|
||||
private static final String START_WAVE = "1";
|
||||
private static final String ENDGAME_REWARD_NEEDLE_TEXT = "<br>5";
|
||||
|
||||
@Getter
|
||||
private int collectedEggCount = 0;
|
||||
@Getter
|
||||
private int HpHealed = 0;
|
||||
@Getter
|
||||
private int totalCollectedEggCount = 0;
|
||||
@Getter
|
||||
private int totalHpHealed = 0;
|
||||
|
||||
private Font font;
|
||||
private Image clockImage;
|
||||
private int inGameBit = 0;
|
||||
private String currentWave = START_WAVE;
|
||||
private GameTimer gameTime;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private HashMap<WorldPoint, Integer> redEggs;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private HashMap<WorldPoint, Integer> greenEggs;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private HashMap<WorldPoint, Integer> blueEggs;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private HashMap<WorldPoint, Integer> yellowEggs;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@@ -86,74 +116,90 @@ public class BarbarianAssaultPlugin extends Plugin
|
||||
private BarbarianAssaultOverlay overlay;
|
||||
|
||||
@Provides
|
||||
BarbarianAssaultConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
BarbarianAssaultConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(BarbarianAssaultConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
protected void startUp() throws Exception {
|
||||
overlayManager.add(overlay);
|
||||
font = FontManager.getRunescapeFont()
|
||||
.deriveFont(Font.BOLD, 24);
|
||||
.deriveFont(Font.BOLD, 24);
|
||||
|
||||
clockImage = ImageUtil.getResourceStreamFromClass(getClass(), "clock.png");
|
||||
|
||||
redEggs = new HashMap<>();
|
||||
greenEggs = new HashMap<>();
|
||||
blueEggs = new HashMap<>();
|
||||
yellowEggs = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
protected void shutDown() throws Exception {
|
||||
overlayManager.remove(overlay);
|
||||
gameTime = null;
|
||||
currentWave = START_WAVE;
|
||||
inGameBit = 0;
|
||||
collectedEggCount = 0;
|
||||
HpHealed = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID)
|
||||
{
|
||||
public void onWidgetLoaded(WidgetLoaded event) {
|
||||
if (event.getGroupId() == WidgetID.BA_REWARD_GROUP_ID) {
|
||||
Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT);
|
||||
|
||||
if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null)
|
||||
{
|
||||
announceTime("Game finished, duration: ", gameTime.getTime(false));
|
||||
String amt,type,totalMsg,total;
|
||||
amt=type=totalMsg=total="";
|
||||
if (config.waveTimes() && rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null) {
|
||||
if (config.showHpCount() && HpHealed > 0) {
|
||||
totalMsg = "; Total Healed: ";
|
||||
total = ""+totalHpHealed;
|
||||
}
|
||||
else if (config.showEggCount() && collectedEggCount > 0) {
|
||||
totalMsg = "; Total Collected: ";
|
||||
total = ""+totalCollectedEggCount;
|
||||
}
|
||||
announceTime("Game finished, duration: ", gameTime.getTime(false),type, amt, totalMsg, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
public void onChatMessage(ChatMessage event) {
|
||||
if (event.getType() == ChatMessageType.GAMEMESSAGE
|
||||
&& event.getMessage().startsWith("---- Wave:"))
|
||||
{
|
||||
&& event.getMessage().startsWith("---- Wave:")) {
|
||||
String[] message = event.getMessage().split(" ");
|
||||
currentWave = message[BA_WAVE_NUM_INDEX];
|
||||
collectedEggCount = 0;
|
||||
HpHealed = 0;
|
||||
|
||||
if (currentWave.equals(START_WAVE))
|
||||
{
|
||||
if (currentWave.equals(START_WAVE)) {
|
||||
gameTime = new GameTimer();
|
||||
}
|
||||
else if (gameTime != null)
|
||||
{
|
||||
totalHpHealed = 0;
|
||||
totalCollectedEggCount = 0;
|
||||
} else if (gameTime != null) {
|
||||
gameTime.setWaveStartTime();
|
||||
}
|
||||
} else if (event.getType() == ChatMessageType.GAMEMESSAGE
|
||||
&& event.getMessage().contains("egg explode")) {
|
||||
collectedEggCount -= 2;
|
||||
} else if (event.getType() == ChatMessageType.GAMEMESSAGE
|
||||
&& event.getMessage().contains("healed")) {
|
||||
String message = event.getMessage();
|
||||
String[] tokens = message.split(" ");
|
||||
if (Integer.parseInt(tokens[2]) > 0) {
|
||||
int Hp = Integer.parseInt(tokens[2]);
|
||||
HpHealed += Hp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (client.getVar(Varbits.IN_GAME_BA) == 0 || client.getLocalPlayer() == null || overlay.getCurrentRound() != null)
|
||||
{
|
||||
public void onGameTick(GameTick event) {
|
||||
if (client.getVar(Varbits.IN_GAME_BA) == 0 || client.getLocalPlayer() == null || overlay.getCurrentRound() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.CAPE))
|
||||
{
|
||||
switch (client.getLocalPlayer().getPlayerComposition().getEquipmentId(KitType.CAPE)) {
|
||||
case ItemID.ATTACKER_ICON:
|
||||
overlay.setCurrentRound(new Round(Role.ATTACKER));
|
||||
break;
|
||||
@@ -170,39 +216,146 @@ public class BarbarianAssaultPlugin extends Plugin
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
public void onVarbitChanged(VarbitChanged event) {
|
||||
int inGame = client.getVar(Varbits.IN_GAME_BA);
|
||||
|
||||
if (inGameBit != inGame)
|
||||
{
|
||||
if (inGameBit == 1)
|
||||
{
|
||||
String amt,type,totalMsg,total;
|
||||
amt=type=totalMsg=total="";
|
||||
if (inGameBit != inGame) {
|
||||
if (inGameBit == 1) {
|
||||
overlay.setCurrentRound(null);
|
||||
|
||||
if (config.waveTimes() && gameTime != null)
|
||||
{
|
||||
announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true));
|
||||
if (config.waveTimes() && gameTime != null) {
|
||||
totalCollectedEggCount += collectedEggCount;
|
||||
totalHpHealed += HpHealed;
|
||||
if (config.showHpCount() && HpHealed > 0) {
|
||||
amt = "" + HpHealed;
|
||||
type = "; Healed: ";
|
||||
totalMsg = "; Total Healed: ";
|
||||
total = ""+totalHpHealed;
|
||||
}
|
||||
else if (config.showEggCount() && collectedEggCount > 0) {
|
||||
amt = "" + collectedEggCount;
|
||||
type = "; Collected: ";
|
||||
totalMsg = "; Total Collected: ";
|
||||
total = ""+totalCollectedEggCount;
|
||||
}
|
||||
if (currentWave.equals("10"))
|
||||
{
|
||||
totalMsg=total="";
|
||||
}
|
||||
announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true), type, amt, totalMsg, total);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inGameBit = inGame;
|
||||
}
|
||||
|
||||
private void announceTime(String preText, String time)
|
||||
@Subscribe
|
||||
public void onItemSpawned(ItemSpawned itemSpawned)
|
||||
{
|
||||
int itemId = itemSpawned.getItem().getId();
|
||||
WorldPoint worldPoint = itemSpawned.getTile().getWorldLocation();
|
||||
HashMap<WorldPoint, Integer> eggMap = getEggMap(itemId);
|
||||
|
||||
if (eggMap != null)
|
||||
{
|
||||
Integer existingQuantity = eggMap.putIfAbsent(worldPoint, 1);
|
||||
if (existingQuantity != null)
|
||||
{
|
||||
eggMap.put(worldPoint, existingQuantity + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemDespawned(ItemDespawned event)
|
||||
{
|
||||
if (client.getVar(Varbits.IN_GAME_BA) == 0 || !isEgg(event.getItem().getId()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (isUnderPlayer(event.getTile()))
|
||||
{
|
||||
collectedEggCount++;
|
||||
}
|
||||
}
|
||||
|
||||
String getCollectorHeardCall()
|
||||
{
|
||||
Widget widget = client.getWidget(WidgetInfo.BA_COLL_HEARD_TEXT);
|
||||
String call = null;
|
||||
|
||||
if (widget != null)
|
||||
{
|
||||
call = widget.getText();
|
||||
}
|
||||
|
||||
return call;
|
||||
}
|
||||
|
||||
|
||||
private HashMap<WorldPoint, Integer> getEggMap(int itemID)
|
||||
{
|
||||
switch (itemID)
|
||||
{
|
||||
case ItemID.RED_EGG:
|
||||
return redEggs;
|
||||
case ItemID.GREEN_EGG:
|
||||
return greenEggs;
|
||||
case ItemID.BLUE_EGG:
|
||||
return blueEggs;
|
||||
case ItemID.YELLOW_EGG:
|
||||
return yellowEggs;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void announceTime(String preText, String time, String type, String amt, String totalMsg, String total) {
|
||||
|
||||
|
||||
final String chatMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(preText)
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(time)
|
||||
.build();
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(preText)
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(time)
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(type)
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(amt)
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(totalMsg)
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(total)
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(chatMessage)
|
||||
.build());
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(chatMessage)
|
||||
.build());
|
||||
}
|
||||
|
||||
private boolean isEgg(int itemID)
|
||||
{
|
||||
if (itemID == ItemID.RED_EGG || itemID == ItemID.GREEN_EGG
|
||||
|| itemID == ItemID.BLUE_EGG || itemID == ItemID.YELLOW_EGG)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isUnderPlayer(Tile tile) {
|
||||
Player local = client.getLocalPlayer();
|
||||
if (local == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (tile.getWorldLocation().equals(local.getWorldLocation()));
|
||||
}
|
||||
|
||||
public Font getFont()
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
|
||||
* 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.batools;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("BATools")
|
||||
public interface BAToolsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "defTimer",
|
||||
name = "Defender Tick Timer",
|
||||
description = "Shows the current cycle tick of runners."
|
||||
)
|
||||
default boolean defTimer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "calls",
|
||||
name = "Remove Incorrect Calls",
|
||||
description = "Remove incorrect calls."
|
||||
)
|
||||
default boolean calls()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapLadder",
|
||||
name = "Swap ladder option",
|
||||
description = "Swap Climb-down with Quick-start in the wave lobbies"
|
||||
)
|
||||
default boolean swapLadder()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerCodes",
|
||||
name = "Healer Codes",
|
||||
description = "Overlay to show healer codes"
|
||||
)
|
||||
default boolean healerCodes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerMenuOption",
|
||||
name = "Healer menu options",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean healerMenuOption()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "antiDrag",
|
||||
name = "Anti Drag",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean antiDrag()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "antiDragDelay",
|
||||
name = "Anti Drag Delay",
|
||||
description = "asd"
|
||||
)
|
||||
default int antiDragDelay()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "eggBoi",
|
||||
name = "Collector helper",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean eggBoi()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "osHelp",
|
||||
name = "Shift OS",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean osHelp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* 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.batools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
|
||||
public class BAToolsOverlay extends Overlay
|
||||
{
|
||||
private static final Color RED = new Color(221, 44, 0);
|
||||
private static final Color GREEN = new Color(0, 200, 83);
|
||||
private static final Color ORANGE = new Color(255, 109, 0);
|
||||
private static final Color YELLOW = new Color(255, 214, 0);
|
||||
private static final Color CYAN = new Color(0, 184, 212);
|
||||
private static final Color BLUE = new Color(41, 98, 255);
|
||||
private static final Color DEEP_PURPLE = new Color(98, 0, 234);
|
||||
private static final Color PURPLE = new Color(170, 0, 255);
|
||||
private static final Color GRAY = new Color(158, 158, 158);
|
||||
|
||||
private final BAToolsConfig config;
|
||||
private Client client;
|
||||
private BAToolsPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public BAToolsOverlay(Client client, BAToolsPlugin plugin, BAToolsConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if(!config.healerCodes())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Healer healer : plugin.getHealers().values())
|
||||
{
|
||||
NPCComposition composition = healer.getNpc().getComposition();
|
||||
Color color = composition.getCombatLevel() > 1 ? YELLOW : ORANGE;
|
||||
if (composition.getConfigs() != null)
|
||||
{
|
||||
NPCComposition transformedComposition = composition.transform();
|
||||
if (transformedComposition == null)
|
||||
{
|
||||
color = GRAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
composition = transformedComposition;
|
||||
}
|
||||
}
|
||||
int timeLeft = healer.getLastFoodTime() - (int)Duration.between(plugin.getWave_start(), Instant.now()).getSeconds();
|
||||
timeLeft = timeLeft < 1 ? 0 : timeLeft;
|
||||
|
||||
if(healer.getFoodRemaining() > 1)
|
||||
{
|
||||
color = GREEN;
|
||||
}
|
||||
else if(healer.getFoodRemaining() == 1)
|
||||
{
|
||||
if(timeLeft > 0)
|
||||
{
|
||||
color = RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = GREEN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String text = String.format("%d %d",
|
||||
healer.getFoodRemaining(),
|
||||
timeLeft);
|
||||
|
||||
|
||||
|
||||
OverlayUtil.renderActorOverlay(graphics, healer.getNpc(), text, color);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
|
||||
* 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.batools;
|
||||
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.CHUNK_SIZE;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.HitsplatApplied;
|
||||
import net.runelite.api.events.InteractingChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Slf4j
|
||||
@PluginDescriptor(
|
||||
name = "BA Tools",
|
||||
description = "Custom tools for Barbarian Assault",
|
||||
tags = {"minigame", "overlay", "timer"}
|
||||
)
|
||||
public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
int inGameBit = 0;
|
||||
int tickNum;
|
||||
int pastCall = 0;
|
||||
private int currentWave = 1;
|
||||
private static final int BA_WAVE_NUM_INDEX = 2;
|
||||
private final List<MenuEntry> entries = new ArrayList<>();
|
||||
private HashMap<Integer, Instant> foodPressed = new HashMap<>();
|
||||
private CycleCounter counter;
|
||||
private Actor lastInteracted;
|
||||
|
||||
private boolean shiftDown;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private BAToolsConfig config;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private BAToolsOverlay overlay;
|
||||
|
||||
@Getter
|
||||
private Map<NPC, Healer> healers;
|
||||
|
||||
@Getter
|
||||
private Instant wave_start;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
|
||||
@Provides
|
||||
BAToolsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BAToolsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
healers = new HashMap<>();
|
||||
wave_start = Instant.now();
|
||||
lastInteracted = null;
|
||||
foodPressed.clear();
|
||||
client.setInventoryDragDelay(config.antiDragDelay());
|
||||
keyManager.registerKeyListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
removeCounter();
|
||||
healers.clear();
|
||||
inGameBit = 0;
|
||||
lastInteracted = null;
|
||||
overlayManager.remove(overlay);
|
||||
client.setInventoryDragDelay(5);
|
||||
keyManager.unregisterKeyListener(this);
|
||||
shiftDown = false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
switch (event.getGroupId())
|
||||
{
|
||||
case WidgetID.BA_REWARD_GROUP_ID:
|
||||
{
|
||||
Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT);
|
||||
|
||||
if (rewardWidget != null && rewardWidget.getText().contains("<br>5"))
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (config.antiDrag())
|
||||
{
|
||||
client.setInventoryDragDelay(config.antiDragDelay());
|
||||
}
|
||||
|
||||
Widget callWidget = getWidget();
|
||||
|
||||
if (callWidget != null)
|
||||
{
|
||||
if (callWidget.getTextColor() != pastCall && callWidget.getTextColor() == 16316664)
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
pastCall = callWidget.getTextColor();
|
||||
}
|
||||
if (inGameBit == 1)
|
||||
{
|
||||
if (tickNum > 9)
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
if (counter == null)
|
||||
{
|
||||
addCounter();
|
||||
}
|
||||
//counter.setText(String.valueOf(tickNum));
|
||||
counter.setCount(tickNum);
|
||||
if (config.defTimer())
|
||||
{
|
||||
log.info("" + tickNum++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Widget getWidget()
|
||||
{
|
||||
if (client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
int inGame = client.getVar(Varbits.IN_GAME_BA);
|
||||
|
||||
if (inGameBit != inGame)
|
||||
{
|
||||
if (inGameBit == 1)
|
||||
{
|
||||
pastCall = 0;
|
||||
removeCounter();
|
||||
foodPressed.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
addCounter();
|
||||
}
|
||||
}
|
||||
|
||||
inGameBit = inGame;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (event.getType() == ChatMessageType.CONSOLE
|
||||
&& event.getMessage().startsWith("---- Wave:"))
|
||||
{
|
||||
String[] message = event.getMessage().split(" ");
|
||||
currentWave = Integer.parseInt(message[BA_WAVE_NUM_INDEX]);
|
||||
wave_start = Instant.now();
|
||||
healers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
NPC npc = event.getNpc();
|
||||
|
||||
if (isNpcHealer(npc.getId()))
|
||||
{
|
||||
if (checkNewSpawn(npc) || Duration.between(wave_start, Instant.now()).getSeconds() < 16)
|
||||
{
|
||||
int spawnNumber = healers.size();
|
||||
healers.put(npc, new Healer(npc, spawnNumber, currentWave));
|
||||
log.info("spawn number: " + spawnNumber + " on wave " + currentWave);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onHitsplatApplied(HitsplatApplied hitsplatApplied)
|
||||
{
|
||||
Actor actor = hitsplatApplied.getActor();
|
||||
|
||||
if (healers.isEmpty() && !(actor instanceof NPC) && lastInteracted == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Healer healer : healers.values())
|
||||
{
|
||||
if (healer.getNpc() == actor && actor == lastInteracted)
|
||||
{
|
||||
healer.setFoodRemaining(healer.getFoodRemaining() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (healers.remove(event.getNpc()) != null && healers.isEmpty())
|
||||
{
|
||||
healers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInteractingChanged(InteractingChanged event)
|
||||
{
|
||||
Actor opponent = event.getTarget();
|
||||
|
||||
if (opponent != null && opponent instanceof NPC && isNpcHealer(((NPC) opponent).getId()) && event.getSource() != client.getLocalPlayer())
|
||||
{
|
||||
lastInteracted = opponent;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNpcHealer(int npcId)
|
||||
{
|
||||
return npcId == NpcID.PENANCE_HEALER ||
|
||||
npcId == NpcID.PENANCE_HEALER_5766 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5767 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5768 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5769 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5770 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5771 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5772 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5773 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5774;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (config.calls() && getWidget() != null && event.getTarget().endsWith("horn") && !event.getTarget().contains("Unicorn"))
|
||||
{
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
Widget callWidget = getWidget();
|
||||
String call = Calls.getOption(callWidget.getText());
|
||||
MenuEntry correctCall = null;
|
||||
|
||||
entries.clear();
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
String option = entry.getOption();
|
||||
if (option.equals(call))
|
||||
{
|
||||
correctCall = entry;
|
||||
}
|
||||
else if (!option.startsWith("Tell-"))
|
||||
{
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (correctCall != null) //&& callWidget.getTextColor()==16316664)
|
||||
{
|
||||
entries.add(correctCall);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
}
|
||||
else if (config.calls() && event.getTarget().endsWith("horn"))
|
||||
{
|
||||
entries.clear();
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
|
||||
String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder"))
|
||||
{
|
||||
swap("quick-start", option, target, true);
|
||||
}
|
||||
|
||||
if (inGameBit == 1 && config.healerMenuOption() && event.getTarget().contains("Penance Healer"))
|
||||
{
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
|
||||
String targett = lastEntry.getTarget();
|
||||
|
||||
if (foodPressed.containsKey(lastEntry.getIdentifier()))
|
||||
{
|
||||
lastEntry.setTarget(lastEntry.getTarget().split("\\(")[0] + "(" + Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() + ")");
|
||||
if (Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() > 20)
|
||||
{
|
||||
lastEntry.setTarget(lastEntry.getTarget().replace("<col=ffff00>", "<col=2bff63>"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastEntry.setTarget(targett.replace("<col=ffff00>", "<col=2bff63>"));
|
||||
|
||||
}
|
||||
|
||||
client.setMenuEntries(menuEntries);
|
||||
}
|
||||
|
||||
if (client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT) != null && inGameBit == 1 && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown)
|
||||
{
|
||||
String[] currentCall = client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT).getText().split(" ");
|
||||
log.info("1 " + currentCall[0]);
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry correctEgg = null;
|
||||
entries.clear();
|
||||
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
if (entry.getTarget().contains(currentCall[0]) && entry.getOption().equals("Take"))
|
||||
{
|
||||
correctEgg = entry;
|
||||
}
|
||||
}
|
||||
if (correctEgg != null)
|
||||
{
|
||||
entries.add(correctEgg);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
if (client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT) != null && inGameBit == 1 && config.osHelp() && event.getTarget().equals("<col=ffff>Healer item machine") && shiftDown)
|
||||
{
|
||||
String[] currentCall = client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT).getText().split(" ");
|
||||
|
||||
if (!currentCall[0].contains("Pois."))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry correctEgg = null;
|
||||
entries.clear();
|
||||
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
if (entry.getOption().equals("Take-" + currentCall[1]))
|
||||
{
|
||||
correctEgg = entry;
|
||||
}
|
||||
}
|
||||
if (correctEgg != null)
|
||||
{
|
||||
entries.add(correctEgg);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (!config.healerMenuOption() || !event.getMenuTarget().contains("Penance Healer") || client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String currentCall = client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT).getText();
|
||||
String target = event.getMenuTarget();
|
||||
|
||||
if ((currentCall.equals("Pois. Worms") && (target.contains("Poisoned worms") && target.contains("->") && target.contains("Penance Healer")))
|
||||
|| (currentCall.equals("Pois. Meat") && (target.contains("Poisoned meat") && target.contains("->") && target.contains("Penance Healer")))
|
||||
|| (currentCall.equals("Pois. Tofu") && (target.contains("Poisoned tofu") && target.contains("->") && target.contains("Penance Healer"))))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
}
|
||||
|
||||
if (target.contains("->") && target.contains("Penance Healer"))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (config.antiDrag())
|
||||
{
|
||||
client.setInventoryDragDelay(config.antiDragDelay());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addCounter()
|
||||
{
|
||||
if (!config.defTimer() || counter != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int itemSpriteId = ItemID.FIGHTER_TORSO;
|
||||
|
||||
BufferedImage taskImg = itemManager.getImage(itemSpriteId);
|
||||
counter = new CycleCounter(taskImg, this, tickNum);
|
||||
|
||||
infoBoxManager.addInfoBox(counter);
|
||||
}
|
||||
|
||||
private void removeCounter()
|
||||
{
|
||||
if (counter == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
infoBoxManager.removeInfoBox(counter);
|
||||
counter = null;
|
||||
}
|
||||
|
||||
private void swap(String optionA, String optionB, String target, boolean strict)
|
||||
{
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
|
||||
int idxA = searchIndex(entries, optionA, target, strict);
|
||||
int idxB = searchIndex(entries, optionB, target, strict);
|
||||
|
||||
if (idxA >= 0 && idxB >= 0)
|
||||
{
|
||||
MenuEntry entry = entries[idxA];
|
||||
entries[idxA] = entries[idxB];
|
||||
entries[idxB] = entry;
|
||||
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
|
||||
private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict)
|
||||
{
|
||||
for (int i = entries.length - 1; i >= 0; i--)
|
||||
{
|
||||
MenuEntry entry = entries[i];
|
||||
String entryOption = Text.removeTags(entry.getOption()).toLowerCase();
|
||||
String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase();
|
||||
|
||||
if (strict)
|
||||
{
|
||||
if (entryOption.equals(option) && entryTarget.equals(target))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static WorldPoint rotate(WorldPoint point, int rotation)
|
||||
{
|
||||
int chunkX = point.getX() & ~(CHUNK_SIZE - 1);
|
||||
int chunkY = point.getY() & ~(CHUNK_SIZE - 1);
|
||||
int x = point.getX() & (CHUNK_SIZE - 1);
|
||||
int y = point.getY() & (CHUNK_SIZE - 1);
|
||||
switch (rotation)
|
||||
{
|
||||
case 1:
|
||||
return new WorldPoint(chunkX + y, chunkY + (CHUNK_SIZE - 1 - x), point.getPlane());
|
||||
case 2:
|
||||
return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - x), chunkY + (CHUNK_SIZE - 1 - y), point.getPlane());
|
||||
case 3:
|
||||
return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - y), chunkY + x, point.getPlane());
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
private boolean checkNewSpawn(NPC npc)
|
||||
{
|
||||
int regionId = 7509;
|
||||
int regionX = 42;
|
||||
int regionY = 46;
|
||||
int z = 0;
|
||||
|
||||
// world point of the tile marker
|
||||
WorldPoint worldPoint = new WorldPoint(
|
||||
((regionId >>> 8) << 6) + regionX,
|
||||
((regionId & 0xff) << 6) + regionY,
|
||||
z
|
||||
);
|
||||
|
||||
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
||||
for (int x = 0; x < instanceTemplateChunks[z].length; ++x)
|
||||
{
|
||||
for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y)
|
||||
{
|
||||
int chunkData = instanceTemplateChunks[z][x][y];
|
||||
int rotation = chunkData >> 1 & 0x3;
|
||||
int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE;
|
||||
int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE;
|
||||
if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE
|
||||
&& worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE)
|
||||
{
|
||||
WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)),
|
||||
client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)),
|
||||
worldPoint.getPlane());
|
||||
p = rotate(p, rotation);
|
||||
if (p.distanceTo(npc.getWorldLocation()) < 5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* 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.batools;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum Calls
|
||||
{
|
||||
//Attacker Calls
|
||||
RED_EGG("Red egg", "Tell-red"),
|
||||
GREEN_EGG("Green egg", "Tell-green"),
|
||||
BLUE_EGG("Blue egg", "Tell-blue"),
|
||||
//Collector Calls
|
||||
CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"),
|
||||
ACCURATE("Accurate/Field/Water", "Tell-accurate"),
|
||||
AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"),
|
||||
DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"),
|
||||
//Healer Calls
|
||||
TOFU("Tofu", "Tell-tofu"),
|
||||
CRACKERS("Crackers", "Tell-crackers"),
|
||||
WORMS("Worms", "Tell-worms"),
|
||||
//Defender Calls
|
||||
POIS_WORMS("Pois. Worms", "Tell-worms"),
|
||||
POIS_TOFU("Pois. Tofu", "Tell-tofu"),
|
||||
POIS_MEAT("Pois. Meat", "Tell-meat");
|
||||
|
||||
private final String call;
|
||||
private final String option;
|
||||
|
||||
private static final Map<String, String> CALL_MENU = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
for (Calls s : values())
|
||||
{
|
||||
CALL_MENU.put(s.getCall(), s.getOption());
|
||||
}
|
||||
}
|
||||
|
||||
Calls(String call, String option)
|
||||
{
|
||||
this.call = call;
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public String getCall()
|
||||
{
|
||||
return call;
|
||||
}
|
||||
|
||||
public String getOption()
|
||||
{
|
||||
return option;
|
||||
}
|
||||
|
||||
public static String getOption(String call)
|
||||
{
|
||||
return CALL_MENU.get(call);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class CycleCounter extends Counter
|
||||
{
|
||||
public CycleCounter(BufferedImage img, Plugin plugin, int tick)
|
||||
{
|
||||
super(img, plugin, tick);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Actor;
|
||||
|
||||
|
||||
public class Healer
|
||||
{
|
||||
|
||||
@Getter
|
||||
private NPC npc;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int wave;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int spawnNumber;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int foodRemaining;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int lastFoodTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int firstCallFood;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int secondCallFood;
|
||||
|
||||
|
||||
|
||||
public Healer(NPC npc, int spawnNumber, int wave)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.wave = wave;
|
||||
this.spawnNumber = spawnNumber;
|
||||
this.firstCallFood = getCode(wave).getFirstCallFood()[spawnNumber];
|
||||
this.secondCallFood = getCode(wave).getSecondCallFood()[spawnNumber];
|
||||
this.foodRemaining = firstCallFood + secondCallFood;
|
||||
this.lastFoodTime = getCode(wave).getSpacing()[spawnNumber];
|
||||
}
|
||||
|
||||
private HealerCode getCode(int wave)
|
||||
{
|
||||
switch(wave)
|
||||
{
|
||||
case 1:
|
||||
return HealerCode.WAVEONE;
|
||||
case 2:
|
||||
return HealerCode.WAVETWO;
|
||||
case 3:
|
||||
return HealerCode.WAVETHREE;
|
||||
case 4:
|
||||
return HealerCode.WAVEFOUR;
|
||||
case 5:
|
||||
return HealerCode.WAVEFIVE;
|
||||
case 6:
|
||||
return HealerCode.WAVESIX;
|
||||
case 7:
|
||||
return HealerCode.WAVESEVEN;
|
||||
case 8:
|
||||
return HealerCode.WAVEEIGHT;
|
||||
case 9:
|
||||
return HealerCode.WAVENINE;
|
||||
case 10:
|
||||
return HealerCode.WAVETEN;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
enum HealerCode
|
||||
{
|
||||
|
||||
WAVEONE(new int[] {1,1}, new int[] {0,0}, new int[] {0,0}),
|
||||
WAVETWO(new int[] {1,1,2}, new int[] {0,0,0}, new int[] {0,0,21}),
|
||||
WAVETHREE(new int[] {1,6,2}, new int[] {0,0,0}, new int[] {0,0,0}),
|
||||
WAVEFOUR(new int[] {2,5,2,0}, new int[] {0,0,7,10}, new int[] {0,0,0,0}),
|
||||
WAVEFIVE(new int[] {2,5,2,3,0}, new int[] {0,0,0,0,7}, new int[] {0,0,21,30,0}),
|
||||
WAVESIX(new int[] {3,5,3,1,0,0}, new int[] {0,0,0,2,9,10}, new int[] {18,0,0,0,0,0}),
|
||||
WAVESEVEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,0,0,0,6,8,10}, new int[] {27,33,0,0,51,0,0}),
|
||||
WAVEEIGHT(new int[] {2,8,1,1,0,0,0}, new int[] {1,0,1,1,3,1,10}, new int[] {36,0,33,39,45,48,0}),
|
||||
WAVENINE(new int[] {2,8,1,1,0,0,0,0}, new int[] {1,1,1,1,1,1,1,10}, new int[] {0,21,0,0,0,0,0,0,0}),
|
||||
WAVETEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,1,1,1,3,3,10}, new int[] {27,33,0,0,51,0,0});
|
||||
|
||||
|
||||
@Getter
|
||||
private final int[] firstCallFood;
|
||||
@Getter
|
||||
private final int[] secondCallFood;
|
||||
@Getter
|
||||
private final int[] spacing;
|
||||
|
||||
HealerCode(int[] firstCallFood, int[] secondCallFood, int[] spacing)
|
||||
{
|
||||
this.firstCallFood = firstCallFood;
|
||||
this.secondCallFood = secondCallFood;
|
||||
this.spacing = spacing;
|
||||
}
|
||||
}
|
||||
@@ -83,4 +83,24 @@ public interface CannonConfig extends Config
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "ammoAmount",
|
||||
name = "Ammo left",
|
||||
description = "Configure to set the amount of ammo left to receive ammo left notification"
|
||||
)
|
||||
default int ammoAmount()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notifyAmmoLeft",
|
||||
name = "Ammo left notification",
|
||||
description = "Sends a notification when cannon ammo is under the specified amount"
|
||||
)
|
||||
default boolean notifyAmmoLeft()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,7 @@ import net.runelite.api.Projectile;
|
||||
import static net.runelite.api.ProjectileID.CANNONBALL;
|
||||
import static net.runelite.api.ProjectileID.GRANITE_CANNONBALL;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
@@ -275,6 +270,7 @@ public class CannonPlugin extends Plugin
|
||||
if (!skipProjectileCheckThisTick)
|
||||
{
|
||||
cballsLeft--;
|
||||
client.getCallbacks().post(new CannonballFired());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,6 +375,13 @@ public class CannonPlugin extends Plugin
|
||||
{
|
||||
return Color.orange;
|
||||
}
|
||||
else if (cballsLeft <= config.ammoAmount())
|
||||
{
|
||||
if (config.notifyAmmoLeft())
|
||||
{
|
||||
notifier.notify("Your cannon has " + config.ammoAmount() + " balls left!");
|
||||
}
|
||||
}
|
||||
|
||||
return Color.red;
|
||||
}
|
||||
|
||||
@@ -126,4 +126,37 @@ public interface ClanChatConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "discord",
|
||||
name = "Discord",
|
||||
description = "Send clan chats to a discord webhook <br> See https://support.discordapp.com/hc/en-us/articles/228383668",
|
||||
position = 8
|
||||
)
|
||||
default boolean discord()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "discordPath",
|
||||
name = "Webhook path",
|
||||
description = "Your webhook id and webhook token <br> (the part after \"/webhooks/\")",
|
||||
position = 9
|
||||
)
|
||||
default String discordPath()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "discordAccount",
|
||||
name = "Discord/RS account",
|
||||
description = "The login username (not rsn!) of the runescape account you want to use this on",
|
||||
position = 10
|
||||
)
|
||||
default String discordAccount()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatLineBuffer;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.ClanMember;
|
||||
@@ -72,18 +73,22 @@ import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.clanchat.discord.DiscordClient;
|
||||
import net.runelite.client.plugins.clanchat.discord.DiscordMessage;
|
||||
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
|
||||
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND;
|
||||
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_OPAQUE_BACKGROUND;
|
||||
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import static net.runelite.client.util.Text.removeTags;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Clan Chat",
|
||||
description = "Add rank icons to users talking in clan chat",
|
||||
tags = {"icons", "rank", "recent"}
|
||||
)
|
||||
@Slf4j
|
||||
public class ClanChatPlugin extends Plugin
|
||||
{
|
||||
private static final int MAX_CHATS = 10;
|
||||
@@ -113,6 +118,9 @@ public class ClanChatPlugin extends Plugin
|
||||
private List<String> chats = new ArrayList<>();
|
||||
private List<Player> clanMembers = new ArrayList<>();
|
||||
private ClanChatIndicator clanMemberCounter;
|
||||
|
||||
private DiscordClient discordClient;
|
||||
|
||||
/**
|
||||
* queue of temporary messages added to the client
|
||||
*/
|
||||
@@ -138,6 +146,7 @@ public class ClanChatPlugin extends Plugin
|
||||
clanMembers.clear();
|
||||
removeClanCounter();
|
||||
resetClanChats();
|
||||
stopDiscordClient();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -158,6 +167,15 @@ public class ClanChatPlugin extends Plugin
|
||||
{
|
||||
removeClanCounter();
|
||||
}
|
||||
|
||||
if (config.discord())
|
||||
{
|
||||
startDiscordClient();
|
||||
}
|
||||
else
|
||||
{
|
||||
stopDiscordClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,6 +303,38 @@ public class ClanChatPlugin extends Plugin
|
||||
addClanActivityMessages();
|
||||
}
|
||||
|
||||
private void submitMessage(String message, String user, String url)
|
||||
{
|
||||
if (discordClient == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DiscordMessage discordMessage = new DiscordMessage();
|
||||
|
||||
message = removeTags(message);
|
||||
if (!user.contains("<img=2>") && !user.contains("<img=10>"))
|
||||
{
|
||||
discordMessage.setContent(message);
|
||||
}
|
||||
else if (user.contains("img=10"))
|
||||
{
|
||||
discordMessage.setContent("<:hcim:557056153834487819> " + message);
|
||||
}
|
||||
else
|
||||
{
|
||||
discordMessage.setContent("<:iron:557056153729630209> " + message);
|
||||
}
|
||||
discordMessage.setUsername(removeTags(user));
|
||||
discordMessage.setAvatar_url(url);
|
||||
|
||||
discordClient.submit(discordMessage, config.discordPath());
|
||||
}
|
||||
private void submitMessage(String message)
|
||||
{
|
||||
submitMessage(message, "", "");
|
||||
}
|
||||
|
||||
private void timeoutClanMessages()
|
||||
{
|
||||
if (clanJoinMessages.isEmpty())
|
||||
@@ -346,7 +396,7 @@ public class ClanChatPlugin extends Plugin
|
||||
|
||||
private void addActivityMessage(ClanMember member, ClanActivityType activityType)
|
||||
{
|
||||
final String activityMessage = activityType == ClanActivityType.JOINED ? " has joined." : " has left.";
|
||||
final String activityMessage = activityType == ClanActivityType.JOINED ? " has joined. " : " has left. ";
|
||||
final ClanMemberRank rank = member.getRank();
|
||||
Color textColor = CHAT_CLAN_TEXT_OPAQUE_BACKGROUND;
|
||||
Color channelColor = CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
|
||||
@@ -358,7 +408,7 @@ public class ClanChatPlugin extends Plugin
|
||||
channelColor = CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND;
|
||||
}
|
||||
|
||||
if (config.clanChatIcons() && rank != null && rank != ClanMemberRank.UNRANKED)
|
||||
if (config.clanChatIcons() && rank != ClanMemberRank.UNRANKED)
|
||||
{
|
||||
rankIcon = clanManager.getIconNumber(rank);
|
||||
}
|
||||
@@ -378,6 +428,10 @@ public class ClanChatPlugin extends Plugin
|
||||
|
||||
final String messageString = message.build();
|
||||
client.addChatMessage(ChatMessageType.FRIENDSCHATNOTIFICATION, "", messageString, "");
|
||||
if (discordClient != null)
|
||||
{
|
||||
submitMessage(member.getUsername() + activityMessage + client.getClanChatCount() + " people online.");
|
||||
}
|
||||
|
||||
final ChatLineBuffer chatLineBuffer = client.getChatLineMap().get(ChatMessageType.FRIENDSCHATNOTIFICATION.getType());
|
||||
final MessageNode[] lines = chatLineBuffer.getLines();
|
||||
@@ -399,12 +453,7 @@ public class ClanChatPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.getClanChatCount() <= 0)
|
||||
if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN || client.getClanChatCount() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -426,6 +475,12 @@ public class ClanChatPlugin extends Plugin
|
||||
}
|
||||
break;
|
||||
case FRIENDSCHAT:
|
||||
if (discordClient != null)
|
||||
{
|
||||
String url = clanManager.getRank(chatMessage.getName()).getDiscavatar();
|
||||
submitMessage(chatMessage.getMessage(), chatMessage.getName(), url);
|
||||
}
|
||||
|
||||
if (!config.clanChatIcons())
|
||||
{
|
||||
return;
|
||||
@@ -447,8 +502,12 @@ public class ClanChatPlugin extends Plugin
|
||||
{
|
||||
clanMembers.clear();
|
||||
removeClanCounter();
|
||||
|
||||
clanJoinMessages.clear();
|
||||
|
||||
if (gameState == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
stopDiscordClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,6 +536,11 @@ public class ClanChatPlugin extends Plugin
|
||||
if (event.isJoined())
|
||||
{
|
||||
clanJoinedTick = client.getTickCount();
|
||||
|
||||
if (config.discord())
|
||||
{
|
||||
startDiscordClient();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -595,4 +659,22 @@ public class ClanChatPlugin extends Plugin
|
||||
clanMemberCounter = new ClanChatIndicator(image, this);
|
||||
infoBoxManager.addInfoBox(clanMemberCounter);
|
||||
}
|
||||
|
||||
private void startDiscordClient()
|
||||
{
|
||||
if (discordClient == null && config.discordAccount().equals(client.getUsername()))
|
||||
{
|
||||
discordClient = new DiscordClient();
|
||||
submitMessage("Started\n\n" + client.getLocalPlayer().getName() + " has joined.");
|
||||
}
|
||||
}
|
||||
|
||||
private void stopDiscordClient()
|
||||
{
|
||||
if (discordClient != null)
|
||||
{
|
||||
submitMessage(client.getLocalPlayer().getName() + " has left.\n\nStopped");
|
||||
discordClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package net.runelite.client.plugins.clanchat.discord;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.io.IOException;
|
||||
import static java.lang.Integer.parseInt;
|
||||
import java.time.Instant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class DiscordClient
|
||||
{
|
||||
private static final MediaType JSON = MediaType.parse("application/json");
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
private int rateLimit = 1;
|
||||
private Instant rateReset = Instant.EPOCH;
|
||||
|
||||
public void submit(DiscordMessage message, String path)
|
||||
{
|
||||
if (rateLimit < 1 && Instant.now().isBefore(rateReset))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final HttpUrl url = new HttpUrl.Builder()
|
||||
.scheme("https")
|
||||
.host("discordapp.com")
|
||||
.addPathSegments("api/webhooks")
|
||||
.addPathSegments(path)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(JSON, GSON.toJson(message)))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.debug("discord message failed", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
rateLimit = parseInt(response.header("X-RateLimit-Remaining"));
|
||||
rateReset = Instant.ofEpochSecond((parseInt(response.header("X-RateLimit-Reset"))));
|
||||
log.debug("Submitted discord message, limit: {}, reset: {}", rateLimit, rateReset);
|
||||
response.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package net.runelite.client.plugins.clanchat.discord;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DiscordMessage
|
||||
{
|
||||
private String username;
|
||||
private String content;
|
||||
private String avatar_url;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("clanmanmode")
|
||||
public interface ClanManModeConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "highlightattackable",
|
||||
name = "Highlight attackable targets",
|
||||
description = "Highlights targets attackable by all clan members"
|
||||
)
|
||||
default boolean highlightAttackable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "attackablecolor",
|
||||
name = "Attackable target c olor",
|
||||
description = "Color of targets all clan members can target"
|
||||
)
|
||||
default Color getAttackableColor()
|
||||
{
|
||||
return new Color(0, 184, 212);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "highlightattacked",
|
||||
name = "Highlight clan targets",
|
||||
description = "Highlights people being attacked by your clan"
|
||||
)
|
||||
default boolean highlightAttacked()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "attackedcolor",
|
||||
name = "Clan target color",
|
||||
description = "Color of players being attacked by clan"
|
||||
)
|
||||
default Color getClanAttackableColor()
|
||||
{
|
||||
return new Color(0, 184, 212);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "drawPlayerTiles",
|
||||
name = "Draw tiles under players",
|
||||
description = "Configures whether or not tiles under highlighted players should be drawn"
|
||||
)
|
||||
default boolean drawTiles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "drawOverheadPlayerNames",
|
||||
name = "Draw names above players",
|
||||
description = "Configures whether or not player names should be drawn above players"
|
||||
)
|
||||
default boolean drawOverheadPlayerNames()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "drawMinimapNames",
|
||||
name = "Draw names on minimap",
|
||||
description = "Configures whether or not minimap names for players with rendered names should be drawn"
|
||||
)
|
||||
default boolean drawMinimapNames()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "showtargets",
|
||||
name = "Highlight My Attackers",
|
||||
description = "Shows players interacting with you"
|
||||
)
|
||||
default boolean showAttackers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "attackcolor",
|
||||
name = "Attacker Color",
|
||||
description = "Color of attackers"
|
||||
)
|
||||
default Color getAttackerColor()
|
||||
{
|
||||
return new Color(255, 0, 0);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "showbold",
|
||||
name = "Bold names of clan targets",
|
||||
description = "Turns names of clan targets bold"
|
||||
)
|
||||
default boolean ShowBold() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "hideafter",
|
||||
name = "Hide attackable targets after login",
|
||||
description = "Automatically disables attackable player highlighting after login"
|
||||
)
|
||||
default boolean hideAttackable() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "hidetime",
|
||||
name = "Ticks to hide",
|
||||
description = "How many ticks after you are logged in that attackbles are hidden (1 tick = 0.6 seconds)"
|
||||
)
|
||||
default int hideTime() { return 5; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "mycblvl",
|
||||
name = "Calc targets on my own combat level",
|
||||
description = "Calculates potential targets based off your own combat lvl instead of clans"
|
||||
)
|
||||
default boolean CalcSelfCB() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "hideatkopt",
|
||||
name = "Hide attack option for clan members",
|
||||
description = "Disables attack option for clan members"
|
||||
)
|
||||
default boolean hideAtkOpt() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "showclanmembers",
|
||||
name = "Persistent Clan Members",
|
||||
description = "Will highlight clan members even when not in clan chat"
|
||||
)
|
||||
default boolean PersistentClan() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 15,
|
||||
keyName = "clancolor",
|
||||
name = "Clan Member Color",
|
||||
description = "Color of clan members"
|
||||
)
|
||||
default Color getClanMemberColor()
|
||||
{
|
||||
return new Color(255, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class ClanManModeMinimapOverlay extends Overlay
|
||||
{
|
||||
private final ClanManModeService ClanManModeService;
|
||||
private final ClanManModeConfig config;
|
||||
|
||||
@Inject
|
||||
private ClanManModeMinimapOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService)
|
||||
{
|
||||
this.config = config;
|
||||
this.ClanManModeService = ClanManModeService;
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
final String name = actor.getName().replace('\u00A0', ' ');
|
||||
|
||||
if (config.drawMinimapNames())
|
||||
{
|
||||
final net.runelite.api.Point minimapLocation = actor.getMinimapLocation();
|
||||
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.ClanMemberRank;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class ClanManModeOverlay extends Overlay
|
||||
{
|
||||
private final ClanManModeService ClanManModeService;
|
||||
private final ClanManModeConfig config;
|
||||
private final ClanManager clanManager;
|
||||
|
||||
@Inject
|
||||
private ClanManModeOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService,
|
||||
ClanManager clanManager)
|
||||
{
|
||||
this.config = config;
|
||||
this.ClanManModeService = ClanManModeService;
|
||||
this.clanManager = clanManager;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
if (!config.drawOverheadPlayerNames())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String name = actor.getName().replace('\u00A0', ' ');
|
||||
int offset = actor.getLogicalHeight() + 40;
|
||||
Point textLocation = actor.getCanvasTextLocation(graphics, name, offset);
|
||||
|
||||
if (textLocation != null)
|
||||
{
|
||||
if (config.getClanAttackableColor().equals(color) && config.ShowBold()) {
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"aqua\">!Clan Man Mode</font>",
|
||||
description = "Assists in clan PVP scenarios",
|
||||
tags = {"highlight", "minimap", "overlay", "players"}
|
||||
)
|
||||
public class ClanManModePlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private ClanManModeConfig config;
|
||||
|
||||
@Inject
|
||||
private ClanManModeOverlay ClanManModeOverlay;
|
||||
|
||||
@Inject
|
||||
private ClanManModeTileOverlay ClanManModeTileOverlay;
|
||||
|
||||
@Inject
|
||||
private ClanManModeMinimapOverlay ClanManModeMinimapOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClanManager clanManager;
|
||||
|
||||
@Provides
|
||||
ClanManModeConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(ClanManModeConfig.class);
|
||||
}
|
||||
|
||||
int wildernessLevel;
|
||||
int clanmin;
|
||||
int clanmax;
|
||||
int inwildy;
|
||||
int ticks;
|
||||
Map<String, Integer> clan = new HashMap<>();
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
overlayManager.add(ClanManModeOverlay);
|
||||
overlayManager.add(ClanManModeTileOverlay);
|
||||
overlayManager.add(ClanManModeMinimapOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
overlayManager.remove(ClanManModeOverlay);
|
||||
overlayManager.remove(ClanManModeTileOverlay);
|
||||
overlayManager.remove(ClanManModeMinimapOverlay);
|
||||
clan.clear();
|
||||
ticks = 0;
|
||||
wildernessLevel = 0;
|
||||
clanmin = 0;
|
||||
clanmax = 0;
|
||||
inwildy = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged) {
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING) {
|
||||
ticks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event) {
|
||||
ticks++;
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
if (!clan.containsKey(localPlayer.getName())) {
|
||||
clan.put(localPlayer.getName(), localPlayer.getCombatLevel());
|
||||
}
|
||||
WorldPoint a = localPlayer.getWorldLocation();
|
||||
int underLevel = ((a.getY() - 9920) / 8) + 1;
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
inwildy = client.getVar(Varbits.IN_WILDERNESS);
|
||||
if (clan.size() > 0) {
|
||||
clanmin = Collections.min(clan.values());
|
||||
clanmax = Collections.max(clan.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
if (!config.hideAtkOpt()) {
|
||||
return;
|
||||
}
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
|
||||
if (option.equals("attack")) {
|
||||
final Pattern ppattern = Pattern.compile("<col=ffffff>(.+?)<col=");
|
||||
final Matcher pmatch = ppattern.matcher(event.getTarget());
|
||||
pmatch.find();
|
||||
if (pmatch.matches()) {
|
||||
if (pmatch.group(1) != null) {
|
||||
if (clan.containsKey(pmatch.group(1).replace(" ", " "))) {
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
entries = ArrayUtils.removeElement(entries, entries[entries.length - 1]);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@Singleton
|
||||
public class ClanManModeService
|
||||
{
|
||||
private final Client client;
|
||||
private final ClanManModeConfig config;
|
||||
private final ClanManModePlugin plugin;
|
||||
|
||||
@Inject
|
||||
private ClanManModeService(Client client, ClanManModeConfig config, ClanManModePlugin plugin)
|
||||
{
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
Map<String, String> interactors = new HashMap<>();
|
||||
|
||||
public void forEachPlayer(final BiConsumer<Player, Color> consumer)
|
||||
{
|
||||
int minatk = plugin.clanmax - plugin.wildernessLevel;
|
||||
int maxatk = plugin.clanmin + plugin.wildernessLevel;
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
final String localName = localPlayer.getName();
|
||||
int selfmin = localPlayer.getCombatLevel() - plugin.wildernessLevel;
|
||||
int selfmax = localPlayer.getCombatLevel() + plugin.wildernessLevel;
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
if (player == null || player.getName() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player == localPlayer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isClanMember = player.isClanMember();
|
||||
Actor interacting = player.getInteracting();
|
||||
Player interactor = null;
|
||||
if (interacting != null && !(interacting instanceof NPC)) {
|
||||
interactor = ((Player) interacting);
|
||||
}
|
||||
|
||||
if (config.showAttackers()) {
|
||||
if (interactor != null) {
|
||||
if (interactor.getName().equals(localName)) {
|
||||
consumer.accept(player, config.getAttackerColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.inwildy == 1) {
|
||||
if (isClanMember) {
|
||||
if (!plugin.clan.containsKey(player.getName())) {
|
||||
plugin.clan.put(player.getName(), player.getCombatLevel());
|
||||
}
|
||||
if (config.highlightAttacked()) {
|
||||
if (interactor != null) {
|
||||
if (!interactors.containsKey(interactor.getName())) {
|
||||
WorldPoint a = interactor.getWorldLocation();
|
||||
int underLevel = ((a.getY() - 9920) / 8) + 1;
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
int wildydiff = plugin.wildernessLevel - wildernessLevel;
|
||||
if (wildydiff < 0) {
|
||||
wildydiff = 0;
|
||||
}
|
||||
if (config.CalcSelfCB()) {
|
||||
if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember()) {
|
||||
interactors.put(interactor.getName(), player.getName());
|
||||
consumer.accept(interactor, config.getClanAttackableColor());
|
||||
}
|
||||
} else {
|
||||
if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember()) {
|
||||
interactors.put(interactor.getName(), player.getName());
|
||||
consumer.accept(interactor, config.getClanAttackableColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (config.PersistentClan()) {
|
||||
if (plugin.clan.containsKey(player.getName())) {
|
||||
consumer.accept(player, config.getClanMemberColor());
|
||||
}
|
||||
}
|
||||
if (config.highlightAttacked()) {
|
||||
if (interactors.containsKey(player.getName())) {
|
||||
String attackername = interactors.get(player.getName());
|
||||
Boolean found = false;
|
||||
for (Player attacker : client.getPlayers()) {
|
||||
if (attacker == null || attacker.getName() == null) {
|
||||
continue;
|
||||
}
|
||||
if (attacker.getName().equals(attackername)) {
|
||||
found = true;
|
||||
Actor ainteract = attacker.getInteracting();
|
||||
if (ainteract != null) {
|
||||
if (ainteract.getName().equals(player.getName())) {
|
||||
consumer.accept(player, config.getClanAttackableColor());
|
||||
} else {
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
} else {
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (config.highlightAttackable()) {
|
||||
if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName())) {
|
||||
continue;
|
||||
}
|
||||
WorldPoint a = player.getWorldLocation();
|
||||
int underLevel = ((a.getY() - 9920) / 8) + 1;
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
int wildydiff = plugin.wildernessLevel - wildernessLevel;
|
||||
if (wildydiff < 0) {
|
||||
wildydiff = 0;
|
||||
}
|
||||
if (config.CalcSelfCB()) {
|
||||
if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin) {
|
||||
consumer.accept(player, config.getAttackableColor());
|
||||
}
|
||||
} else {
|
||||
if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk) {
|
||||
consumer.accept(player, config.getAttackableColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class ClanManModeTileOverlay extends Overlay
|
||||
{
|
||||
private final ClanManModeService ClanManModeService;
|
||||
private final ClanManModeConfig config;
|
||||
|
||||
@Inject
|
||||
private ClanManModeTileOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService)
|
||||
{
|
||||
this.config = config;
|
||||
this.ClanManModeService = ClanManModeService;
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!config.drawTiles())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ClanManModeService.forEachPlayer((player, color) ->
|
||||
{
|
||||
final Polygon poly = player.getCanvasTilePoly();
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -310,7 +310,8 @@ public class ConfigPanel extends PluginPanel
|
||||
String name = listItem.getName();
|
||||
JLabel title = new JLabel(name);
|
||||
title.setForeground(Color.WHITE);
|
||||
title.setToolTipText("<html>" + name + ":<br>" + listItem.getDescription() + "</html>");
|
||||
title.setText("<html>" + name +"</html>");
|
||||
title.setToolTipText("<html>" + ":<br>" + listItem.getDescription() + "</html>");
|
||||
topPanel.add(title);
|
||||
|
||||
for (ConfigItemDescriptor cid : cd.getItems())
|
||||
|
||||
@@ -153,8 +153,10 @@ class PluginListItem extends JPanel
|
||||
setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 20));
|
||||
|
||||
JLabel nameLabel = new JLabel(name);
|
||||
nameLabel.setText("<html>" + name +"</html>");
|
||||
nameLabel.setForeground(Color.WHITE);
|
||||
|
||||
|
||||
if (!description.isEmpty())
|
||||
{
|
||||
nameLabel.setToolTipText("<html>" + name + ":<br>" + description + "</html>");
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||
* 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.cox;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Range;
|
||||
|
||||
@ConfigGroup("hydra")
|
||||
public interface CoxConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "showHydraTile",
|
||||
name = "Hydra's Size Box ",
|
||||
description = "Displays hydra's size box for luring over vents"
|
||||
)
|
||||
default boolean showHydraTile()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "tileColour",
|
||||
name = "Color of hydra tile size",
|
||||
description = "Configures the color of hydra's size"
|
||||
)
|
||||
default Color hydraTileColour()
|
||||
{
|
||||
return Color.ORANGE;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = -1000,
|
||||
max = 1000
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "prayerHeight",
|
||||
name = "Sets hydra's prayer height",
|
||||
description = "The height of the prayer indicator over Hydra"
|
||||
)
|
||||
default int prayerHeight()
|
||||
{
|
||||
return 450;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "showHydraPrayer",
|
||||
name = "Hydra's Attack Style Indicator",
|
||||
description = "Displays hydra's size box for luring over vents"
|
||||
)
|
||||
default boolean showPrayer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Jacky <https://github.com/jkybtw>
|
||||
* 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.cox;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class CoxOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final CoxPlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
public CoxOverlay(Client client, CoxPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!client.isInInstancedRegion()) return null;
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
{
|
||||
if (plugin.getOlm() != null)
|
||||
{
|
||||
if (plugin.getAttackStyle() == 0)
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Pray: ")
|
||||
.right("Mage")
|
||||
.build());
|
||||
}
|
||||
|
||||
if (plugin.getAttackStyle() == 1)
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Pray: ")
|
||||
.right("Ranged")
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package net.runelite.client.plugins.cox;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GraphicsObject;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Scene;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class CoxOverlayAbove extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final CoxPlugin plugin;
|
||||
private CoxConfig config;
|
||||
|
||||
@Inject
|
||||
public CoxOverlayAbove(Client client, CoxPlugin plugin, CoxConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!client.isInInstancedRegion() && plugin.getOlm() == null) return null;
|
||||
|
||||
renderGroundObject(graphics);
|
||||
|
||||
renderTileObjects(graphics);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// renders special attack ground objects
|
||||
private void renderGroundObject(Graphics2D graphics)
|
||||
{
|
||||
List<GraphicsObject> graphicsObjects = client.getGraphicsObjects();
|
||||
|
||||
for (GraphicsObject graphicsObject : graphicsObjects)
|
||||
{
|
||||
if (graphicsObject.getId() == 1447 || graphicsObject.getId() == 1356)
|
||||
{
|
||||
LocalPoint lp = graphicsObject.getLocation();
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, Color.RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderGameObjects(Graphics2D graphics, Tile tile, Player player)
|
||||
{
|
||||
GameObject[] gameObjects = tile.getGameObjects();
|
||||
if (gameObjects != null)
|
||||
{
|
||||
for (GameObject gameObject : gameObjects)
|
||||
{
|
||||
if (gameObject != null && gameObject.getId() == 30033)
|
||||
{
|
||||
if (player.getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= 5)
|
||||
{
|
||||
// Draw a polygon around the convex hull
|
||||
// of the model vertices
|
||||
Polygon p = gameObject.getConvexHull();
|
||||
if (p != null)
|
||||
{
|
||||
graphics.drawPolygon(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTileObjects(Graphics2D graphics)
|
||||
{
|
||||
Scene scene = client.getScene();
|
||||
Tile[][][] tiles = scene.getTiles();
|
||||
|
||||
int z = client.getPlane();
|
||||
|
||||
for (int x = 0; x < Constants.SCENE_SIZE; ++x)
|
||||
{
|
||||
for (int y = 0; y < Constants.SCENE_SIZE; ++y)
|
||||
{
|
||||
Tile tile = tiles[z][x][y];
|
||||
|
||||
if (tile == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Player player = client.getLocalPlayer();
|
||||
if (player == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
renderGameObjects(graphics, tile, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Jacky <https://github.com/jkybtw>
|
||||
* 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.cox;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Cox",
|
||||
description = "COX Helper",
|
||||
tags = {"combat", "overlay", "pve", "pvm"}
|
||||
)
|
||||
public class CoxPlugin extends Plugin
|
||||
{
|
||||
@Getter
|
||||
private NPC olm = null;
|
||||
|
||||
@Getter
|
||||
private int attackStyle = 0; // 0 - mage // 1 - range
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private CoxOverlay coxOverlay;
|
||||
|
||||
@Inject CoxOverlayAbove coxOverlayAbove;
|
||||
|
||||
@Inject
|
||||
private CoxConfig config;
|
||||
|
||||
|
||||
@Provides
|
||||
CoxConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(CoxConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(coxOverlay);
|
||||
overlayManager.add(coxOverlayAbove);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(coxOverlay);
|
||||
overlayManager.remove(coxOverlayAbove);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (!client.isInInstancedRegion())
|
||||
{
|
||||
olm = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.getPlane() != 0) return;
|
||||
|
||||
List<NPC> npcs = client.getNpcs();
|
||||
|
||||
for (NPC npc : npcs)
|
||||
{
|
||||
if (npc.getId() == 7554)
|
||||
{
|
||||
olm = npc;
|
||||
}
|
||||
}
|
||||
|
||||
if (olm == null) return;
|
||||
|
||||
List<Projectile> projectiles = client.getProjectiles();
|
||||
|
||||
for (Projectile projectile : projectiles)
|
||||
{
|
||||
if (projectile.getId() == 1339)
|
||||
{
|
||||
// mage
|
||||
attackStyle = 0;
|
||||
}
|
||||
|
||||
if (projectile.getId() == 1340)
|
||||
{
|
||||
// range
|
||||
attackStyle = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package net.runelite.client.plugins.easy.bank;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
|
||||
@ConfigGroup("easybank")
|
||||
public interface EasyBankConfig extends Config {
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawOne",
|
||||
name = "Withdraw/Deposit One",
|
||||
description = "",
|
||||
position = 0
|
||||
)
|
||||
|
||||
default boolean getWithdrawOne() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawOneItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
|
||||
default String getWithdrawOneItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawFive",
|
||||
name = "Withdraw/Deposit Five",
|
||||
description = "",
|
||||
position = 2
|
||||
)
|
||||
|
||||
default boolean getWithdrawFive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawFiveItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 3
|
||||
)
|
||||
|
||||
default String getWithdrawFiveItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawTen",
|
||||
name = "Withdraw/Deposit Ten",
|
||||
description = "",
|
||||
position = 4
|
||||
)
|
||||
|
||||
default boolean getWithdrawTen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawTenItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 5
|
||||
)
|
||||
|
||||
default String getWithdrawTenItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawX",
|
||||
name = "Withdraw/Deposit X",
|
||||
description = "",
|
||||
position = 6
|
||||
)
|
||||
|
||||
default boolean getWithdrawX() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawXAmount",
|
||||
name = "Amount",
|
||||
description = "",
|
||||
position = 7
|
||||
)
|
||||
|
||||
default String getWithdrawXAmount() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawXItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 8
|
||||
)
|
||||
|
||||
default String getWithdrawXItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawAll",
|
||||
name = "Withdraw/Deposit All",
|
||||
description = "",
|
||||
position = 9
|
||||
)
|
||||
|
||||
default boolean getWithdrawAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "withdrawAllItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 10
|
||||
)
|
||||
|
||||
default String getWithdrawAllItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package net.runelite.client.plugins.easy.bank;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.easy.util.Swapper;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "EasyBank",
|
||||
description = "EasyBank.",
|
||||
tags = {"EasyBank", "easy"}
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class EasyBankPlugin extends Plugin {
|
||||
|
||||
private Swapper swapper = new Swapper();
|
||||
private MenuEntry[] entries;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private EasyBankConfig config;
|
||||
|
||||
@Provides
|
||||
EasyBankConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(EasyBankConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp() {
|
||||
log.debug("EasyBank Started.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
log.debug("EasyBank Stopped.");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
|
||||
Widget loginScreenOne = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN);
|
||||
Widget loginScreenTwo = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY);
|
||||
|
||||
if (loginScreenOne != null || loginScreenTwo != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
final String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
|
||||
|
||||
swapper.setEntries(client.getMenuEntries());
|
||||
|
||||
if (!(widgetBankTitleBar == null) && !widgetBankTitleBar.isHidden()) {
|
||||
|
||||
if (config.getWithdrawOne()) {
|
||||
for (String item : config.getWithdrawOneItems().split(",")) {
|
||||
item = item.trim();
|
||||
if (target.equalsIgnoreCase(item)) {
|
||||
swapper.markForSwap("Withdraw-1", option, target);
|
||||
swapper.markForSwap("Deposit-1", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getWithdrawFive()) {
|
||||
for (String item : config.getWithdrawFiveItems().split(",")) {
|
||||
item = item.trim();
|
||||
if (target.equalsIgnoreCase(item)) {
|
||||
swapper.markForSwap("Withdraw-5", option, target);
|
||||
swapper.markForSwap("Deposit-5", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getWithdrawTen()) {
|
||||
for (String item : config.getWithdrawTenItems().split(",")) {
|
||||
item = item.trim();
|
||||
if (target.equalsIgnoreCase(item)) {
|
||||
swapper.markForSwap("Withdraw-10", option, target);
|
||||
swapper.markForSwap("Deposit-10", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getWithdrawX()) {
|
||||
for (String item : config.getWithdrawXItems().split(",")) {
|
||||
item = item.trim();
|
||||
if (target.equalsIgnoreCase(item)) {
|
||||
swapper.markForSwap("Withdraw-" + config.getWithdrawXAmount(), option, target);
|
||||
swapper.markForSwap("Deposit-" + config.getWithdrawXAmount(), option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getWithdrawAll()) {
|
||||
for (String item : config.getWithdrawAllItems().split(",")) {
|
||||
item = item.trim();
|
||||
if (target.equalsIgnoreCase(item)) {
|
||||
swapper.markForSwap("Withdraw-All", option, target);
|
||||
swapper.markForSwap("Deposit-All", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
swapper.startSwap();
|
||||
client.setMenuEntries(swapper.getEntries());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package net.runelite.client.plugins.easy.pvp;
|
||||
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("easypvp")
|
||||
public interface EasyPvpConfig extends Config {
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showWildernessRange",
|
||||
name = "Show Wilderness Range",
|
||||
description = "",
|
||||
position = 0
|
||||
)
|
||||
|
||||
default boolean getShowWildernessRange() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "ShowAttackablePlayers",
|
||||
name = "Show Attackable Players",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
|
||||
default boolean getShowAttackablePlayers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warnProtectItemOff",
|
||||
name = "Warn Protect Item Off",
|
||||
description = "",
|
||||
position = 2
|
||||
)
|
||||
|
||||
default boolean getWarnProtectItemOff() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showFreezeTimers",
|
||||
name = "Show Freeze Timers",
|
||||
description = "",
|
||||
position = 3
|
||||
)
|
||||
|
||||
default boolean getShowFreezeTimers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package net.runelite.client.plugins.easy.pvp;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class EasyPvpOverlay extends Overlay {
|
||||
|
||||
private final Client client;
|
||||
private final EasyPvpPlugin plugin;
|
||||
private final EasyPvpConfig config;
|
||||
|
||||
@Inject
|
||||
private EasyPvpOverlay(Client client, EasyPvpPlugin plugin, EasyPvpConfig config) {
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (config.getShowAttackablePlayers()) {
|
||||
for (Player player : plugin.getTargets()) {
|
||||
OverlayUtil.renderPolygon(graphics, player.getConvexHull(), Color.RED);
|
||||
|
||||
Point minimapLocation = player.getMinimapLocation();
|
||||
if (minimapLocation != null) {
|
||||
OverlayUtil.renderMinimapLocation(graphics, minimapLocation, Color.RED.darker());
|
||||
OverlayUtil.renderTextLocation(graphics, minimapLocation, player.getName(), Color.RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// @Override
|
||||
// public Dimension render(Graphics2D graphics)
|
||||
// {
|
||||
// if (config.getShowWildernessRange())
|
||||
// {
|
||||
//// plugin.getDeadNpcsToDisplay().forEach((id, npc) -> renderNpcRespawn(npc, graphics));
|
||||
// }
|
||||
//
|
||||
// if (config.getShowAttackablePlayers())
|
||||
//
|
||||
// for (Player player : plugin.getAttackablePlayers()) {
|
||||
// if (player != null) {
|
||||
// renderNpcOverlay(graphics, player, player.getName(), Color.RED);
|
||||
// } else {
|
||||
// plugin.getAttackablePlayers().remove(player);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// private void renderNpcOverlay(Graphics2D graphics, Player actor, String name, Color color)
|
||||
// {
|
||||
// LocalPoint lp = actor.getLocalLocation();
|
||||
//// Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, 1);
|
||||
//
|
||||
// renderTile(graphics, lp, color);
|
||||
//// renderMinimap();
|
||||
//
|
||||
//// if (config.drawNames())
|
||||
//// {
|
||||
//// Point textLocation = actor.getCanvasTextLocation(graphics, name, actor.getLogicalHeight() + 40);
|
||||
////
|
||||
//// if (textLocation != null)
|
||||
//// {
|
||||
//// OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
|
||||
//// }
|
||||
//// }
|
||||
// }
|
||||
|
||||
// private void renderTile(final Graphics2D graphics, final LocalPoint dest, final Color color)
|
||||
// {
|
||||
// if (dest == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// final Polygon poly = Perspective.getCanvasTilePoly(client, dest);
|
||||
// if (poly == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
// }
|
||||
@@ -0,0 +1,197 @@
|
||||
package net.runelite.client.plugins.easy.pvp;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provides;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "EasyPvP",
|
||||
description = "EasyPvP.",
|
||||
tags = {"EasyPVP", "easy"}
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class EasyPvpPlugin extends Plugin {
|
||||
|
||||
private int inWildy;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private EasyPvpConfig config;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private EasyPvpOverlay overlay;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Set<Player> targets = new HashSet<>();
|
||||
|
||||
private String target;
|
||||
private boolean prayMage;
|
||||
private WorldPoint location;
|
||||
private String spell;
|
||||
private int currentExperience;
|
||||
private int gainedExperience;
|
||||
|
||||
@Provides
|
||||
EasyPvpConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(EasyPvpConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp() {
|
||||
prayMage = false;
|
||||
spell = "";
|
||||
overlayManager.add(overlay);
|
||||
log.debug("EasyPvP Started.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
overlayManager.remove(overlay);
|
||||
log.debug("EasyPvP Stopped.");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event) {
|
||||
|
||||
inWildy = client.getVar(Varbits.IN_WILDERNESS);
|
||||
|
||||
if (inWildy == 0) {
|
||||
targets.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
Widget wildyText = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
|
||||
if (wildyText == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int wildyLevel = Integer.parseInt(wildyText.getText().split(":")[1].trim());
|
||||
|
||||
|
||||
if (config.getShowAttackablePlayers()) {
|
||||
for (Player player : client.getPlayers()) {
|
||||
if (Math.abs(player.getCombatLevel() - client.getLocalPlayer().getCombatLevel()) <= wildyLevel) { // && !player.equals(client.getLocalPlayer())
|
||||
targets.add(player);
|
||||
} else targets.remove(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Subscribe
|
||||
// public void onGameStateChanged(GameStateChanged event) {
|
||||
// if (event.getGameState() == GameState.LOGGED_IN) {
|
||||
// currentExperience = client.getSkillExperience(Skill.MAGIC);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Subscribe
|
||||
// public void onMenuOptionClicked(MenuOptionClicked event) {
|
||||
// if (event.getMenuTarget().contains("->")) {
|
||||
// target = Text.removeTags(event.getMenuTarget()).split(" -> ")[1];
|
||||
// spell = Text.removeTags(event.getMenuTarget()).split(" -> ")[0];
|
||||
// log.debug("{} - {}", spell, target);
|
||||
// prayMage = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Subscribe
|
||||
// public void onExperienceChanged(ExperienceChanged event) {
|
||||
// if (event.getSkill() == Skill.MAGIC) {
|
||||
// gainedExperience = client.getSkillExperience(Skill.MAGIC) - currentExperience;
|
||||
// currentExperience = client.getSkillExperience(Skill.MAGIC);
|
||||
// long frozenTime = calculateFreezeTime(gainedExperience, spell, prayMage);
|
||||
// if (frozenTime > 0) {
|
||||
// for (Player player : client.getPlayers()) {
|
||||
// if (player.getName().equals(target)) {
|
||||
// location = player.getWorldLocation();
|
||||
// if (player.getOverheadIcon() != null && player.getOverheadIcon().equals(HeadIcon.MAGIC)) {
|
||||
// prayMage = true;
|
||||
// break;
|
||||
// }
|
||||
// targets.add(new Markable(player, location, System.currentTimeMillis(), frozenTime));
|
||||
// log.debug("Marked Target {}", player.getName());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public long calculateFreezeTime(int experience, String spell, boolean protectionPrayer) {
|
||||
// long freezeTime = 0;
|
||||
// switch (spell) {
|
||||
// case "Bind":
|
||||
// if (experience > 30) {
|
||||
// if (protectionPrayer) {
|
||||
// freezeTime = 2500;
|
||||
// } else {
|
||||
// freezeTime = 5000;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// case "Snare":
|
||||
// if (experience > 60) {
|
||||
// if (protectionPrayer) {
|
||||
// freezeTime = 5000;
|
||||
// } else {
|
||||
// freezeTime = 10000;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// case "Entangle":
|
||||
// if (experience > 89) {
|
||||
// if (protectionPrayer) {
|
||||
// freezeTime = 7500;
|
||||
// } else {
|
||||
// freezeTime = 15000;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// case "Ice Rush":
|
||||
// if (experience > 34) {
|
||||
// freezeTime = 5000;
|
||||
// }
|
||||
// break;
|
||||
// case "Ice Burst":
|
||||
// if (experience > 40) {
|
||||
// freezeTime = 10000;
|
||||
// }
|
||||
// break;
|
||||
// case "Ice Blitz":
|
||||
// if (experience > 46) {
|
||||
// freezeTime = 15000;
|
||||
// }
|
||||
// break;
|
||||
// case "Ice Barrage":
|
||||
// if (experience > 52) {
|
||||
// freezeTime = 20000;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// return freezeTime;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.runelite.client.plugins.easy.scape;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("easyscape")
|
||||
public interface EasyScapeConfig extends Config {
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeExamine",
|
||||
name = "Remove Examine",
|
||||
description = "Removes Examine from the list of options.",
|
||||
position = 0
|
||||
)
|
||||
|
||||
default boolean getRemoveExamine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeObjects",
|
||||
name = "Remove Objects",
|
||||
description = "Removes interaction with the listed objects.",
|
||||
position = 1
|
||||
)
|
||||
|
||||
default boolean getRemoveObjects() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removedObjects",
|
||||
name = "Objects",
|
||||
description = "Objects listed here will have all interaction be removed.",
|
||||
position = 2
|
||||
)
|
||||
|
||||
default String getRemovedObjects() {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package net.runelite.client.plugins.easy.scape;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "EasyScape",
|
||||
description = "EasyScape.",
|
||||
tags = {"EasyScape"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class EasyScapePlugin extends Plugin {
|
||||
|
||||
private MenuEntry[] entries;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private EasyScapeConfig config;
|
||||
|
||||
@Provides
|
||||
EasyScapeConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(EasyScapeConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp() {
|
||||
log.debug("EasyScape Started.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
log.debug("EasyScape Stopped.");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
|
||||
Widget loginScreenOne = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN);
|
||||
Widget loginScreenTwo = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY);
|
||||
|
||||
if (loginScreenOne != null || loginScreenTwo != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
entries = client.getMenuEntries();
|
||||
|
||||
if (config.getRemoveExamine()) {
|
||||
for (int i = entries.length - 1; i >= 0; i--) {
|
||||
if (entries[i].getOption().equals("Examine")) {
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
|
||||
if (config.getRemoveObjects() && !config.getRemovedObjects().equals("")) {
|
||||
for (String removed : config.getRemovedObjects().split(",")) {
|
||||
removed = removed.trim();
|
||||
if (target.contains("(") && target.split(" \\(")[0].equalsIgnoreCase(removed)) {
|
||||
delete(event.getIdentifier());
|
||||
} else if (target.contains("->")) {
|
||||
String trimmed = target.split("->")[1].trim();
|
||||
if (trimmed.length() >= removed.length() && trimmed.substring(0, removed.length()).equalsIgnoreCase(removed)) {
|
||||
delete(event.getIdentifier());
|
||||
break;
|
||||
}
|
||||
} else if (target.length() >= removed.length() && target.substring(0, removed.length()).equalsIgnoreCase(removed)) {
|
||||
delete(event.getIdentifier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void delete(int target) {
|
||||
for (int i = entries.length - 1; i >= 0; i--) {
|
||||
if (entries[i].getIdentifier() == target) {
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package net.runelite.client.plugins.easy.shop;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("easyshop")
|
||||
public interface EasyShopConfig extends Config {
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapBuyOne",
|
||||
name = "Swappable Buy One",
|
||||
description = "",
|
||||
position = 0
|
||||
)
|
||||
|
||||
default boolean getSwapBuyOne() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "buyOneItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
|
||||
default String getBuyOneItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapBuyFive",
|
||||
name = "Swappable Buy Five",
|
||||
description = "",
|
||||
position = 2
|
||||
)
|
||||
|
||||
default boolean getSwapBuyFive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "buyFiveItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 3
|
||||
)
|
||||
|
||||
default String getBuyFiveItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapBuyTen",
|
||||
name = "Swappable Buy Ten",
|
||||
description = "",
|
||||
position = 4
|
||||
)
|
||||
|
||||
default boolean getSwapBuyTen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "buyTenItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 5
|
||||
)
|
||||
|
||||
default String getBuyTenItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapBuyFifty",
|
||||
name = "Swappable Buy Fifty",
|
||||
description = "",
|
||||
position = 6
|
||||
)
|
||||
|
||||
default boolean getSwapBuyFifty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "buyFiftyItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 7
|
||||
)
|
||||
|
||||
default String getBuyFiftyItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSellOne",
|
||||
name = "Swappable Sell One",
|
||||
description = "",
|
||||
position = 8
|
||||
)
|
||||
|
||||
default boolean getSwapSellOne() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "sellOneItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 9
|
||||
)
|
||||
|
||||
default String getSellOneItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSellFive",
|
||||
name = "Swappable Sell Five",
|
||||
description = "",
|
||||
position = 10
|
||||
)
|
||||
|
||||
default boolean getSwapSellFive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "sellFiveItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 11
|
||||
)
|
||||
|
||||
default String getSellFiveItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSellTen",
|
||||
name = "Swappable Sell Ten",
|
||||
description = "",
|
||||
position = 12
|
||||
)
|
||||
|
||||
default boolean getSwapSellTen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "sellTenItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 13
|
||||
)
|
||||
|
||||
default String getSellTenItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSellFifty",
|
||||
name = "Swappable Sell Fifty",
|
||||
description = "",
|
||||
position = 14
|
||||
)
|
||||
|
||||
default boolean getSwapSellFifty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "sellFiftyItems",
|
||||
name = "Items",
|
||||
description = "",
|
||||
position = 15
|
||||
)
|
||||
|
||||
default String getSellFiftyItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package net.runelite.client.plugins.easy.shop;
|
||||
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.easy.util.Swapper;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "EasyShop",
|
||||
description = "EasyShop.",
|
||||
tags = {"EasyShop", "easy"}
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class EasyShopPlugin extends Plugin {
|
||||
|
||||
private Swapper swapper = new Swapper();
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private EasyShopConfig config;
|
||||
|
||||
@Provides
|
||||
EasyShopConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(EasyShopConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp() {
|
||||
log.debug("EasyShop Started.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
log.debug("EasyShop Stopped.");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
|
||||
Widget loginScreenOne = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN);
|
||||
Widget loginScreenTwo = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY);
|
||||
|
||||
if (loginScreenOne != null || loginScreenTwo != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
final String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
swapper.setEntries(client.getMenuEntries());
|
||||
|
||||
if (config.getSwapBuyOne() && !config.getBuyOneItems().equals("")) {
|
||||
for (String item : config.getBuyOneItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Buy 1", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapBuyFive() && !config.getBuyFiveItems().equals("")) {
|
||||
for (String item : config.getBuyFiveItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Buy 5", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapBuyTen() && !config.getBuyTenItems().equals("")) {
|
||||
for (String item : config.getBuyTenItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Buy 10", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapBuyFifty() && !config.getBuyFiftyItems().equals("")) {
|
||||
for (String item : config.getBuyFiftyItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Buy 50", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapSellOne() && !config.getSellOneItems().equals("")) {
|
||||
for (String item : config.getSellOneItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Sell 1", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapSellFive() && !config.getSellFiveItems().equals("")) {
|
||||
for (String item : config.getSellFiveItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Sell 5", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapSellTen() && !config.getSellTenItems().equals("")) {
|
||||
for (String item : config.getSellTenItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Sell 10", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapSellFifty() && !config.getSellFiftyItems().equals("")) {
|
||||
for (String item : config.getSellFiftyItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swapper.markForSwap("Sell 50", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swapper.startSwap();
|
||||
client.setMenuEntries(swapper.getEntries());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
package net.runelite.client.plugins.easy.swap;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.plugins.easy.util.DuelingRingMode;
|
||||
import net.runelite.client.plugins.easy.util.EssenceMode;
|
||||
import net.runelite.client.plugins.easy.util.GamesNecklaceMode;
|
||||
import net.runelite.client.plugins.easy.util.GloryMode;
|
||||
|
||||
@ConfigGroup("easyswap")
|
||||
public interface EasySwapConfig extends Config {
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "easyConstruction",
|
||||
name = "Easy Construction",
|
||||
description = "Makes \"Remove\" the default option for listed items in build mode.",
|
||||
position = 0
|
||||
)
|
||||
|
||||
default boolean getEasyConstruction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "constructionItems",
|
||||
name = "Construction Items",
|
||||
description = "Items listed here will have the default option set to \"Removed\" in build mode.",
|
||||
position = 1
|
||||
)
|
||||
|
||||
default String getConstructionItems() {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSmithing",
|
||||
name = "Swap Smithing",
|
||||
description = "Enables swapping of smith-1 and smith-all options.",
|
||||
position = 2
|
||||
)
|
||||
|
||||
default boolean getSwapSmithing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapTanning",
|
||||
name = "Swap Tanning",
|
||||
description = "Enables swapping of tan-1 and tan-all options.",
|
||||
position = 3
|
||||
)
|
||||
|
||||
default boolean getSwapTanning() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapCrafting",
|
||||
name = "Swap Crafting",
|
||||
description = "Enables swapping of Make-1 and Make-all options.",
|
||||
position = 4
|
||||
)
|
||||
|
||||
default boolean getSwapCrafting() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapArdougneCape",
|
||||
name = "Swap Ardougne Cape",
|
||||
description = "Enables swapping of teleport and wear.",
|
||||
position = 5
|
||||
)
|
||||
|
||||
default boolean getSwapArdougneCape() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSawmill",
|
||||
name = "Swap Sawmill Operator",
|
||||
description = "Makes Buy-plank the default option on the sawmill operator.",
|
||||
position = 6
|
||||
)
|
||||
|
||||
default boolean getSwapSawmill() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSawmillPlanks",
|
||||
name = "Swap Buy Planks",
|
||||
description = "Makes Buy All the default option in buy planks.",
|
||||
position = 7
|
||||
)
|
||||
|
||||
default boolean getSwapSawmillPlanks() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapPuroPuro",
|
||||
name = "Swap Puro Puro Wheat",
|
||||
description = "",
|
||||
position = 8
|
||||
)
|
||||
|
||||
default boolean getSwapPuro() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapEssencePounch",
|
||||
name = "Swap Essence Pouch",
|
||||
description = "",
|
||||
position = 9
|
||||
)
|
||||
|
||||
default boolean getSwapEssencePouch() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "essenceMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 10
|
||||
)
|
||||
|
||||
default EssenceMode getEssenceMode() {
|
||||
return EssenceMode.RUNECRAFTING;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapGamesNecklace",
|
||||
name = "Swap Games Necklace",
|
||||
description = "",
|
||||
position = 11
|
||||
)
|
||||
default boolean getGamesNecklace() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gamesNecklaceMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 12
|
||||
)
|
||||
|
||||
default GamesNecklaceMode getGamesNecklaceMode() {
|
||||
return GamesNecklaceMode.BURTHORPE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapDuelingRing",
|
||||
name = "Swap Dueling Ring",
|
||||
description = "",
|
||||
position = 13
|
||||
)
|
||||
|
||||
default boolean getDuelingRing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "duelingRingMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 14
|
||||
)
|
||||
|
||||
default DuelingRingMode getDuelingRingMode() {
|
||||
return DuelingRingMode.DUEL_ARENA;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapGlory",
|
||||
name = "Swap Glory",
|
||||
description = "",
|
||||
position = 15
|
||||
)
|
||||
|
||||
default boolean getGlory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gloryMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 16
|
||||
)
|
||||
|
||||
default GloryMode getGloryMode() {
|
||||
return GloryMode.EDGEVILLE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package net.runelite.client.plugins.easy.swap;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.easy.util.Swapper;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static net.runelite.api.MenuAction.WALK;
|
||||
import static net.runelite.api.ObjectID.PORTAL_4525;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "EasySwap",
|
||||
description = "EasySwap.",
|
||||
tags = {"EasySwap", "easy"}
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class EasySwapPlugin extends Plugin {
|
||||
|
||||
private static final int PURO_PURO_REGION_ID = 10307;
|
||||
|
||||
private Swapper swapper = new Swapper();
|
||||
private boolean inHouse = false;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private EasySwapConfig config;
|
||||
|
||||
@Provides
|
||||
EasySwapConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(EasySwapConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp() {
|
||||
log.debug("EasySwap Started.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
log.debug("EasySwap Stopped.");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
|
||||
Widget loginScreenOne = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN);
|
||||
Widget loginScreenTwo = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY);
|
||||
|
||||
if (loginScreenOne != null || loginScreenTwo != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
final String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
swapper.setEntries(client.getMenuEntries());
|
||||
|
||||
if (config.getSwapPuro() && isPuroPuro()) {
|
||||
if (event.getType() == WALK.getId()) {
|
||||
swapper.deprioritizeWalk();
|
||||
} else if (option.equalsIgnoreCase("examine")) {
|
||||
swapper.markForSwap("push-through", option, target);
|
||||
} else if (option.equalsIgnoreCase("use")) {
|
||||
swapper.markForSwap("escape", option, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getEasyConstruction() && !config.getConstructionItems().equals("") && inHouse) {
|
||||
if (event.getType() == WALK.getId()) {
|
||||
swapper.deprioritizeWalk();
|
||||
}
|
||||
|
||||
swapper.markForSwap("Build", option, target);
|
||||
|
||||
for (int i = swapper.getEntries().length - 1; i >= 0; i--) {
|
||||
for (String item : config.getConstructionItems().split(",")) {
|
||||
if (item.trim().equalsIgnoreCase(Text.removeTags(swapper.getEntries()[i].getTarget()))) {
|
||||
if (!swapper.getEntries()[i].getOption().equalsIgnoreCase("remove")) {
|
||||
swapper.removeIndex(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapSmithing()) {
|
||||
if (option.equalsIgnoreCase("Smith 1")) {
|
||||
swapper.markForSwap("Smith All", option, target);
|
||||
} else if (option.equalsIgnoreCase("Smith 1 Set")) {
|
||||
swapper.markForSwap("Smith All Sets", option, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapTanning() && option.equalsIgnoreCase("Tan 1")) {
|
||||
swapper.markForSwap("Tan All", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapCrafting()) {
|
||||
switch (option) {
|
||||
case "Make-1":
|
||||
swapper.markForSwap("Make-All", option, target);
|
||||
break;
|
||||
case "Craft 1":
|
||||
swapper.markForSwap("Craft All", option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapSawmill() && target.equalsIgnoreCase("Sawmill operator")) {
|
||||
swapper.markForSwap("Buy-plank", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapSawmillPlanks() && option.equalsIgnoreCase("Buy 1")) {
|
||||
swapper.markForSwap("Buy All", option, target);
|
||||
}
|
||||
|
||||
if (option.equalsIgnoreCase("Clear-All") && target.equalsIgnoreCase("bank Filler")) {
|
||||
swapper.markForSwap("Clear", option, target);
|
||||
}
|
||||
|
||||
if (target.toLowerCase().contains("ardougne cloak") && config.getSwapArdougneCape()) {
|
||||
swapper.markForSwap("Kandarin Monastery", option, target);
|
||||
swapper.markForSwap("Monastery Teleport", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapEssencePouch()) {
|
||||
if (isEssencePouch(target)) {
|
||||
Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
|
||||
switch (config.getEssenceMode()) {
|
||||
case RUNECRAFTING:
|
||||
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden()) {
|
||||
swapper.markForSwap("Empty", option, target);
|
||||
} else {
|
||||
swapper.markForSwap("Fill", option, target);
|
||||
}
|
||||
break;
|
||||
case ESSENCE_MINING:
|
||||
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden()) {
|
||||
swapper.markForSwap("Fill", option, target);
|
||||
} else {
|
||||
swapper.markForSwap("Empty", option, target);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getGamesNecklace()) {
|
||||
if (target.toLowerCase().contains("games necklace")) {
|
||||
swapper.markForSwap(config.getGamesNecklaceMode().toString(), option, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getDuelingRing()) {
|
||||
if (target.toLowerCase().contains("ring of dueling")) {
|
||||
swapper.markForSwap(config.getDuelingRingMode().toString(), option, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getGlory()) {
|
||||
if (target.toLowerCase().contains("amulet of glory")) {
|
||||
swapper.markForSwap(config.getGloryMode().toString(), option, target);
|
||||
}
|
||||
}
|
||||
|
||||
swapper.startSwap();
|
||||
client.setMenuEntries(swapper.getEntries());
|
||||
}
|
||||
|
||||
private boolean isEssencePouch(String target) {
|
||||
return (target.equalsIgnoreCase("Small Pouch") || target.equalsIgnoreCase("Medium Pouch") || target.equalsIgnoreCase("Large Pouch") || target.equalsIgnoreCase("Giant Pouch"));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
if (PORTAL_4525 == gameObject.getId())
|
||||
{
|
||||
this.inHouse = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOADING)
|
||||
{
|
||||
this.inHouse = false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isHouse() {
|
||||
return this.inHouse;
|
||||
}
|
||||
|
||||
private boolean isPuroPuro() {
|
||||
Player player = client.getLocalPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return false;
|
||||
} else {
|
||||
WorldPoint location = player.getWorldLocation();
|
||||
return location.getRegionID() == PURO_PURO_REGION_ID;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.runelite.client.plugins.easy.util;
|
||||
|
||||
public enum DuelingRingMode {
|
||||
DUEL_ARENA("Duel Arena"),
|
||||
CASTLE_WARS("Castle Wars"),
|
||||
CLAN_WARS("Clan Wars");
|
||||
|
||||
private final String name;
|
||||
|
||||
DuelingRingMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.runelite.client.plugins.easy.util;
|
||||
|
||||
public enum EssenceMode {
|
||||
RUNECRAFTING("Runecrafting"),
|
||||
ESSENCE_MINING("Essence Mining");
|
||||
|
||||
private final String name;
|
||||
|
||||
EssenceMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.runelite.client.plugins.easy.util;
|
||||
|
||||
public enum GamesNecklaceMode {
|
||||
BURTHORPE("Burthorpe"),
|
||||
BARBARIAN_OUTPOST("Barbarian Outpost"),
|
||||
CORPOREAL_BEAST("Corporeal Beast"),
|
||||
TEARS_OF_GUTHIX("Tears of Guthix"),
|
||||
WINTERTODT("Wintertodt Camp");
|
||||
|
||||
private final String name;
|
||||
|
||||
GamesNecklaceMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.runelite.client.plugins.easy.util;
|
||||
|
||||
public enum GloryMode {
|
||||
EDGEVILLE("Edgeville"),
|
||||
KARAMJA("Karamja"),
|
||||
DRAYNOR_VILLAGE("Draynor Village"),
|
||||
AL_KHARID("Al Kharid");
|
||||
|
||||
private final String name;
|
||||
|
||||
GloryMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.runelite.client.plugins.easy.util;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
public class Markable {
|
||||
|
||||
@Getter
|
||||
private Player player;
|
||||
|
||||
@Getter
|
||||
private WorldPoint location;
|
||||
|
||||
@Getter
|
||||
private long frozenTime;
|
||||
|
||||
@Getter
|
||||
private long frozenUntil;
|
||||
|
||||
public Markable(Player player, WorldPoint location, long frozenTime, long frozenLength) {
|
||||
this.player = player;
|
||||
this.location = location;
|
||||
this.frozenTime = frozenTime;
|
||||
this.frozenUntil = frozenTime + frozenLength + 3000;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.runelite.client.plugins.easy.util;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
public class Swappable {
|
||||
|
||||
@Getter
|
||||
private String target;
|
||||
|
||||
@Getter
|
||||
private String optionOne;
|
||||
|
||||
@Getter
|
||||
private String optionTwo;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int indexOne;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int indexTwo;
|
||||
|
||||
public Swappable(String target, String optionOne, String optionTwo) {
|
||||
this.target = Text.removeTags(target.toLowerCase());
|
||||
this.optionOne = Text.removeTags(optionOne);
|
||||
this.optionTwo = Text.removeTags(optionTwo);
|
||||
this.indexOne = -1;
|
||||
this.indexTwo = -1;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return this.indexOne != -1 && this.indexTwo != -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package net.runelite.client.plugins.easy.util;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET;
|
||||
|
||||
public class Swapper {
|
||||
|
||||
private Set<Swappable> swapping;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private MenuEntry[] entries;
|
||||
|
||||
public Swapper() {
|
||||
this.swapping = new HashSet<>();
|
||||
}
|
||||
|
||||
public void deprioritizeWalk() {
|
||||
MenuEntry menuEntry = entries[entries.length - 1];
|
||||
menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET);
|
||||
}
|
||||
|
||||
public void removeIndex(int index) {
|
||||
entries = ArrayUtils.remove(entries, index);
|
||||
}
|
||||
|
||||
public void markForSwap(String optionA, String optionB, String target) {
|
||||
swapping.add(new Swappable(target, optionA, optionB));
|
||||
}
|
||||
|
||||
public void startSwap() {
|
||||
int index = 0;
|
||||
for (MenuEntry entry : entries) {
|
||||
String target = Text.removeTags(entry.getTarget()).toLowerCase();
|
||||
String option = Text.removeTags(entry.getOption()).toLowerCase();
|
||||
for (Swappable swap : swapping) {
|
||||
if (swap.getTarget().equalsIgnoreCase(target)) {
|
||||
if (option.equalsIgnoreCase(swap.getOptionOne())) {
|
||||
swap.setIndexOne(index);
|
||||
} else if (option.equalsIgnoreCase(swap.getOptionTwo())) {
|
||||
swap.setIndexTwo(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
for (Swappable swap : swapping) {
|
||||
if (swap.isReady()) {
|
||||
MenuEntry entry = entries[swap.getIndexOne()];
|
||||
entries[swap.getIndexOne()] = entries[swap.getIndexTwo()];
|
||||
entries[swap.getIndexTwo()] = entry;
|
||||
}
|
||||
}
|
||||
swapping.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package net.runelite.client.plugins.easy.zulrah;
|
||||
|
||||
public class EasyZulrahConfig {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package net.runelite.client.plugins.easy.zulrah;
|
||||
|
||||
public class EasyZulrahPlugin {
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||
* 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.equipmentinspector;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.plugins.grounditems.config.ItemHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.MenuHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
|
||||
|
||||
@ConfigGroup("grounditems")
|
||||
public interface EquipmentInspectorConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "ShowValue",
|
||||
name = "Show the total value of the items",
|
||||
description = "shows the total value of the items",
|
||||
position = 1
|
||||
)
|
||||
default boolean ShowValue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "protecteditems",
|
||||
name = "# of protected items",
|
||||
description = "Limit 4",
|
||||
position = 2
|
||||
)
|
||||
default int protecteditems()
|
||||
{ return 1; }
|
||||
@ConfigItem(
|
||||
keyName = "ExactValue",
|
||||
name = "Show exact value",
|
||||
description = "shows the excact gp value",
|
||||
position = 3
|
||||
)
|
||||
default boolean ExactValue()
|
||||
{ return false; }
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package net.runelite.client.plugins.equipmentinspector;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.kit.KitType;
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class EquipmentInspectorPanel extends PluginPanel
|
||||
{
|
||||
private final static String NO_PLAYER_SELECTED = "No player selected";
|
||||
|
||||
private GridBagConstraints c;
|
||||
private JPanel equipmentPanels;
|
||||
private JPanel header;
|
||||
private JLabel nameLabel;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
public EquipmentInspectorPanel()
|
||||
{
|
||||
GroupLayout layout = new GroupLayout(this);
|
||||
setLayout(layout);
|
||||
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
equipmentPanels = new JPanel(new GridBagLayout());
|
||||
c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.weightx = 1;
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
|
||||
header = new JPanel();
|
||||
header.setLayout(new BorderLayout());
|
||||
header.setBorder(new CompoundBorder(
|
||||
BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(58, 58, 58)),
|
||||
BorderFactory.createEmptyBorder(0, 0, 10, 0)));
|
||||
|
||||
nameLabel = new JLabel(NO_PLAYER_SELECTED);
|
||||
nameLabel.setForeground(Color.WHITE);
|
||||
|
||||
header.add(nameLabel, BorderLayout.CENTER);
|
||||
|
||||
layout.setHorizontalGroup(layout.createParallelGroup()
|
||||
.addComponent(equipmentPanels)
|
||||
.addComponent(header)
|
||||
);
|
||||
layout.setVerticalGroup(layout.createSequentialGroup()
|
||||
.addComponent(header)
|
||||
.addGap(10)
|
||||
.addComponent(equipmentPanels)
|
||||
);
|
||||
|
||||
update(new HashMap<>(), "");
|
||||
}
|
||||
|
||||
public void update(Map<KitType, ItemComposition> playerEquipment, String playerName)
|
||||
{
|
||||
if (playerName.isEmpty() || playerName == null)
|
||||
{
|
||||
nameLabel.setText(NO_PLAYER_SELECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
nameLabel.setText("Player: " + playerName);
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
equipmentPanels.removeAll();
|
||||
playerEquipment.forEach((kitType, itemComposition) ->
|
||||
{
|
||||
AsyncBufferedImage itemImage = itemManager.getImage(itemComposition.getId());
|
||||
equipmentPanels.add(new ItemPanel(itemComposition, kitType, itemImage), c);
|
||||
c.gridy++;
|
||||
|
||||
});
|
||||
header.revalidate();
|
||||
header.repaint();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
package net.runelite.client.plugins.equipmentinspector;
|
||||
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.PlayerMenuOptionClicked;
|
||||
import net.runelite.api.kit.KitType;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.QueuedMessage;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.item.ItemPrice;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!Equipment Inspector</font>",
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
|
||||
public class EquipmentInspectorPlugin extends Plugin {
|
||||
|
||||
private static final String INSPECT_EQUIPMENT = "Gear";
|
||||
private static final String KICK_OPTION = "Kick";
|
||||
|
||||
@Inject
|
||||
@Nullable
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private EquipmentInspectorConfig config;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
@Inject
|
||||
private MenuManager menuManager;
|
||||
|
||||
@Inject
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
@Inject
|
||||
private ClientToolbar pluginToolbar;
|
||||
|
||||
@Provides
|
||||
EquipmentInspectorConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(EquipmentInspectorConfig.class);
|
||||
}
|
||||
|
||||
private NavigationButton navButton;
|
||||
private EquipmentInspectorPanel equipmentInspectorPanel;
|
||||
private int TotalPrice = 0;
|
||||
private int Prot1 = 0;
|
||||
private int Prot2 = 0;
|
||||
private int Prot3 = 0;
|
||||
private int Prot4 = 0;
|
||||
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
|
||||
equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class);
|
||||
if(client != null) {
|
||||
menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT);
|
||||
}
|
||||
|
||||
BufferedImage icon;
|
||||
synchronized (ImageIO.class)
|
||||
{
|
||||
icon = ImageIO.read(getClass().getResourceAsStream("normal.png"));
|
||||
}
|
||||
|
||||
navButton = NavigationButton.builder()
|
||||
.tooltip("Equipment Inspector")
|
||||
.icon(icon)
|
||||
.priority(5)
|
||||
.panel(equipmentInspectorPanel)
|
||||
.build();
|
||||
|
||||
|
||||
pluginToolbar.addNavigation(navButton);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
|
||||
menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuOption().equals(INSPECT_EQUIPMENT))
|
||||
{
|
||||
|
||||
|
||||
executor.execute(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
SwingUtilities.invokeAndWait(() ->
|
||||
{
|
||||
if (!navButton.isSelected())
|
||||
{
|
||||
navButton.getOnSelect().run();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (InterruptedException | InvocationTargetException e)
|
||||
{
|
||||
|
||||
throw new RuntimeException(e);
|
||||
|
||||
}
|
||||
String playerName = Text.removeTags(event.getMenuTarget());
|
||||
// The player menu uses a non-breaking space in the player name, we need to replace this to compare
|
||||
// against the playerName in the player cache.
|
||||
String finalPlayerName = playerName.replace('\u00A0', ' ');
|
||||
System.out.println(finalPlayerName);
|
||||
List<Player> players = client.getPlayers();
|
||||
Optional<Player> targetPlayer = players.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(p -> p.getName().equals(finalPlayerName)).findFirst();
|
||||
|
||||
if (targetPlayer.isPresent())
|
||||
{
|
||||
TotalPrice = 0;
|
||||
Prot1 = 0;
|
||||
Prot2 = 0;
|
||||
Prot3 = 0;
|
||||
Prot4 = 0;
|
||||
Player p = targetPlayer.get();
|
||||
Map<KitType, ItemComposition> playerEquipment = new HashMap<>();
|
||||
|
||||
for (KitType kitType : KitType.values())
|
||||
{
|
||||
int itemId = p.getPlayerComposition().getEquipmentId(kitType);
|
||||
if (itemId != -1)
|
||||
{
|
||||
ItemComposition itemComposition = client.getItemDefinition(itemId);
|
||||
playerEquipment.put(kitType, itemComposition);
|
||||
int ItemPrice = itemManager.getItemPrice(itemId);
|
||||
TotalPrice += ItemPrice;
|
||||
if (ItemPrice > Prot1 ) {
|
||||
Prot4 = Prot3;
|
||||
Prot3 = Prot2;
|
||||
Prot2 = Prot1;
|
||||
|
||||
Prot1 = ItemPrice;
|
||||
} else if (ItemPrice > Prot2){
|
||||
Prot4 = Prot3;
|
||||
Prot3 = Prot2;
|
||||
Prot2 = ItemPrice;
|
||||
} else if (ItemPrice > Prot3){
|
||||
Prot4 = Prot3;
|
||||
Prot3 = ItemPrice;
|
||||
} else if (ItemPrice > Prot4){
|
||||
Prot4 = ItemPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
int IgnoredItems = config.protecteditems();
|
||||
if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) {
|
||||
IgnoredItems = 4;
|
||||
|
||||
}
|
||||
if (config.ShowValue()) {
|
||||
switch (IgnoredItems) {
|
||||
case 1:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
break;
|
||||
case 2:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
TotalPrice = TotalPrice - Prot2;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
TotalPrice = TotalPrice - Prot2;
|
||||
TotalPrice = TotalPrice - Prot3;
|
||||
break;
|
||||
case 4:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
TotalPrice = TotalPrice - Prot2;
|
||||
TotalPrice = TotalPrice - Prot3;
|
||||
TotalPrice = TotalPrice - Prot4;
|
||||
break;
|
||||
}
|
||||
String StringPrice = "";
|
||||
if (!config.ExactValue()) {
|
||||
TotalPrice = TotalPrice / 1000;
|
||||
StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice);
|
||||
StringPrice = StringPrice + 'K';
|
||||
}
|
||||
if (config.ExactValue()) {
|
||||
StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice);
|
||||
}
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Risked Value: ")
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(StringPrice)
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
equipmentInspectorPanel.update(playerEquipment, playerName);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.runelite.client.plugins.equipmentinspector;
|
||||
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.kit.KitType;
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
class ItemPanel extends JPanel
|
||||
{
|
||||
|
||||
ItemPanel(ItemComposition item, KitType kitType, AsyncBufferedImage icon)
|
||||
{
|
||||
setBorder(new EmptyBorder(3, 3, 3, 3));
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
GroupLayout layout = new GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
|
||||
JLabel name = new JLabel(item.getName());
|
||||
|
||||
JLabel location = new JLabel(StringUtils.capitalize(kitType.toString().toLowerCase()));
|
||||
location.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel imageLabel = new JLabel();
|
||||
icon.addTo(imageLabel);
|
||||
|
||||
layout.setVerticalGroup(layout.createParallelGroup()
|
||||
.addComponent(imageLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
);
|
||||
|
||||
layout.setHorizontalGroup(layout.createSequentialGroup()
|
||||
.addComponent(imageLabel)
|
||||
.addGap(8)
|
||||
.addGroup(layout.createParallelGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
);
|
||||
|
||||
// AWT's Z order is weird. This put image at the back of the stack
|
||||
setComponentZOrder(imageLabel, getComponentCount() - 1);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 624 B |
@@ -0,0 +1,63 @@
|
||||
package net.runelite.client.plugins.fightcavejadhelper;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class FightCaveJadHelperOverlay extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
|
||||
private final Client client;
|
||||
private final FightCaveJadHelperPlugin plugin;
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private FightCaveJadHelperOverlay(Client client, FightCaveJadHelperPlugin plugin, SpriteManager spriteManager)
|
||||
{
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.spriteManager = spriteManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final JadAttack attack = plugin.getAttack();
|
||||
|
||||
if (attack == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final BufferedImage prayerImage = getPrayerImage(attack);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer())
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(JadAttack attack)
|
||||
{
|
||||
final int prayerSpriteID = attack == JadAttack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES;
|
||||
return spriteManager.getSprite(prayerSpriteID, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package net.runelite.client.plugins.fightcavejadhelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"#4863A0\">!Fight Cave - Jad</font>",
|
||||
description = "Show what to pray against Jad",
|
||||
tags = {"bosses", "combat", "minigame", "overlay", "prayer", "pve", "pvm"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class FightCaveJadHelperPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private FightCaveJadHelperOverlay overlay;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Nullable
|
||||
private JadAttack attack;
|
||||
|
||||
private NPC jad;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(final NpcSpawned event)
|
||||
{
|
||||
final int id = event.getNpc().getId();
|
||||
|
||||
if (id == NpcID.TZTOKJAD || id == NpcID.TZTOKJAD_6506)
|
||||
{
|
||||
jad = event.getNpc();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(final NpcDespawned event)
|
||||
{
|
||||
if (jad == event.getNpc())
|
||||
{
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(final AnimationChanged event)
|
||||
{
|
||||
if (event.getActor() != jad)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (jad.getAnimation() == JadAttack.MAGIC.getAnimation())
|
||||
{
|
||||
attack = JadAttack.MAGIC;
|
||||
}
|
||||
else if (jad.getAnimation() == JadAttack.RANGE.getAnimation())
|
||||
{
|
||||
attack = JadAttack.RANGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.runelite.client.plugins.fightcavejadhelper;
|
||||
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Prayer;
|
||||
|
||||
public enum JadAttack
|
||||
{
|
||||
MAGIC(AnimationID.TZTOK_JAD_MAGIC_ATTACK, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE(AnimationID.TZTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES);
|
||||
|
||||
private final int animation;
|
||||
private final Prayer prayer;
|
||||
|
||||
JadAttack(int animation, Prayer prayer)
|
||||
{
|
||||
this.animation = animation;
|
||||
this.prayer = prayer;
|
||||
}
|
||||
|
||||
public int getAnimation()
|
||||
{
|
||||
return animation;
|
||||
}
|
||||
|
||||
public Prayer getPrayer()
|
||||
{
|
||||
return prayer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* 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.fightcavewavehelper;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("Fight Cave - Wave Helper")
|
||||
public interface FightCaveWaveHelperConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "waveDisplay",
|
||||
name = "Wave display",
|
||||
description = "Shows monsters that will spawn on the selected wave(s)."
|
||||
)
|
||||
default WaveDisplayMode waveDisplay()
|
||||
{
|
||||
return WaveDisplayMode.BOTH;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* 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.fightcavewavehelper;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"#4863A0\">!Fight Cave - Waves</font>",
|
||||
description = "Displays current and upcoming wave monsters in the Fight Caves",
|
||||
tags = {"bosses", "combat", "minigame", "overlay", "pve", "pvm", "jad", "fire", "cape", "wave"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class FightCaveWaveHelperPlugin extends Plugin
|
||||
{
|
||||
private static final Pattern WAVE_PATTERN = Pattern.compile(".*Wave: (\\d+).*");
|
||||
private static final int FIGHT_CAVE_REGION = 9551;
|
||||
private static final int MAX_MONSTERS_OF_TYPE_PER_WAVE = 2;
|
||||
|
||||
static final int MAX_WAVE = 63;
|
||||
|
||||
@Getter
|
||||
static final List<EnumMap<WaveMonster, Integer>> WAVES = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private int currentWave = -1;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private WaveOverlay waveOverlay;
|
||||
|
||||
static
|
||||
{
|
||||
final WaveMonster[] waveMonsters = WaveMonster.values();
|
||||
|
||||
// Add wave 1, future waves are derived from its contents
|
||||
final EnumMap<WaveMonster, Integer> waveOne = new EnumMap<>(WaveMonster.class);
|
||||
waveOne.put(waveMonsters[0], 1);
|
||||
WAVES.add(waveOne);
|
||||
|
||||
for (int wave = 1; wave < MAX_WAVE; wave++)
|
||||
{
|
||||
final EnumMap<WaveMonster, Integer> prevWave = WAVES.get(wave - 1).clone();
|
||||
int maxMonsterOrdinal = -1;
|
||||
|
||||
for (int i = 0; i < waveMonsters.length; i++)
|
||||
{
|
||||
final int ordinalMonsterQuantity = prevWave.getOrDefault(waveMonsters[i], 0);
|
||||
|
||||
if (ordinalMonsterQuantity == MAX_MONSTERS_OF_TYPE_PER_WAVE)
|
||||
{
|
||||
maxMonsterOrdinal = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxMonsterOrdinal >= 0)
|
||||
{
|
||||
prevWave.remove(waveMonsters[maxMonsterOrdinal]);
|
||||
}
|
||||
|
||||
final int addedMonsterOrdinal = maxMonsterOrdinal >= 0 ? maxMonsterOrdinal + 1 : 0;
|
||||
final WaveMonster addedMonster = waveMonsters[addedMonsterOrdinal];
|
||||
final int addedMonsterQuantity = prevWave.getOrDefault(addedMonster, 0);
|
||||
|
||||
prevWave.put(addedMonster, addedMonsterQuantity + 1);
|
||||
|
||||
WAVES.add(prevWave);
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
FightCaveWaveHelperConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(FightCaveWaveHelperConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
overlayManager.add(waveOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
overlayManager.remove(waveOverlay);
|
||||
currentWave = -1;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inFightCave())
|
||||
{
|
||||
currentWave = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage());
|
||||
|
||||
if (event.getType() != ChatMessageType.GAMEMESSAGE
|
||||
|| !inFightCave()
|
||||
|| !waveMatcher.matches())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentWave = Integer.parseInt(waveMatcher.group(1));
|
||||
}
|
||||
|
||||
boolean inFightCave()
|
||||
{
|
||||
return ArrayUtils.contains(client.getMapRegions(), FIGHT_CAVE_REGION);
|
||||
}
|
||||
|
||||
static String formatMonsterQuantity(final WaveMonster monster, final int quantity)
|
||||
{
|
||||
return String.format("%dx %s", quantity, monster);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* 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.fightcavewavehelper;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum WaveDisplayMode
|
||||
{
|
||||
CURRENT("Current wave"),
|
||||
NEXT("Next wave"),
|
||||
BOTH("Both");
|
||||
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* 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.fightcavewavehelper;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
enum WaveMonster
|
||||
{
|
||||
TZ_KIH("Tz-Kih", 22),
|
||||
TZ_KEK("Tz-Kek", 45),
|
||||
TOK_XIL("Tok-Xil", 90),
|
||||
YT_MEJKOT("Yt-MejKot", 180),
|
||||
KET_ZEK("Ket-Zek", 360),
|
||||
TZKOK_JAD("TzTok-Jad", 702);
|
||||
|
||||
private final String name;
|
||||
private final int level;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s - Level %s", name, level);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* 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.fightcavewavehelper;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
class WaveOverlay extends Overlay
|
||||
{
|
||||
private static final Color HEADER_COLOR = ColorScheme.BRAND_ORANGE;
|
||||
|
||||
private final FightCaveWaveHelperConfig config;
|
||||
private final FightCaveWaveHelperPlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private WaveOverlay(FightCaveWaveHelperConfig config, FightCaveWaveHelperPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.TOP_RIGHT);
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.inFightCave()
|
||||
|| plugin.getCurrentWave() < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
final int currentWave = plugin.getCurrentWave();
|
||||
final int waveIndex = currentWave - 1;
|
||||
|
||||
if (config.waveDisplay() == WaveDisplayMode.CURRENT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex);
|
||||
|
||||
addWaveInfo("Wave " + plugin.getCurrentWave(), waveContents);
|
||||
}
|
||||
|
||||
if ((config.waveDisplay() == WaveDisplayMode.NEXT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
&& currentWave != FightCaveWaveHelperPlugin.MAX_WAVE)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex + 1);
|
||||
|
||||
addWaveInfo("Next wave", waveContents);
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private void addWaveInfo(final String headerText, final Map<WaveMonster, Integer> waveContents)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(headerText)
|
||||
.color(HEADER_COLOR)
|
||||
.build());
|
||||
|
||||
for (LineComponent line : buildWaveLines(waveContents))
|
||||
{
|
||||
panelComponent.getChildren().add(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<LineComponent> buildWaveLines(final Map<WaveMonster, Integer> wave)
|
||||
{
|
||||
final List<Map.Entry<WaveMonster, Integer>> monsters = new ArrayList<>(wave.entrySet());
|
||||
monsters.sort(Map.Entry.comparingByKey());
|
||||
final List<LineComponent> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<WaveMonster, Integer> monsterEntry : monsters)
|
||||
{
|
||||
final WaveMonster monster = monsterEntry.getKey();
|
||||
final int quantity = monsterEntry.getValue();
|
||||
final LineComponent line = LineComponent.builder()
|
||||
.left(FightCaveWaveHelperPlugin.formatMonsterQuantity(monster, quantity))
|
||||
.build();
|
||||
|
||||
outputLines.add(line);
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.client.plugins.freezetimers.Spell;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
public class Barrage
|
||||
extends Spell {
|
||||
public static final long DURATION = 20000L;
|
||||
private long remainingTime;
|
||||
private boolean isFinished;
|
||||
|
||||
public Barrage(Actor affectedTarget, Actor caster) {
|
||||
super(affectedTarget, caster);
|
||||
}
|
||||
|
||||
public long getRemainingTime() {
|
||||
long elapsedTime = System.currentTimeMillis() - this.startTime;
|
||||
if (Barrage.getDURATION() > elapsedTime) {
|
||||
return Barrage.getDURATION() - elapsedTime;
|
||||
}
|
||||
this.isFinished = true;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Barrage) {
|
||||
Barrage barrage = (Barrage)o;
|
||||
return Text.standardize(this.getAffectedTarget().getName()).equals(Text.standardize(((Barrage)o).getAffectedTarget().getName())) && this.getStartTime() == ((Barrage)o).getStartTime();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long getDURATION() {
|
||||
return 20000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return this.isFinished;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup(value="freezetimers")
|
||||
public interface FreezeTimersConfig
|
||||
extends Config {
|
||||
@ConfigItem(position=0, keyName="freezeenable", name="Enable PvP freeze timers", description="Configures whether or not to show freeze timers.")
|
||||
default public boolean EnableFreezeTimers() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(position=1, keyName="tilehighlight", name="Frozen opponent tile highlighting", description="Configures whether or not to highlight tiles frozen opponents are standing on.")
|
||||
default public boolean drawTiles() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(position=2, keyName="timercolor", name="Freeze Timer Color", description="Color of freeze timer")
|
||||
default public Color FreezeTimerColor() {
|
||||
return new Color(0, 184, 212);
|
||||
}
|
||||
|
||||
@ConfigItem(position=3, keyName="spellIcon", name="Show spell icon", description="Shows the spell icon for the freeze spell affecting the target")
|
||||
default public boolean spellIcon() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(position=4, keyName="refreezeTimer", name="Refreeze Timer", description="Show a timer that counts up until the target can be refrozen")
|
||||
default public boolean refreezeTimer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(position=5, keyName="refreezeTimerColor", name="Refreeze color", description="The color for the timer that counts until the target can be refrozen")
|
||||
default public Color RefreezeTimerColor() {
|
||||
return Color.red;
|
||||
}
|
||||
|
||||
@ConfigItem(position = 6, keyName = "tbtimer", name = "Tele Block Timer", description = "Enables tele block timer")
|
||||
default boolean TBTimer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(position = 7, keyName = "timerpos", name = "Freeze Timer Position", description = "Position of freeze timer")
|
||||
default int FreezeTimerPos() {
|
||||
return 80;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersService;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class FreezeTimersOverlay
|
||||
extends Overlay {
|
||||
private final FreezeTimersService FreezeTimersService;
|
||||
private final FreezeTimersConfig config;
|
||||
private final FreezeTimersPlugin plugin;
|
||||
private final SpriteManager spriteManager;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
private FreezeTimersOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2, FreezeTimersPlugin plugin, Client client, SpriteManager spriteManager) {
|
||||
this.config = config;
|
||||
this.FreezeTimersService = FreezeTimersService2;
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
this.spriteManager = spriteManager;
|
||||
this.setPosition(OverlayPosition.DYNAMIC);
|
||||
this.setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!this.config.EnableFreezeTimers()) {
|
||||
return null;
|
||||
}
|
||||
this.FreezeTimersService.forEachPlayer((player, color) -> this.renderPlayerOverlay(graphics, (Player)player, (Color)color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) {
|
||||
BufferedImage clanchatImage;
|
||||
int timer = 0;
|
||||
String name = actor.getName();
|
||||
int freezetype = this.plugin.freezetype(name);
|
||||
boolean frozenoverlay = false;
|
||||
int offset = 5;
|
||||
long dtime = this.plugin.opponentfreezetime(name);
|
||||
long tbed = plugin.istbed(name);
|
||||
Point textLocation = null;
|
||||
HeadIcon headIcon = actor.getOverheadIcon();
|
||||
int freezetime = 0;
|
||||
if (freezetype == 1 || freezetype == 4) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 2 || freezetype == 5) {
|
||||
freezetime = 10000;
|
||||
} else if (freezetype == 3 || freezetype == 6) {
|
||||
freezetime = 15000;
|
||||
} else if (freezetype == 7) {
|
||||
freezetime = 20000;
|
||||
} else if (freezetype == 8) {
|
||||
freezetime = 2500;
|
||||
} else if (freezetype == 9) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 10) {
|
||||
freezetime = 7500;
|
||||
}
|
||||
long currenttime = System.currentTimeMillis();
|
||||
long timediff = currenttime - dtime;
|
||||
timer = (freezetime - (int)timediff) / 1000;
|
||||
if (timediff < (long)freezetime) {
|
||||
textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos());
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
} else if (timediff < (long)(freezetime + 3000)) {
|
||||
timer = Math.abs(timer);
|
||||
++timer;
|
||||
if (this.config.refreezeTimer()) {
|
||||
textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos());
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
if (headIcon != null) {
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
}
|
||||
frozenoverlay = true;
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), this.config.RefreezeTimerColor());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.plugin.deleteopponent(name);
|
||||
}
|
||||
if (textLocation != null && (clanchatImage = this.plugin.GetFreezeIcon(freezetype - 1)) != null) {
|
||||
int width = clanchatImage.getWidth();
|
||||
int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent();
|
||||
Point imageLocation = new Point(textLocation.getX(), textLocation.getY() - (config.FreezeTimerPos() / 2));
|
||||
graphics.setFont(FontManager.getRunescapeFont());
|
||||
graphics.setStroke(new BasicStroke(3.0f));
|
||||
if (this.config.spellIcon()) {
|
||||
frozenoverlay = true;
|
||||
graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), clanchatImage.getHeight());
|
||||
OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage);
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color);
|
||||
} else {
|
||||
graphics.setColor(Color.cyan);
|
||||
graphics.drawOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight());
|
||||
graphics.setColor(Color.blue);
|
||||
graphics.fillOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight());
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.TBTimer()) {
|
||||
if (tbed > 0) {
|
||||
int type = plugin.tbtype(name);
|
||||
int tbexpiry;
|
||||
if (type > 0) {
|
||||
if (type == 1) {
|
||||
tbexpiry = 300000;
|
||||
} else if (type == 2) {
|
||||
tbexpiry = 150000;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
long tbtime = currenttime - tbed;
|
||||
int tbtimer = (tbexpiry - (int) tbtime) / 1000;
|
||||
if (tbtime < tbexpiry) {
|
||||
textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos());
|
||||
if (frozenoverlay) {
|
||||
textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos());
|
||||
} else {
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
}
|
||||
} else {
|
||||
plugin.deletetb(name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,402 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.freezetimers.Barrage;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersOverlay;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersTileOverlay;
|
||||
import net.runelite.client.plugins.freezetimers.Spell;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"aqua\">!Freeze Timers</font>",
|
||||
description = "PVP Freeze Timers",
|
||||
tags = {"PvP", "Freeze", "Timers"}
|
||||
)
|
||||
|
||||
public class FreezeTimersPlugin
|
||||
extends Plugin {
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
@Inject
|
||||
private FreezeTimersConfig config;
|
||||
@Inject
|
||||
private FreezeTimersOverlay FreezeTimersOverlay;
|
||||
@Inject
|
||||
private FreezeTimersTileOverlay FreezeTimersTileOverlay;
|
||||
@Inject
|
||||
private Client client;
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
private static final int[] FREEZE_ICONS = {
|
||||
SpriteID.SPELL_BIND,
|
||||
SpriteID.SPELL_SNARE,
|
||||
SpriteID.SPELL_ENTANGLE,
|
||||
SpriteID.SPELL_ICE_RUSH,
|
||||
SpriteID.SPELL_ICE_BURST,
|
||||
SpriteID.SPELL_ICE_BLITZ,
|
||||
SpriteID.SPELL_ICE_BARRAGE,
|
||||
SpriteID.SPELL_BIND,
|
||||
SpriteID.SPELL_SNARE,
|
||||
SpriteID.SPELL_ENTANGLE,
|
||||
SpriteID.SPELL_TELE_BLOCK
|
||||
};
|
||||
private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(25, 25);
|
||||
private static final Color FREEZE_ICON_OUTLINE_COLOR = new Color(33, 33, 33);
|
||||
private final BufferedImage[] FreezeIcons = new BufferedImage[FREEZE_ICONS.length];
|
||||
private final int SPLASH_ID = 85;
|
||||
Map<String, Long> tbedthings = new HashMap<>();
|
||||
Map<String, Integer> tbtypes = new HashMap<>();
|
||||
Map<String, Spell> testMap = new HashMap<String, Spell>();
|
||||
Map<String, Long> frozenthings = new HashMap<String, Long>();
|
||||
Map<String, WorldPoint> frozenthingpoints = new HashMap<String, WorldPoint>();
|
||||
Map<String, Integer> freezetype = new HashMap<String, Integer>();
|
||||
Map<Integer, Integer> magexp = new HashMap<Integer, Integer>();
|
||||
int lastxp;
|
||||
int ticks;
|
||||
int currticks;
|
||||
String currtarget;
|
||||
String spell;
|
||||
|
||||
@Provides
|
||||
FreezeTimersConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(FreezeTimersConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged) {
|
||||
if (gameStateChanged.getGameState() == GameState.LOGGED_IN) {
|
||||
this.loadFreezeIcons();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
this.overlayManager.add(this.FreezeTimersOverlay);
|
||||
this.overlayManager.add(this.FreezeTimersTileOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
this.overlayManager.remove(this.FreezeTimersOverlay);
|
||||
this.overlayManager.remove(this.FreezeTimersTileOverlay);
|
||||
this.frozenthings.clear();
|
||||
this.frozenthingpoints.clear();
|
||||
this.tbedthings.clear();
|
||||
this.tbtypes.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event) {
|
||||
if (event.getMenuTarget().contains("->")) {
|
||||
Pattern spattern = Pattern.compile(">(.+?)</col>");
|
||||
Pattern ppattern = Pattern.compile("> <col=ffffff>(.+?)<col=");
|
||||
Matcher smatch = spattern.matcher(event.getMenuTarget());
|
||||
Matcher pmatch = ppattern.matcher(event.getMenuTarget());
|
||||
smatch.find();
|
||||
pmatch.find();
|
||||
if (smatch.group(1) != null && pmatch.group(1) != null) {
|
||||
this.currticks = this.ticks;
|
||||
this.spell = smatch.group(1);
|
||||
this.currtarget = pmatch.group(1).replace("\u00a0", " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onExperienceChanged(ExperienceChanged event) {
|
||||
if (event.getSkill() == Skill.MAGIC) {
|
||||
int xp = this.client.getSkillExperience(Skill.MAGIC);
|
||||
int gains = xp - this.lastxp;
|
||||
this.lastxp = xp;
|
||||
if (!this.magexp.containsKey(this.ticks)) {
|
||||
this.magexp.clear();
|
||||
this.magexp.put(this.ticks, gains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onAnimationChanged(AnimationChanged event) {
|
||||
Logger l = this.client.getLogger();
|
||||
Actor subject = event.getActor();
|
||||
Actor target = subject.getInteracting();
|
||||
if (subject.getAnimation() == 1979) {
|
||||
try {
|
||||
if (target.getGraphic() == 85 || target.getGraphic() != -1) {
|
||||
return;
|
||||
}
|
||||
if (this.frozenthings.containsKey(target.getName())) {
|
||||
return;
|
||||
}
|
||||
this.testMap.put(target.getName(), new Barrage(target, subject));
|
||||
this.freezetype.put(target.getName(), 7);
|
||||
this.frozenthings.put(target.getName(), System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(target.getName(), target.getWorldLocation());
|
||||
}
|
||||
catch (NullPointerException nullPointerException) {
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event) {
|
||||
int xp = 0;
|
||||
boolean praymage = false;
|
||||
if (this.magexp.containsKey(this.ticks)) {
|
||||
xp = this.magexp.get(this.ticks);
|
||||
}
|
||||
if (xp > 0 && this.currtarget != null) {
|
||||
if (this.frozenthings.containsKey(this.currtarget)) {
|
||||
this.currtarget = null;
|
||||
return;
|
||||
}
|
||||
WorldPoint targetPosition = null;
|
||||
for (Player player : this.client.getPlayers()) {
|
||||
String playerName;
|
||||
if (player == null || !(playerName = player.getName()).equals(this.currtarget)) continue;
|
||||
if (player.getOverheadIcon() != null && player.getOverheadIcon().equals((Object)HeadIcon.MAGIC)) {
|
||||
praymage = true;
|
||||
}
|
||||
targetPosition = player.getWorldLocation();
|
||||
break;
|
||||
}
|
||||
if (targetPosition != null) {
|
||||
if (this.spell.equals("Bind") && xp > 30) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
if (praymage) {
|
||||
this.freezetype.put(this.currtarget, 8);
|
||||
} else {
|
||||
this.freezetype.put(this.currtarget, 1);
|
||||
}
|
||||
} else if (this.spell.equals("Snare") && xp > 60) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
if (praymage) {
|
||||
this.freezetype.put(this.currtarget, 9);
|
||||
} else {
|
||||
this.freezetype.put(this.currtarget, 2);
|
||||
}
|
||||
} else if (this.spell.equals("Entangle") && xp >= 89) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
if (praymage) {
|
||||
this.freezetype.put(this.currtarget, 10);
|
||||
} else {
|
||||
this.freezetype.put(this.currtarget, 3);
|
||||
}
|
||||
} else if (this.spell.equals("Ice Rush") && xp > 34) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 4);
|
||||
} else if (this.spell.equals("Ice Burst") && xp > 40) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 5);
|
||||
} else if (this.spell.equals("Ice Blitz") && xp > 46) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 6);
|
||||
} else if (this.spell.equals("Ice Barrage") && xp > 52) {
|
||||
Barrage barrage = new Barrage(this.client.getLocalPlayer().getInteracting(), this.client.getLocalPlayer());
|
||||
this.testMap.put(this.currtarget, barrage);
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 7);
|
||||
} else if (spell.equals("Tele Block") && xp == 95) {
|
||||
if (config.TBTimer()) {
|
||||
if (praymage) {
|
||||
this.tbtypes.put(this.currtarget, 2);
|
||||
} else {
|
||||
this.tbtypes.put(this.currtarget, 1);
|
||||
}
|
||||
this.tbedthings.put(this.currtarget, System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.currtarget != null && this.ticks > this.currticks + 1) {
|
||||
Player local = this.client.getLocalPlayer();
|
||||
Actor interacting = local.getInteracting();
|
||||
if (interacting != null) {
|
||||
if (!interacting.getName().equals(this.currtarget)) {
|
||||
this.currtarget = null;
|
||||
}
|
||||
} else {
|
||||
this.currtarget = null;
|
||||
}
|
||||
}
|
||||
++this.ticks;
|
||||
}
|
||||
|
||||
public long opponentfreezetime(String name) {
|
||||
if (this.frozenthings.containsKey(name)) {
|
||||
return this.frozenthings.get(name);
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public WorldPoint playerpos(String name) {
|
||||
if (this.frozenthingpoints.containsKey(name)) {
|
||||
return this.frozenthingpoints.get(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updatePosition(String name, WorldPoint point) {
|
||||
if (this.frozenthingpoints.containsKey(name)) {
|
||||
this.frozenthingpoints.remove(name);
|
||||
this.frozenthingpoints.put(name, point);
|
||||
}
|
||||
}
|
||||
|
||||
public int freezetype(String name) {
|
||||
if (this.freezetype.containsKey(name)) {
|
||||
return this.freezetype.get(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public long istbed(String name) {
|
||||
if (this.tbedthings.containsKey(name)) {
|
||||
return this.tbedthings.get(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public int tbtype(String name) {
|
||||
if (this.tbtypes.containsKey(name)) {
|
||||
return this.tbtypes.get(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public void deleteopponent(String name) {
|
||||
if (this.frozenthings.containsKey(name)) {
|
||||
this.frozenthings.remove(name);
|
||||
}
|
||||
if (this.frozenthingpoints.containsKey(name)) {
|
||||
this.frozenthingpoints.remove(name);
|
||||
}
|
||||
if (this.freezetype.containsKey(name)) {
|
||||
this.freezetype.remove(name);
|
||||
}
|
||||
}
|
||||
public void deletetb(String name) {
|
||||
if (this.tbedthings.containsKey(name)) {
|
||||
this.tbedthings.remove(name);
|
||||
}
|
||||
if (this.tbtypes.containsKey(name)) {
|
||||
this.tbtypes.remove(name);
|
||||
}
|
||||
}
|
||||
private void loadFreezeIcons() {
|
||||
IndexedSprite[] freezeIcons = new IndexedSprite[]{};
|
||||
IndexedSprite[] newfreezeIcons = Arrays.copyOf(freezeIcons, FREEZE_ICONS.length);
|
||||
int curPosition = 0;
|
||||
int i = 0;
|
||||
while (i < FREEZE_ICONS.length) {
|
||||
int resource = FREEZE_ICONS[i];
|
||||
this.FreezeIcons[i] = FreezeTimersPlugin.rgbaToIndexedBufferedImage(FreezeTimersPlugin.FreezeIconFromSprite(this.spriteManager.getSprite(resource, 0)));
|
||||
newfreezeIcons[curPosition] = FreezeTimersPlugin.createIndexedSprite(this.client, this.FreezeIcons[i]);
|
||||
++i;
|
||||
++curPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private static IndexedSprite createIndexedSprite(Client client, BufferedImage bufferedImage) {
|
||||
IndexColorModel indexedCM = (IndexColorModel)bufferedImage.getColorModel();
|
||||
int width = bufferedImage.getWidth();
|
||||
int height = bufferedImage.getHeight();
|
||||
byte[] pixels = ((DataBufferByte)bufferedImage.getRaster().getDataBuffer()).getData();
|
||||
int[] palette = new int[indexedCM.getMapSize()];
|
||||
indexedCM.getRGBs(palette);
|
||||
IndexedSprite newIndexedSprite = client.createIndexedSprite();
|
||||
newIndexedSprite.setPixels(pixels);
|
||||
newIndexedSprite.setPalette(palette);
|
||||
newIndexedSprite.setWidth(width);
|
||||
newIndexedSprite.setHeight(height);
|
||||
newIndexedSprite.setOriginalWidth(width);
|
||||
newIndexedSprite.setOriginalHeight(height);
|
||||
newIndexedSprite.setOffsetX(0);
|
||||
newIndexedSprite.setOffsetY(0);
|
||||
return newIndexedSprite;
|
||||
}
|
||||
|
||||
private static BufferedImage rgbaToIndexedBufferedImage(BufferedImage sourceBufferedImage) {
|
||||
BufferedImage indexedImage = new BufferedImage(sourceBufferedImage.getWidth(), sourceBufferedImage.getHeight(), 13);
|
||||
ColorModel cm = indexedImage.getColorModel();
|
||||
IndexColorModel icm = (IndexColorModel)cm;
|
||||
int size = icm.getMapSize();
|
||||
byte[] reds = new byte[size];
|
||||
byte[] greens = new byte[size];
|
||||
byte[] blues = new byte[size];
|
||||
icm.getReds(reds);
|
||||
icm.getGreens(greens);
|
||||
icm.getBlues(blues);
|
||||
WritableRaster raster = indexedImage.getRaster();
|
||||
int pixel = raster.getSample(0, 0, 0);
|
||||
IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel);
|
||||
BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null);
|
||||
resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null);
|
||||
return resultIndexedImage;
|
||||
}
|
||||
|
||||
private static BufferedImage FreezeIconFromSprite(BufferedImage freezeSprite) {
|
||||
BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.width, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.height);
|
||||
return ImageUtil.outlineImage(freezeCanvas, FREEZE_ICON_OUTLINE_COLOR);
|
||||
}
|
||||
|
||||
BufferedImage GetFreezeIcon(int id) {
|
||||
return this.FreezeIcons[id];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin;
|
||||
|
||||
@Singleton
|
||||
public class FreezeTimersService {
|
||||
private final Client client;
|
||||
private final FreezeTimersConfig config;
|
||||
private final FreezeTimersPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private FreezeTimersService(Client client, FreezeTimersConfig config, FreezeTimersPlugin plugin) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void forEachPlayer(BiConsumer<Player, Color> consumer) {
|
||||
for (Player player : this.client.getPlayers()) {
|
||||
if (player == null || player.getName() == null) continue;
|
||||
String name = player.getName();
|
||||
int freezetype = this.plugin.freezetype(name);
|
||||
long tbed = plugin.istbed(name);
|
||||
long dtime = this.plugin.opponentfreezetime(name);
|
||||
int freezetime = 0;
|
||||
if (freezetype == 1 || freezetype == 4) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 2 || freezetype == 5) {
|
||||
freezetime = 10000;
|
||||
} else if (freezetype == 3 || freezetype == 6) {
|
||||
freezetime = 15000;
|
||||
} else if (freezetype == 7) {
|
||||
freezetime = 20000;
|
||||
} else if (freezetype == 8) {
|
||||
freezetime = 2500;
|
||||
} else if (freezetype == 9) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 10) {
|
||||
freezetime = 7500;
|
||||
}
|
||||
if (dtime <= 0L) continue;
|
||||
long currenttime = System.currentTimeMillis();
|
||||
long timediff = currenttime - dtime;
|
||||
if (timediff < (long)freezetime) {
|
||||
WorldPoint lastWorldPoint;
|
||||
WorldPoint currentWorldPoint = player.getWorldLocation();
|
||||
if (currentWorldPoint.equals(lastWorldPoint = this.plugin.playerpos(name))) {
|
||||
consumer.accept(player, this.config.FreezeTimerColor());
|
||||
continue;
|
||||
}
|
||||
if (timediff < 605L) {
|
||||
this.plugin.updatePosition(name, currentWorldPoint);
|
||||
consumer.accept(player, this.config.FreezeTimerColor());
|
||||
continue;
|
||||
}
|
||||
this.plugin.deleteopponent(name);
|
||||
continue;
|
||||
}
|
||||
if (timediff < (long)(freezetime + 3000)) {
|
||||
consumer.accept(player, Color.YELLOW);
|
||||
continue;
|
||||
} else {
|
||||
this.plugin.deleteopponent(name);
|
||||
}
|
||||
if (tbed > 0) {
|
||||
consumer.accept(player, config.FreezeTimerColor());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersService;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class FreezeTimersTileOverlay
|
||||
extends Overlay {
|
||||
private final FreezeTimersService FreezeTimersService;
|
||||
private final FreezeTimersConfig config;
|
||||
|
||||
@Inject
|
||||
private FreezeTimersTileOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2) {
|
||||
this.config = config;
|
||||
this.FreezeTimersService = FreezeTimersService2;
|
||||
this.setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.setPosition(OverlayPosition.DYNAMIC);
|
||||
this.setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!this.config.drawTiles()) {
|
||||
return null;
|
||||
}
|
||||
this.FreezeTimersService.forEachPlayer((player, color) -> {
|
||||
Polygon poly = player.getCanvasTilePoly();
|
||||
if (poly != null) {
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
public enum PlayerSpellEffect {
|
||||
BARRAGE("Ice Barrage", 20000, false),
|
||||
BLITZ("Ice Blitz", 15000, false);
|
||||
|
||||
private final String SPELL_NAME;
|
||||
private long startTime;
|
||||
private int duration;
|
||||
private boolean halvable;
|
||||
|
||||
private PlayerSpellEffect(String name, int duration, boolean halvable) {
|
||||
this.SPELL_NAME = name;
|
||||
this.duration = duration;
|
||||
this.halvable = halvable;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public String getSPELL_NAME() {
|
||||
return this.SPELL_NAME;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return this.startTime;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public boolean isHalvable() {
|
||||
return this.halvable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
|
||||
public abstract class Spell {
|
||||
private final Actor affectedTarget;
|
||||
private final Actor caster;
|
||||
public final long startTime;
|
||||
private long remainingTime;
|
||||
private boolean isFinished;
|
||||
|
||||
protected Spell(Actor affectedTarget, Actor caster) {
|
||||
this.affectedTarget = affectedTarget;
|
||||
this.caster = caster;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public Actor getAffectedTarget() {
|
||||
return this.affectedTarget;
|
||||
}
|
||||
|
||||
public Actor getCaster() {
|
||||
return this.caster;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return this.startTime;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.isFinished;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
package net.runelite.client.plugins.friendtagging;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import javax.inject.Inject;
|
||||
import lombok.NonNull;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Friend;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Nameable;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.NameableNameChanged;
|
||||
import net.runelite.api.events.RemovedFriend;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.game.chatbox.ChatboxTextInput;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@PluginDescriptor(
|
||||
name="Friend Tagging",
|
||||
description="Tag people on your friends list."
|
||||
)
|
||||
|
||||
public class FriendTaggingPlugin extends Plugin
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(FriendTaggingPlugin.class);
|
||||
public static ConcurrentHashMap<String, String> taggedFriends = new ConcurrentHashMap();
|
||||
private static final String CONFIG_GROUP = "friendtagging";
|
||||
private static final int CHARACTER_LIMIT = 30;
|
||||
private static final String KEY_PREFIX = "tag_";
|
||||
private static final String ADD_TAG = "Add Tag";
|
||||
private static final String DELETE_TAG = "Delete Tag";
|
||||
@Inject
|
||||
private Client client;
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
@Inject
|
||||
private ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
this.loadFriendTags();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
super.shutDown();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
int groupId = WidgetInfo.TO_GROUP(event.getActionParam1());
|
||||
if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) {
|
||||
String friendName = Text.removeTags(event.getTarget());
|
||||
MenuEntry entry = new MenuEntry();
|
||||
entry.setOption(friendName == null || this.getTag(friendName) == null ? ADD_TAG : DELETE_TAG);
|
||||
entry.setType(MenuAction.RUNELITE.getId());
|
||||
entry.setTarget(event.getTarget());
|
||||
entry.setParam0(event.getActionParam0());
|
||||
entry.setParam1(event.getActionParam1());
|
||||
MenuEntry[] menuEntries = ObjectArrays.concat(this.client.getMenuEntries(), entry);
|
||||
this.client.setMenuEntries(menuEntries);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onRemovedFriend(RemovedFriend event) {
|
||||
String displayName = event.getName().trim().toLowerCase();
|
||||
this.deleteTag(displayName);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNameableNameChanged(NameableNameChanged event) {
|
||||
Friend friend;
|
||||
Nameable nameable = event.getNameable();
|
||||
if (nameable instanceof Friend && (friend = (Friend)nameable).getName() != null && friend.getPrevName() != null) {
|
||||
this.migrateFriendTag(friend.getName(), friend.getPrevName());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event) {
|
||||
if (WidgetInfo.TO_GROUP(event.getWidgetId()) == WidgetInfo.FRIENDS_LIST.getGroupId()) {
|
||||
if (Strings.isNullOrEmpty(event.getMenuTarget())) {
|
||||
return;
|
||||
}
|
||||
String sanitizedTarget = Text.removeTags(event.getMenuTarget());
|
||||
if (event.getMenuOption().equals(ADD_TAG)) {
|
||||
event.consume();
|
||||
ChatboxTextInput chatboxTextInput = this.chatboxPanelManager.openTextInput("Enter the tag").value("").onDone(content -> {
|
||||
if (content == null) {
|
||||
return;
|
||||
}
|
||||
content = Text.removeTags(content).trim();
|
||||
this.setTag(sanitizedTarget, (String)content);
|
||||
}).build();
|
||||
}
|
||||
if (event.getMenuOption().equals(DELETE_TAG)) {
|
||||
event.consume();
|
||||
this.client.getLogger().info(sanitizedTarget);
|
||||
taggedFriends.forEach((k, v) -> this.client.getLogger().info(k + ": ", v));
|
||||
this.deleteTag(sanitizedTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getTag(String name) {
|
||||
name = name.trim().toLowerCase();
|
||||
String keyName = KEY_PREFIX + name;
|
||||
return taggedFriends.get(keyName);
|
||||
}
|
||||
|
||||
private void setTag(String name, String tag) {
|
||||
this.client.getLogger().info("SETTING " + name + ": " + tag);
|
||||
name = name.trim().toLowerCase();
|
||||
String keyName = KEY_PREFIX + name;
|
||||
if (tag.length() <= 30) {
|
||||
taggedFriends.put(keyName, tag);
|
||||
this.configManager.setConfiguration(CONFIG_GROUP, keyName, tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteTag(String name) {
|
||||
name = name.trim().toLowerCase();
|
||||
String keyName = KEY_PREFIX + name;
|
||||
this.configManager.unsetConfiguration(CONFIG_GROUP, keyName);
|
||||
taggedFriends.remove(keyName);
|
||||
}
|
||||
|
||||
private void loadFriendTags() {
|
||||
String prefix = "friendtagging.tag_";
|
||||
for (String key : this.configManager.getConfigurationKeys(prefix)) {
|
||||
String result = this.configManager.getConfiguration(CONFIG_GROUP, key = key.replace("friendtagging.", ""));
|
||||
if (!Objects.nonNull(result) || result.equals("")) continue;
|
||||
taggedFriends.put(key, this.configManager.getConfiguration(CONFIG_GROUP, key));
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateFriendTag(String currentDisplayName, String prevDisplayName) {
|
||||
String prevTag;
|
||||
String currentTag = this.getTag(currentDisplayName);
|
||||
if (currentTag == null && (prevTag = this.getTag(prevDisplayName)) != null) {
|
||||
this.setTag(prevDisplayName, "");
|
||||
this.setTag(currentDisplayName, prevTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Damen <https://github.com/basicDamen>
|
||||
* 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.grotesqueguardians;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GraphicsObject;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class GrotesqueGuardiansOverlay extends Overlay
|
||||
{
|
||||
private static final int GROTESQUE_GUARDIANS_REGION_ID = 6727;
|
||||
private final Client client;
|
||||
private static final int GROTESQUE_GUARDIANS_LIGHTNING_START = 1416;
|
||||
private static final int GROTESQUE_GUARDIANS_LIGHTNING_END = 1431;
|
||||
private static final int GROTESQUE_GUARDIANS_FALLING_ROCKS = 1436;
|
||||
private static final int GROTESQUE_GUARDIANS_STONE_ORB = 160;
|
||||
|
||||
@Inject
|
||||
private GrotesqueGuardiansOverlay(Client client)
|
||||
{
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!client.isInInstancedRegion() || client.getMapRegions()[0] != GROTESQUE_GUARDIANS_REGION_ID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Awaiting GraphicsObjectDespawn event to be tracked to make this more efficient.
|
||||
for (GraphicsObject graphicsObject : client.getGraphicsObjects())
|
||||
{
|
||||
Color color = null;
|
||||
|
||||
if (graphicsObject.getId() >= GROTESQUE_GUARDIANS_LIGHTNING_START && graphicsObject.getId() <= GROTESQUE_GUARDIANS_LIGHTNING_END)
|
||||
{
|
||||
color = Color.ORANGE;
|
||||
}
|
||||
else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_STONE_ORB)
|
||||
{
|
||||
color = Color.GRAY;
|
||||
}
|
||||
else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_FALLING_ROCKS)
|
||||
{
|
||||
color = Color.YELLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalPoint lp = graphicsObject.getLocation();
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Damen <https://github.com/basicDamen>
|
||||
* 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.grotesqueguardians;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"#4863A0\">!Grotesque Guardians</font>",
|
||||
description = "Display tile indicators for the Grotesque Guardian special attacks",
|
||||
tags = {"grotesque", "guardians", "gargoyle", "garg"}
|
||||
)
|
||||
public class GrotesqueGuardiansPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private GrotesqueGuardiansOverlay overlay;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.runelite.client.plugins.hideprayers;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("hideprayers")
|
||||
public interface HidePrayersConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "pk prayers",
|
||||
name = "Hides none pk prayers",
|
||||
description = "Hides widget icons."
|
||||
)
|
||||
default boolean showPrayers() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "eagle/mystic",
|
||||
name = "Shows eagle and mystic prayers",
|
||||
description = "Hides widget icons."
|
||||
)
|
||||
default boolean showEagleMystic() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "ultstr",
|
||||
name = "Shows ultimate strength",
|
||||
description = "Hides widget icons."
|
||||
)
|
||||
default boolean showUltStrength() { return false; }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
package net.runelite.client.plugins.hideprayers;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!Hide Prayers</font>",
|
||||
description = "Hides specific Prayers in the Prayer tab."
|
||||
)
|
||||
public class HidePrayersPlugin extends Plugin {
|
||||
private static final int PRAYER_COUNT = Prayer.values().length;
|
||||
|
||||
private static final List<WidgetInfo> PRAYER_WIDGET_INFO_LIST = ImmutableList.of(WidgetInfo.PRAYER_THICK_SKIN,
|
||||
WidgetInfo.PRAYER_BURST_OF_STRENGTH, WidgetInfo.PRAYER_CLARITY_OF_THOUGHT, WidgetInfo.PRAYER_SHARP_EYE,
|
||||
WidgetInfo.PRAYER_MYSTIC_WILL, WidgetInfo.PRAYER_ROCK_SKIN, WidgetInfo.PRAYER_SUPERHUMAN_STRENGTH,
|
||||
WidgetInfo.PRAYER_IMPROVED_REFLEXES, WidgetInfo.PRAYER_RAPID_RESTORE, WidgetInfo.PRAYER_RAPID_HEAL,
|
||||
WidgetInfo.PRAYER_PROTECT_ITEM, WidgetInfo.PRAYER_HAWK_EYE, WidgetInfo.PRAYER_MYSTIC_LORE,
|
||||
WidgetInfo.PRAYER_STEEL_SKIN, WidgetInfo.PRAYER_ULTIMATE_STRENGTH, WidgetInfo.PRAYER_INCREDIBLE_REFLEXES,
|
||||
WidgetInfo.PRAYER_PROTECT_FROM_MAGIC, WidgetInfo.PRAYER_PROTECT_FROM_MISSILES,
|
||||
WidgetInfo.PRAYER_PROTECT_FROM_MELEE, WidgetInfo.PRAYER_EAGLE_EYE, WidgetInfo.PRAYER_MYSTIC_MIGHT,
|
||||
WidgetInfo.PRAYER_RETRIBUTION, WidgetInfo.PRAYER_REDEMPTION, WidgetInfo.PRAYER_SMITE,
|
||||
WidgetInfo.PRAYER_PRESERVE, WidgetInfo.PRAYER_CHIVALRY, WidgetInfo.PRAYER_PIETY, WidgetInfo.PRAYER_RIGOUR,
|
||||
WidgetInfo.PRAYER_AUGURY);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private HidePrayersConfig config;
|
||||
|
||||
@Provides
|
||||
HidePrayersConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(HidePrayersConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
hidePrayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
restorePrayers();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event) {
|
||||
if (event.getGameState() == GameState.LOGGED_IN) {
|
||||
hidePrayers();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event) {
|
||||
if (event.getGroup().equals("hideprayers")) {
|
||||
hidePrayers();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event) {
|
||||
if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID) {
|
||||
hidePrayers();
|
||||
}
|
||||
}
|
||||
|
||||
private PrayerTabState getPrayerTabState() {
|
||||
HashTable<WidgetNode> componentTable = client.getComponentTable();
|
||||
for (WidgetNode widgetNode : componentTable.getNodes()) {
|
||||
if (widgetNode.getId() == WidgetID.PRAYER_GROUP_ID) {
|
||||
return PrayerTabState.PRAYERS;
|
||||
} else if (widgetNode.getId() == WidgetID.QUICK_PRAYERS_GROUP_ID) {
|
||||
return PrayerTabState.QUICK_PRAYERS;
|
||||
}
|
||||
}
|
||||
return PrayerTabState.NONE;
|
||||
}
|
||||
|
||||
private void restorePrayers() {
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
return;
|
||||
|
||||
PrayerTabState prayerTabState = getPrayerTabState();
|
||||
|
||||
if (prayerTabState == PrayerTabState.PRAYERS) {
|
||||
List<Widget> prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
|
||||
return;
|
||||
|
||||
for (int index = 0; index < PRAYER_COUNT; index++)
|
||||
prayerWidgets.get(Prayer.values()[index].ordinal()).setHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void hidePrayers() {
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
return;
|
||||
|
||||
PrayerTabState prayerTabState = getPrayerTabState();
|
||||
|
||||
if (prayerTabState == PrayerTabState.PRAYERS) {
|
||||
List<Widget> prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
|
||||
return;
|
||||
|
||||
for (int index = 0; index < PRAYER_COUNT; index++) {
|
||||
Prayer prayer = Prayer.values()[index];
|
||||
Widget prayerWidget = prayerWidgets.get(prayer.ordinal());
|
||||
|
||||
if (!config.showPrayers() && !config.showEagleMystic())
|
||||
prayerWidget.setHidden(false);
|
||||
|
||||
if (config.showPrayers()) {
|
||||
prayerWidget.setHidden(true);
|
||||
prayerWidgets.get(Prayer.values()[10].ordinal()).setHidden(false);// protect item
|
||||
prayerWidgets.get(Prayer.values()[16].ordinal()).setHidden(false);// mage
|
||||
prayerWidgets.get(Prayer.values()[17].ordinal()).setHidden(false);// range
|
||||
prayerWidgets.get(Prayer.values()[18].ordinal()).setHidden(false);// melee
|
||||
prayerWidgets.get(Prayer.values()[23].ordinal()).setHidden(false);// smite
|
||||
if (config.showEagleMystic()) {
|
||||
prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
|
||||
prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
|
||||
} else {
|
||||
prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(false);// rigour
|
||||
prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(false);// augury
|
||||
}
|
||||
if (config.showUltStrength()) {
|
||||
prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
|
||||
} else {
|
||||
prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(false);// piety
|
||||
}
|
||||
}
|
||||
if (config.showEagleMystic()) {
|
||||
prayerWidget.setHidden(true);
|
||||
prayerWidgets.get(Prayer.values()[19].ordinal()).setHidden(false);// eagle
|
||||
prayerWidgets.get(Prayer.values()[20].ordinal()).setHidden(false);// mystic
|
||||
prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
|
||||
prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
|
||||
}
|
||||
if (config.showUltStrength()) {
|
||||
prayerWidget.setHidden(true);
|
||||
prayerWidgets.get(Prayer.values()[14].ordinal()).setHidden(false);// Ult Strength
|
||||
prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.runelite.client.plugins.hideprayers;
|
||||
|
||||
public enum PrayerTabState
|
||||
{
|
||||
NONE,
|
||||
PRAYERS,
|
||||
QUICK_PRAYERS
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("hydra")
|
||||
public interface HydraConfig extends Config {
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "hydraenable",
|
||||
name = "Enable Hydra (194 cb) Helper",
|
||||
description = "Configures whether or not to enable Hydra Helper. (For use on regular hydra's only, will not work with Alchemical Hydra)."
|
||||
)
|
||||
default boolean EnableHydra() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "textindicators",
|
||||
name = "Text Indicator",
|
||||
description = "Configures if text indicator is shown above hydra's or not."
|
||||
)
|
||||
default boolean TextIndicator() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "countersize",
|
||||
name = "Bold indicator",
|
||||
description = "Configures if text indicator is bold or not."
|
||||
)
|
||||
default boolean BoldText() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "prayerhelper",
|
||||
name = "Prayer Helper",
|
||||
description = "Configures if prayer helper is shown or not."
|
||||
)
|
||||
default boolean PrayerHelper() { return true; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
|
||||
public class HydraIndicatorOverlay extends Overlay {
|
||||
private final HydraConfig config;
|
||||
private final HydraPlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private HydraIndicatorOverlay(HydraConfig config, HydraPlugin plugin) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.MED);
|
||||
panelComponent.setPreferredSize(new Dimension(14, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!config.PrayerHelper()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (plugin.Hydra != null) {
|
||||
if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) {
|
||||
int val = plugin.hydras.get(plugin.Hydra.getIndex());
|
||||
if (val != 0) {
|
||||
panelComponent.getChildren().clear();
|
||||
panelComponent.getChildren().add(LineComponent.builder().right(Integer.toString(val)).build());
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class HydraOverlay extends Overlay {
|
||||
private final HydraConfig config;
|
||||
private final HydraPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private HydraOverlay(HydraConfig config, HydraPlugin plugin) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
panelComponent.setPreferredSize(new Dimension(150, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!config.TextIndicator()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (NPC hydra : client.getNpcs()) {
|
||||
if (hydra == null || hydra.getName() == null) {
|
||||
continue;
|
||||
}
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (plugin.hydras.containsKey(hydra.getIndex())) {
|
||||
int val = plugin.hydras.get(hydra.getIndex());
|
||||
if (val != 0) {
|
||||
if (config.BoldText()) {
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
}
|
||||
if (plugin.hydraattacks.containsKey(hydra.getIndex())) {
|
||||
int attack = plugin.hydraattacks.get(hydra.getIndex());
|
||||
if (attack == 8261) {
|
||||
if (val == 3) {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE);
|
||||
} else {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN);
|
||||
}
|
||||
} else if (attack == 8262) {
|
||||
if (val == 3) {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN);
|
||||
} else {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
Point runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam = hydra.getCanvasTextLocation(graphics, Integer.toString(val), hydra.getLogicalHeight() + 40);
|
||||
if (runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam != null) {
|
||||
OverlayUtil.renderTextLocation(graphics, runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam, Integer.toString(val), Color.WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
graphics.setFont(FontManager.getRunescapeFont());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Hydra",
|
||||
description = "Hydra Helper",
|
||||
tags = {"Hydra", "Helper"}
|
||||
)
|
||||
public class HydraPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private HydraConfig config;
|
||||
|
||||
@Inject
|
||||
private HydraOverlay HydraOverlay;
|
||||
|
||||
@Inject
|
||||
private HydraPrayOverlay HydraPrayOverlay;
|
||||
|
||||
@Inject
|
||||
private HydraIndicatorOverlay HydraIndicatorOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@Provides
|
||||
HydraConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(HydraConfig.class);
|
||||
}
|
||||
|
||||
Map<Integer, Integer> hydras = new HashMap<>();
|
||||
Map<Integer, Integer> hydraattacks = new HashMap<>();
|
||||
NPC Hydra;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
overlayManager.add(HydraOverlay);
|
||||
overlayManager.add(HydraPrayOverlay);
|
||||
overlayManager.add(HydraIndicatorOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
overlayManager.remove(HydraOverlay);
|
||||
overlayManager.remove(HydraPrayOverlay);
|
||||
overlayManager.remove(HydraIndicatorOverlay);
|
||||
hydras.clear();
|
||||
hydraattacks.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event) {
|
||||
if (!config.EnableHydra()) {
|
||||
return;
|
||||
}
|
||||
NPC hydra = event.getNpc();
|
||||
if (hydra.getCombatLevel() != 0 && hydra.getName() != null) {
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (!hydras.containsKey(hydra.getIndex())) {
|
||||
hydras.put(hydra.getIndex(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event) {
|
||||
if (!config.EnableHydra()) {
|
||||
return;
|
||||
}
|
||||
NPC hydra = event.getNpc();
|
||||
if (hydra.getCombatLevel() != 0 && hydra.getName() != null) {
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (hydras.containsKey(hydra.getIndex())) {
|
||||
hydras.remove(hydra.getIndex());
|
||||
}
|
||||
if (hydraattacks.containsKey(hydra.getIndex())) {
|
||||
hydraattacks.remove(hydra.getIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(AnimationChanged event) {
|
||||
Actor monster = event.getActor();
|
||||
Actor local = client.getLocalPlayer();
|
||||
if (monster instanceof NPC) {
|
||||
NPC hydra = (NPC) monster;
|
||||
if (hydra.getCombatLevel() != 0 && hydra.getName() != null) {
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (hydras.containsKey(hydra.getIndex())) {
|
||||
if (hydra.getAnimation() == 8261 || hydra.getAnimation() == 8262) {
|
||||
if (hydra.getInteracting().equals(local)) {
|
||||
Hydra = hydra;
|
||||
}
|
||||
if (hydraattacks.containsKey(hydra.getIndex())) {
|
||||
int lastattack = hydraattacks.get(hydra.getIndex());
|
||||
hydraattacks.replace(hydra.getIndex(), hydra.getAnimation());
|
||||
|
||||
if (lastattack != hydra.getAnimation()) {
|
||||
hydras.replace(hydra.getIndex(), 2);
|
||||
} else {
|
||||
int currval = hydras.get(hydra.getIndex());
|
||||
if (currval == 1) {
|
||||
hydras.replace(hydra.getIndex(), 3);
|
||||
} else {
|
||||
hydras.replace(hydra.getIndex(), currval - 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hydraattacks.put(hydra.getIndex(), hydra.getAnimation());
|
||||
int currval = hydras.get(hydra.getIndex());
|
||||
if (currval == 1) {
|
||||
hydras.replace(hydra.getIndex(), 3);
|
||||
} else {
|
||||
hydras.replace(hydra.getIndex(), currval - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class HydraPrayOverlay extends Overlay {
|
||||
private final HydraConfig config;
|
||||
private final HydraPlugin plugin;
|
||||
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private HydraPrayOverlay(HydraConfig config, HydraPlugin plugin, SpriteManager spriteManager) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
this.spriteManager = spriteManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!config.PrayerHelper()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (plugin.Hydra != null) {
|
||||
if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) {
|
||||
int val = plugin.hydras.get(plugin.Hydra.getIndex());
|
||||
if (val != 0) {
|
||||
if (plugin.hydraattacks.containsKey(plugin.Hydra.getIndex())) {
|
||||
int attack = plugin.hydraattacks.get(plugin.Hydra.getIndex());
|
||||
if (attack == 8261) {
|
||||
if (val == 3) {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
} else {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
} else if (attack == 8262) {
|
||||
if (val == 3) {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
} else {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.runelite.client.plugins.inventorysetups;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class InventorySetup
|
||||
{
|
||||
@Getter
|
||||
private ArrayList<InventorySetupItem> inventory;
|
||||
@Getter
|
||||
private ArrayList<InventorySetupItem> equipment;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package net.runelite.client.plugins.inventorysetups;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Query;
|
||||
import net.runelite.api.SpritePixels;
|
||||
import net.runelite.api.queries.BankItemQuery;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.util.QueryRunner;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
public class InventorySetupBankOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final QueryRunner queryRunner;
|
||||
private final InventorySetupPlugin plugin;
|
||||
private final InventorySetupConfig config;
|
||||
|
||||
@Inject
|
||||
public InventorySetupBankOverlay(Client client, QueryRunner queryRunner, InventorySetupPlugin plugin, InventorySetupConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.queryRunner = queryRunner;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.getBankHighlight())
|
||||
{
|
||||
int[] ids = plugin.getCurrentInventorySetupIds();
|
||||
if (ids == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ids = Arrays.stream(ids)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(id -> id != -1)
|
||||
.toArray();
|
||||
final Query query = new BankItemQuery().idEquals(ids);
|
||||
final WidgetItem[] widgetItems = queryRunner.runQuery(query);
|
||||
final Widget bankContainer = client.getWidget(WidgetInfo.BANK_CONTAINER);
|
||||
for (final WidgetItem item : widgetItems)
|
||||
{
|
||||
Point canvasLocation = item.getCanvasLocation();
|
||||
Rectangle canvasBounds = item.getCanvasBounds();
|
||||
Point windowLocation = bankContainer.getCanvasLocation();
|
||||
|
||||
if (canvasLocation == null || windowLocation == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(canvasLocation.getY() + 60 >= windowLocation.getY() + bankContainer.getHeight()) && !(canvasLocation.getY() + canvasBounds.getHeight() <= windowLocation.getY() + 90))
|
||||
{
|
||||
final Color color = config.getBankHighlightColor();
|
||||
|
||||
if (color != null)
|
||||
{
|
||||
final BufferedImage outline = loadItemOutline(item.getId(), item.getQuantity(), color);
|
||||
graphics.drawImage(outline, item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 1, null);
|
||||
if (item.getQuantity() > 1)
|
||||
{
|
||||
drawQuantity(graphics, item, Color.YELLOW);
|
||||
}
|
||||
else if (item.getQuantity() == 0)
|
||||
{
|
||||
drawQuantity(graphics, item, Color.YELLOW.darker());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawQuantity(Graphics2D graphics, WidgetItem item, Color darker)
|
||||
{
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 2, item.getCanvasLocation().getY() + 11);
|
||||
graphics.setColor(darker);
|
||||
graphics.setFont(FontManager.getRunescapeSmallFont());
|
||||
graphics.drawString(String.valueOf(item.getQuantity()), item.getCanvasLocation().getX() + 1, item.getCanvasLocation().getY() + 10);
|
||||
}
|
||||
|
||||
private BufferedImage loadItemOutline(final int itemId, final int itemQuantity, final Color outlineColor)
|
||||
{
|
||||
final SpritePixels itemSprite = client.createItemSprite(itemId, itemQuantity, 2, 0, 0, true, 710);
|
||||
return itemSprite.toBufferedOutline(outlineColor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.runelite.client.plugins.inventorysetups;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
@ConfigGroup("inventorysetups")
|
||||
public interface InventorySetupConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "highlightDifferences",
|
||||
name = "Highlight Differences",
|
||||
description = "Highlight slots that don't match the selected setup",
|
||||
position = 0
|
||||
)
|
||||
|
||||
default boolean getHighlightDifferences()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightDifferenceColor",
|
||||
name = "Highlight Color",
|
||||
description = "The color used to highlight differences between setups",
|
||||
position = 1
|
||||
)
|
||||
|
||||
default Color getHighlightColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "stackDifference",
|
||||
name = "Stack Difference",
|
||||
description = "Differences between setups will be highlighted if the stack size is different",
|
||||
position = 2
|
||||
)
|
||||
|
||||
default boolean getStackDifference()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "variationDifference",
|
||||
name = "Variation Difference",
|
||||
description = "Variations of items (E.g., charged jewellery) will be counted as different",
|
||||
position = 2
|
||||
)
|
||||
|
||||
default boolean getVariationDifference()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bankHighlight",
|
||||
name = "Bank Highlight",
|
||||
description = "Highlight setup items in bank",
|
||||
position = 4
|
||||
)
|
||||
|
||||
default boolean getBankHighlight()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bankHighlightColor",
|
||||
name = "Bank Highlight Color",
|
||||
description = "The color used to highlight setup items in bank",
|
||||
position = 5
|
||||
)
|
||||
|
||||
default Color getBankHighlightColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.runelite.client.plugins.inventorysetups;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class InventorySetupItem
|
||||
{
|
||||
@Getter
|
||||
private final int id;
|
||||
@Getter
|
||||
private final String name;
|
||||
@Getter
|
||||
private final int quantity;
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
package net.runelite.client.plugins.inventorysetups;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.ItemVariationMapping;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.inventorysetups.ui.InventorySetupPluginPanel;
|
||||
import net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Inventory Setups",
|
||||
description = "Save inventory setups",
|
||||
tags = { "items", "inventory", "setups"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class InventorySetupPlugin extends Plugin
|
||||
{
|
||||
|
||||
private static final String CONFIG_GROUP = "inventorysetups";
|
||||
private static final String CONFIG_KEY = "setups";
|
||||
private static final int NUM_INVENTORY_ITEMS = 28;
|
||||
private static final int NUM_EQUIPMENT_ITEMS = 14;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private InventorySetupBankOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
|
||||
@Inject
|
||||
private InventorySetupConfig config;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
private InventorySetupPluginPanel panel;
|
||||
|
||||
private HashMap<String, InventorySetup> inventorySetups;
|
||||
|
||||
private NavigationButton navButton;
|
||||
|
||||
private boolean highlightDifference;
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
|
||||
panel = new InventorySetupPluginPanel(this, itemManager);
|
||||
|
||||
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "inventorysetups_icon.png");
|
||||
|
||||
navButton = NavigationButton.builder()
|
||||
.tooltip("Inventory Setups")
|
||||
.icon(icon)
|
||||
.priority(9)
|
||||
.panel(panel)
|
||||
.build();
|
||||
|
||||
clientToolbar.addNavigation(navButton);
|
||||
|
||||
// load all the inventory setups from the config file
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGIN_SCREEN)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
loadConfig();
|
||||
panel.showNoSetupsPanel();
|
||||
return true;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void addInventorySetup()
|
||||
{
|
||||
final String name = JOptionPane.showInputDialog(panel,
|
||||
"Enter the name of this setup.",
|
||||
"Add New Setup",
|
||||
JOptionPane.PLAIN_MESSAGE);
|
||||
|
||||
// cancel button was clicked
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.isEmpty())
|
||||
{
|
||||
JOptionPane.showMessageDialog(panel,
|
||||
"Invalid Setup Name",
|
||||
"Names must not be empty.",
|
||||
JOptionPane.PLAIN_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inventorySetups.containsKey(name))
|
||||
{
|
||||
String builder = "The setup " + name + " already exists. " +
|
||||
"Would you like to replace it with the current setup?";
|
||||
int confirm = JOptionPane.showConfirmDialog(panel,
|
||||
builder,
|
||||
"Warning",
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.PLAIN_MESSAGE);
|
||||
|
||||
if (confirm == JOptionPane.CANCEL_OPTION)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// delete the old setup, no need to ask for confirmation
|
||||
// because the user confirmed above
|
||||
removeInventorySetup(name, false);
|
||||
}
|
||||
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
ArrayList<InventorySetupItem> inv = getNormalizedContainer(InventoryID.INVENTORY);
|
||||
ArrayList<InventorySetupItem> eqp = getNormalizedContainer(InventoryID.EQUIPMENT);
|
||||
|
||||
final InventorySetup invSetup = new InventorySetup(inv, eqp);
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
inventorySetups.put(name, invSetup);
|
||||
panel.addInventorySetup(name);
|
||||
panel.setCurrentInventorySetup(name);
|
||||
|
||||
updateConfig();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void removeInventorySetup(final String name, boolean askForConfirmation)
|
||||
{
|
||||
if (inventorySetups.containsKey(name))
|
||||
{
|
||||
int confirm = JOptionPane.YES_OPTION;
|
||||
|
||||
if (askForConfirmation)
|
||||
{
|
||||
confirm = JOptionPane.showConfirmDialog(panel,
|
||||
"Are you sure you want to remove this setup?",
|
||||
"Warning",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.PLAIN_MESSAGE);
|
||||
}
|
||||
|
||||
if (confirm == JOptionPane.YES_OPTION)
|
||||
{
|
||||
inventorySetups.remove(name);
|
||||
panel.removeInventorySetup(name);
|
||||
}
|
||||
|
||||
updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public final InventorySetup getInventorySetup(final String name)
|
||||
{
|
||||
return inventorySetups.get(name);
|
||||
}
|
||||
|
||||
@Provides
|
||||
InventorySetupConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(InventorySetupConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals(CONFIG_GROUP))
|
||||
{
|
||||
// only allow highlighting if the config is enabled and the player is logged in
|
||||
highlightDifference = config.getHighlightDifferences() && client.getGameState() == GameState.LOGGED_IN;
|
||||
final String setupName = panel.getSelectedInventorySetup();
|
||||
if (highlightDifference && !setupName.isEmpty())
|
||||
{
|
||||
panel.setCurrentInventorySetup(setupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
if (inventorySetups.isEmpty())
|
||||
{
|
||||
configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
final Gson gson = new Gson();
|
||||
final String json = gson.toJson(inventorySetups);
|
||||
configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, json);
|
||||
}
|
||||
|
||||
private void loadConfig()
|
||||
{
|
||||
// serialize the internal data structure from the json in the configuration
|
||||
final String json = configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY);
|
||||
if (json == null || json.isEmpty())
|
||||
{
|
||||
inventorySetups = new HashMap<>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO add last resort?, serialize exception just make empty map
|
||||
final Gson gson = new Gson();
|
||||
Type type = new TypeToken<HashMap<String, InventorySetup>>()
|
||||
{
|
||||
|
||||
}.getType();
|
||||
inventorySetups = gson.fromJson(json, type);
|
||||
}
|
||||
|
||||
for (final String key : inventorySetups.keySet())
|
||||
{
|
||||
panel.addInventorySetup(key);
|
||||
}
|
||||
|
||||
highlightDifference = false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemContainerChanged(ItemContainerChanged event)
|
||||
{
|
||||
|
||||
if (!highlightDifference || client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// empty entry, no need to compare anything
|
||||
final String selectedInventorySetup = panel.getSelectedInventorySetup();
|
||||
if (selectedInventorySetup.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check to see that the container is the equipment or inventory
|
||||
ItemContainer container = event.getItemContainer();
|
||||
|
||||
if (container == client.getItemContainer(InventoryID.INVENTORY))
|
||||
{
|
||||
ArrayList<InventorySetupItem> normContainer = getNormalizedContainer(InventoryID.INVENTORY);
|
||||
final InventorySetup setup = inventorySetups.get(selectedInventorySetup);
|
||||
panel.highlightDifferences(normContainer, setup, InventoryID.INVENTORY);
|
||||
}
|
||||
else if (container == client.getItemContainer(InventoryID.EQUIPMENT))
|
||||
{
|
||||
ArrayList<InventorySetupItem> normContainer = getNormalizedContainer(InventoryID.EQUIPMENT);
|
||||
final InventorySetup setup = inventorySetups.get(selectedInventorySetup);
|
||||
panel.highlightDifferences(normContainer, setup, InventoryID.EQUIPMENT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
switch (event.getGameState())
|
||||
{
|
||||
// set the highlighting off if login screen shows up
|
||||
case LOGIN_SCREEN:
|
||||
highlightDifference = false;
|
||||
final String setupName = panel.getSelectedInventorySetup();
|
||||
if (!setupName.isEmpty())
|
||||
{
|
||||
panel.setCurrentInventorySetup(setupName);
|
||||
}
|
||||
break;
|
||||
|
||||
// set highlighting
|
||||
case LOGGED_IN:
|
||||
highlightDifference = config.getHighlightDifferences();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<InventorySetupItem> getNormalizedContainer(final InventoryID id)
|
||||
{
|
||||
assert id == InventoryID.INVENTORY || id == InventoryID.EQUIPMENT : "invalid inventory ID";
|
||||
|
||||
final ItemContainer container = client.getItemContainer(id);
|
||||
|
||||
ArrayList<InventorySetupItem> newContainer = new ArrayList<>();
|
||||
|
||||
Item[] items = null;
|
||||
if (container != null)
|
||||
{
|
||||
items = container.getItems();
|
||||
}
|
||||
|
||||
int size = id == InventoryID.INVENTORY ? NUM_INVENTORY_ITEMS : NUM_EQUIPMENT_ITEMS;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (items == null || i >= items.length)
|
||||
{
|
||||
newContainer.add(new InventorySetupItem(-1, "", 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
final Item item = items[i];
|
||||
String itemName = "";
|
||||
if (client.isClientThread())
|
||||
{
|
||||
itemName = itemManager.getItemComposition(item.getId()).getName();
|
||||
}
|
||||
newContainer.add(new InventorySetupItem(item.getId(), itemName, item.getQuantity()));
|
||||
}
|
||||
}
|
||||
|
||||
return newContainer;
|
||||
}
|
||||
|
||||
public final InventorySetupConfig getConfig()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
public boolean getHighlightDifference()
|
||||
{
|
||||
return highlightDifference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
clientToolbar.removeNavigation(navButton);
|
||||
}
|
||||
|
||||
final int[] getCurrentInventorySetupIds()
|
||||
{
|
||||
InventorySetup setup = inventorySetups.get(panel.getSelectedInventorySetup());
|
||||
if (setup == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ArrayList<InventorySetupItem> items = new ArrayList<>();
|
||||
items.addAll(setup.getEquipment());
|
||||
items.addAll(setup.getInventory());
|
||||
ArrayList<Integer> itemIds = new ArrayList<>();
|
||||
for (InventorySetupItem item : items)
|
||||
{
|
||||
int id = item.getId();
|
||||
ItemComposition itemComposition = itemManager.getItemComposition(id);
|
||||
if (id > 0)
|
||||
{
|
||||
itemIds.add(ItemVariationMapping.map(id));
|
||||
itemIds.add(itemComposition.getPlaceholderId());
|
||||
}
|
||||
|
||||
}
|
||||
return itemIds.stream().mapToInt(i -> i).toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package net.runelite.client.plugins.inventorysetups.ui;
|
||||
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.ItemVariationMapping;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupConfig;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class InventorySetupContainerPanel extends JPanel
|
||||
{
|
||||
|
||||
protected ItemManager itemManager;
|
||||
|
||||
private final InventorySetupPlugin plugin;
|
||||
|
||||
InventorySetupContainerPanel(final ItemManager itemManager, final InventorySetupPlugin plugin, String captionText)
|
||||
{
|
||||
this.itemManager = itemManager;
|
||||
this.plugin = plugin;
|
||||
JPanel containerPanel = new JPanel();
|
||||
|
||||
final JPanel containerSlotsPanel = new JPanel();
|
||||
|
||||
setupContainerPanel(containerSlotsPanel);
|
||||
|
||||
// caption
|
||||
final JLabel caption = new JLabel(captionText);
|
||||
caption.setHorizontalAlignment(JLabel.CENTER);
|
||||
caption.setVerticalAlignment(JLabel.CENTER);
|
||||
|
||||
// panel that holds the caption and any other graphics
|
||||
final JPanel captionPanel = new JPanel();
|
||||
captionPanel.add(caption);
|
||||
|
||||
containerPanel.setLayout(new BorderLayout());
|
||||
containerPanel.add(captionPanel, BorderLayout.NORTH);
|
||||
containerPanel.add(containerSlotsPanel, BorderLayout.CENTER);
|
||||
|
||||
add(containerPanel);
|
||||
}
|
||||
|
||||
void setContainerSlot(int index,
|
||||
final InventorySetupSlot containerSlot,
|
||||
final ArrayList<InventorySetupItem> items)
|
||||
{
|
||||
if (index >= items.size() || items.get(index).getId() == -1)
|
||||
{
|
||||
containerSlot.setImageLabel(null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = items.get(index).getId();
|
||||
int quantity = items.get(index).getQuantity();
|
||||
final String itemName = items.get(index).getName();
|
||||
AsyncBufferedImage itemImg = itemManager.getImage(itemId, quantity, quantity > 1);
|
||||
String toolTip = itemName;
|
||||
if (quantity > 1)
|
||||
{
|
||||
toolTip += " (" + quantity + ")";
|
||||
}
|
||||
containerSlot.setImageLabel(toolTip, itemImg);
|
||||
}
|
||||
|
||||
void highlightDifferentSlotColor(InventorySetupItem savedItem,
|
||||
InventorySetupItem currItem,
|
||||
final InventorySetupSlot containerSlot)
|
||||
{
|
||||
// important note: do not use item names for comparisons
|
||||
// they are all empty to avoid clientThread usage when highlighting
|
||||
|
||||
final InventorySetupConfig config = plugin.getConfig();
|
||||
final Color highlightColor = config.getHighlightColor();
|
||||
|
||||
if (config.getStackDifference() && currItem.getQuantity() != savedItem.getQuantity())
|
||||
{
|
||||
containerSlot.setBackground(highlightColor);
|
||||
return;
|
||||
}
|
||||
|
||||
int currId = currItem.getId();
|
||||
int checkId = savedItem.getId();
|
||||
|
||||
if (!config.getVariationDifference())
|
||||
{
|
||||
currId = ItemVariationMapping.map(currId);
|
||||
checkId = ItemVariationMapping.map(checkId);
|
||||
}
|
||||
|
||||
if (currId != checkId)
|
||||
{
|
||||
containerSlot.setBackground(highlightColor);
|
||||
return;
|
||||
}
|
||||
|
||||
// set the color back to the original, because they match
|
||||
containerSlot.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
}
|
||||
|
||||
abstract public void setupContainerPanel(final JPanel containerSlotsPanel);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package net.runelite.client.plugins.inventorysetups.ui;
|
||||
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetup;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.GridLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class InventorySetupEquipmentPanel extends InventorySetupContainerPanel
|
||||
{
|
||||
private HashMap<EquipmentInventorySlot, InventorySetupSlot> equipmentSlots;
|
||||
|
||||
InventorySetupEquipmentPanel(final ItemManager itemManager, final InventorySetupPlugin plugin)
|
||||
{
|
||||
super(itemManager, plugin, "Equipment");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupContainerPanel(final JPanel containerSlotsPanel)
|
||||
{
|
||||
this.equipmentSlots = new HashMap<>();
|
||||
for (EquipmentInventorySlot slot : EquipmentInventorySlot.values())
|
||||
{
|
||||
equipmentSlots.put(slot, new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR));
|
||||
}
|
||||
|
||||
final GridLayout gridLayout = new GridLayout(5, 3, 1, 1);
|
||||
containerSlotsPanel.setLayout(gridLayout);
|
||||
|
||||
// add the grid layouts, including invisible ones
|
||||
containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.HEAD));
|
||||
containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.CAPE));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMULET));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.AMMO));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.WEAPON));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BODY));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.SHIELD));
|
||||
containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.LEGS));
|
||||
containerSlotsPanel.add(new InventorySetupSlot(ColorScheme.DARK_GRAY_COLOR));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.GLOVES));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.BOOTS));
|
||||
containerSlotsPanel.add(equipmentSlots.get(EquipmentInventorySlot.RING));
|
||||
|
||||
}
|
||||
|
||||
void setEquipmentSetupSlots(final InventorySetup setup)
|
||||
{
|
||||
final ArrayList<InventorySetupItem> equipment = setup.getEquipment();
|
||||
|
||||
for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values())
|
||||
{
|
||||
int i = slot.getSlotIdx();
|
||||
super.setContainerSlot(i, equipmentSlots.get(slot), equipment);
|
||||
}
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
void highlightDifferences(final ArrayList<InventorySetupItem> currEquipment, final InventorySetup inventorySetup)
|
||||
{
|
||||
final ArrayList<InventorySetupItem> equipToCheck = inventorySetup.getEquipment();
|
||||
|
||||
assert currEquipment.size() == equipToCheck.size() : "size mismatch";
|
||||
|
||||
for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values())
|
||||
{
|
||||
|
||||
int slotIdx = slot.getSlotIdx();
|
||||
super.highlightDifferentSlotColor(equipToCheck.get(slotIdx), currEquipment.get(slotIdx), equipmentSlots.get(slot));
|
||||
}
|
||||
}
|
||||
|
||||
void resetEquipmentSlotsColor()
|
||||
{
|
||||
for (final EquipmentInventorySlot slot : EquipmentInventorySlot.values())
|
||||
{
|
||||
equipmentSlots.get(slot).setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package net.runelite.client.plugins.inventorysetups.ui;
|
||||
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetup;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.GridLayout;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class InventorySetupInventoryPanel extends InventorySetupContainerPanel
|
||||
{
|
||||
|
||||
private static final int ITEMS_PER_ROW = 4;
|
||||
private static final int NUM_INVENTORY_ITEMS = 28;
|
||||
|
||||
private ArrayList<InventorySetupSlot> inventorySlots;
|
||||
|
||||
InventorySetupInventoryPanel(final ItemManager itemManager, final InventorySetupPlugin plugin)
|
||||
{
|
||||
super(itemManager, plugin, "Inventory");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setupContainerPanel(final JPanel containerSlotsPanel)
|
||||
{
|
||||
this.inventorySlots = new ArrayList<>();
|
||||
for (int i = 0; i < NUM_INVENTORY_ITEMS; i++)
|
||||
{
|
||||
inventorySlots.add(new InventorySetupSlot(ColorScheme.DARKER_GRAY_COLOR));
|
||||
}
|
||||
|
||||
int numRows = (NUM_INVENTORY_ITEMS + ITEMS_PER_ROW - 1) / ITEMS_PER_ROW;
|
||||
containerSlotsPanel.setLayout(new GridLayout(numRows, ITEMS_PER_ROW, 1, 1));
|
||||
for (int i = 0; i < NUM_INVENTORY_ITEMS; i++)
|
||||
{
|
||||
containerSlotsPanel.add(inventorySlots.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
void setInventorySetupSlots(final InventorySetup setup)
|
||||
{
|
||||
ArrayList<InventorySetupItem> inventory = setup.getInventory();
|
||||
|
||||
for (int i = 0; i < NUM_INVENTORY_ITEMS; i++)
|
||||
{
|
||||
super.setContainerSlot(i, inventorySlots.get(i), inventory);
|
||||
}
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
void highlightDifferentSlots(final ArrayList<InventorySetupItem> currInventory, final InventorySetup inventorySetup)
|
||||
{
|
||||
|
||||
final ArrayList<InventorySetupItem> inventoryToCheck = inventorySetup.getInventory();
|
||||
|
||||
assert currInventory.size() == inventoryToCheck.size() : "size mismatch";
|
||||
|
||||
for (int i = 0; i < NUM_INVENTORY_ITEMS; i++)
|
||||
{
|
||||
super.highlightDifferentSlotColor(inventoryToCheck.get(i), currInventory.get(i), inventorySlots.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
void resetInventorySlotsColor()
|
||||
{
|
||||
for (InventorySetupSlot inventorySlot : inventorySlots)
|
||||
{
|
||||
inventorySlot.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
package net.runelite.client.plugins.inventorysetups.ui;
|
||||
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetup;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.components.PluginErrorPanel;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class InventorySetupPluginPanel extends PluginPanel
|
||||
{
|
||||
|
||||
private static ImageIcon ADD_ICON;
|
||||
private static ImageIcon ADD_HOVER_ICON;
|
||||
private static ImageIcon REMOVE_ICON;
|
||||
private static ImageIcon REMOVE_HOVER_ICON;
|
||||
|
||||
private final JPanel noSetupsPanel;
|
||||
private final JPanel invEqPanel;
|
||||
|
||||
private final InventorySetupInventoryPanel invPanel;
|
||||
private final InventorySetupEquipmentPanel eqpPanel;
|
||||
|
||||
private final JComboBox<String> setupComboBox;
|
||||
|
||||
private final JLabel removeMarker;
|
||||
|
||||
private final InventorySetupPlugin plugin;
|
||||
|
||||
static
|
||||
{
|
||||
final BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "add_icon.png");
|
||||
ADD_ICON = new ImageIcon(addIcon);
|
||||
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
|
||||
|
||||
final BufferedImage removeIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "remove_icon.png");
|
||||
REMOVE_ICON = new ImageIcon(removeIcon);
|
||||
REMOVE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(removeIcon, 0.53f));
|
||||
}
|
||||
|
||||
public InventorySetupPluginPanel(final InventorySetupPlugin plugin, final ItemManager itemManager)
|
||||
{
|
||||
super(false);
|
||||
this.plugin = plugin;
|
||||
this.removeMarker = new JLabel(REMOVE_ICON);
|
||||
this.invPanel = new InventorySetupInventoryPanel(itemManager, plugin);
|
||||
this.eqpPanel = new InventorySetupEquipmentPanel(itemManager, plugin);
|
||||
this.noSetupsPanel = new JPanel();
|
||||
this.invEqPanel = new JPanel();
|
||||
this.setupComboBox = new JComboBox<>();
|
||||
|
||||
// setup the title
|
||||
final JLabel addMarker = new JLabel(ADD_ICON);
|
||||
final JLabel title = new JLabel();
|
||||
title.setText("Inventory Setups");
|
||||
title.setForeground(Color.WHITE);
|
||||
|
||||
// setup the add marker (+ sign in the top right)
|
||||
addMarker.setToolTipText("Add a new inventory setup");
|
||||
addMarker.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
plugin.addInventorySetup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
addMarker.setIcon(ADD_HOVER_ICON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
addMarker.setIcon(ADD_ICON);
|
||||
}
|
||||
});
|
||||
|
||||
// setup the remove marker (X sign in the top right)
|
||||
removeMarker.setToolTipText("Remove the current inventory setup");
|
||||
removeMarker.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
final String name = (String)setupComboBox.getSelectedItem();
|
||||
plugin.removeInventorySetup(name, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
if (removeMarker.isEnabled())
|
||||
{
|
||||
removeMarker.setIcon(REMOVE_HOVER_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
removeMarker.setIcon(REMOVE_ICON);
|
||||
}
|
||||
});
|
||||
|
||||
// setup the combo box for selection switching
|
||||
// add empty to indicate the empty position
|
||||
setupComboBox.addItem("");
|
||||
setupComboBox.setSelectedIndex(0);
|
||||
setupComboBox.addItemListener(e ->
|
||||
{
|
||||
if (e.getStateChange() == ItemEvent.SELECTED)
|
||||
{
|
||||
String selection = (String)e.getItem();
|
||||
setCurrentInventorySetup(selection);
|
||||
}
|
||||
});
|
||||
|
||||
// the panel on the top right that holds the add and delete buttons
|
||||
final JPanel markersPanel = new JPanel();
|
||||
markersPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 0));
|
||||
markersPanel.add(removeMarker);
|
||||
markersPanel.add(addMarker);
|
||||
|
||||
// the top panel that has the title and the buttons
|
||||
final JPanel titleAndMarkersPanel = new JPanel();
|
||||
titleAndMarkersPanel.setLayout(new BorderLayout());
|
||||
titleAndMarkersPanel.add(title, BorderLayout.WEST);
|
||||
titleAndMarkersPanel.add(markersPanel, BorderLayout.EAST);
|
||||
|
||||
// the panel that stays at the top and doesn't scroll
|
||||
// contains the title, buttons, and the combo box
|
||||
final JPanel northAnchoredPanel = new JPanel();
|
||||
northAnchoredPanel.setLayout(new BoxLayout(northAnchoredPanel, BoxLayout.Y_AXIS));
|
||||
northAnchoredPanel.setBorder(new EmptyBorder(0, 0, 10, 0));
|
||||
northAnchoredPanel.add(titleAndMarkersPanel);
|
||||
northAnchoredPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
northAnchoredPanel.add(setupComboBox);
|
||||
|
||||
// the panel that holds the inventory and equipment panels
|
||||
final BoxLayout invEqLayout = new BoxLayout(invEqPanel, BoxLayout.Y_AXIS);
|
||||
invEqPanel.setLayout(invEqLayout);
|
||||
invEqPanel.add(invPanel);
|
||||
invEqPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
invEqPanel.add(eqpPanel);
|
||||
|
||||
// setup the error panel. It's wrapped around a normal panel
|
||||
// so it doesn't stretch to fill the parent panel
|
||||
final PluginErrorPanel errorPanel = new PluginErrorPanel();
|
||||
errorPanel.setContent("Inventory Setups", "Select or create an inventory setup.");
|
||||
noSetupsPanel.add(errorPanel);
|
||||
|
||||
// the panel that holds the inventory panels, and the error panel
|
||||
final JPanel contentPanel = new JPanel();
|
||||
final BoxLayout contentLayout = new BoxLayout(contentPanel, BoxLayout.Y_AXIS);
|
||||
contentPanel.setLayout(contentLayout);
|
||||
contentPanel.add(invEqPanel);
|
||||
contentPanel.add(noSetupsPanel);
|
||||
|
||||
// wrapper for the main content panel to keep it from stretching
|
||||
final JPanel contentWrapper = new JPanel(new BorderLayout());
|
||||
contentWrapper.add(Box.createGlue(), BorderLayout.CENTER);
|
||||
contentWrapper.add(contentPanel, BorderLayout.NORTH);
|
||||
final JScrollPane contentWrapperPane = new JScrollPane(contentWrapper);
|
||||
contentWrapperPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
add(northAnchoredPanel, BorderLayout.NORTH);
|
||||
add(contentWrapperPane, BorderLayout.CENTER);
|
||||
|
||||
// show the no setups panel on startup
|
||||
showNoSetupsPanel();
|
||||
|
||||
}
|
||||
|
||||
public void showNoSetupsPanel()
|
||||
{
|
||||
setupComboBox.setSelectedIndex(0);
|
||||
removeMarker.setEnabled(false);
|
||||
noSetupsPanel.setVisible(true);
|
||||
invEqPanel.setVisible(false);
|
||||
}
|
||||
|
||||
private void showHasSetupPanel(final String name)
|
||||
{
|
||||
setupComboBox.setSelectedItem(name);
|
||||
removeMarker.setEnabled(true);
|
||||
noSetupsPanel.setVisible(false);
|
||||
invEqPanel.setVisible(true);
|
||||
}
|
||||
|
||||
public void setCurrentInventorySetup(final String name)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
{
|
||||
showNoSetupsPanel();
|
||||
return;
|
||||
}
|
||||
|
||||
showHasSetupPanel(name);
|
||||
|
||||
final InventorySetup inventorySetup = plugin.getInventorySetup(name);
|
||||
|
||||
invPanel.setInventorySetupSlots(inventorySetup);
|
||||
eqpPanel.setEquipmentSetupSlots(inventorySetup);
|
||||
|
||||
if (plugin.getHighlightDifference())
|
||||
{
|
||||
final ArrayList<InventorySetupItem> normInv = plugin.getNormalizedContainer(InventoryID.INVENTORY);
|
||||
final ArrayList<InventorySetupItem> normEqp = plugin.getNormalizedContainer(InventoryID.EQUIPMENT);
|
||||
|
||||
highlightDifferences(normInv, inventorySetup, InventoryID.INVENTORY);
|
||||
highlightDifferences(normEqp, inventorySetup, InventoryID.EQUIPMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
invPanel.resetInventorySlotsColor();
|
||||
eqpPanel.resetEquipmentSlotsColor();
|
||||
}
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void addInventorySetup(final String name)
|
||||
{
|
||||
setupComboBox.addItem(name);
|
||||
}
|
||||
|
||||
public void removeInventorySetup(final String name)
|
||||
{
|
||||
setupComboBox.removeItem(name);
|
||||
showNoSetupsPanel();
|
||||
|
||||
invPanel.resetInventorySlotsColor();
|
||||
eqpPanel.resetEquipmentSlotsColor();
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void highlightDifferences(final ArrayList<InventorySetupItem> container,
|
||||
final InventorySetup setupToCheck,
|
||||
final InventoryID type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INVENTORY:
|
||||
invPanel.highlightDifferentSlots(container, setupToCheck);
|
||||
break;
|
||||
|
||||
case EQUIPMENT:
|
||||
eqpPanel.highlightDifferences(container, setupToCheck);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public final String getSelectedInventorySetup()
|
||||
{
|
||||
return (String)setupComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package net.runelite.client.plugins.inventorysetups.ui;
|
||||
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
|
||||
public class InventorySetupSlot extends JPanel
|
||||
{
|
||||
|
||||
private final JLabel imageLabel;
|
||||
|
||||
public InventorySetupSlot(Color color)
|
||||
{
|
||||
imageLabel = new JLabel();
|
||||
imageLabel.setVerticalAlignment(SwingConstants.CENTER);
|
||||
setPreferredSize(new Dimension(46, 42));
|
||||
setBackground(color);
|
||||
add(imageLabel);
|
||||
|
||||
}
|
||||
|
||||
public void setImageLabel(String toolTip, AsyncBufferedImage itemImage)
|
||||
{
|
||||
if (itemImage == null || toolTip == null)
|
||||
{
|
||||
imageLabel.setToolTipText("");
|
||||
imageLabel.setIcon(null);
|
||||
imageLabel.revalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
imageLabel.setToolTipText(toolTip);
|
||||
itemImage.addTo(imageLabel);
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user