Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
package net.runelite.client.plugins.microbot.HueycoatlPrayer;

import net.runelite.client.config.*;
import net.runelite.client.plugins.microbot.util.prayer.Rs2PrayerEnum;

@ConfigGroup("hueyprayer")
public interface HueyPrayerConfig extends Config
{
@ConfigSection(
name = "General",
description = "Core Huey prayer behaviour",
position = 0
)
String generalSection = "general";

@ConfigSection(
name = "Trio mode",
description = "After a Huey projectile hits, set protection for pillar charging (fixed or autobalance)",
position = 1
)
String trioSection = "trio";

@ConfigItem(
keyName = "enabled",
name = "Enable",
description = "Enable auto prayer"
description = "Enable auto prayer",
position = 0,
section = generalSection
)
default boolean enabled()
{
Expand All @@ -18,7 +35,9 @@ default boolean enabled()
@ConfigItem(
keyName = "disableAfterImpact",
name = "Disable after impact",
description = "When enabled, turns off protection prayer after the projectile hits (saves prayer). When disabled, prayers stay on until the next attack switches them."
description = "When enabled, turns off protection prayer after the projectile hits (saves prayer). When disabled, prayers stay on until the next attack switches them.",
position = 1,
section = generalSection
)
default boolean disableAfterImpact()
{
Expand All @@ -28,10 +47,85 @@ default boolean disableAfterImpact()
@ConfigItem(
keyName = "debug",
name = "Debug Projectiles",
description = "Print projectile IDs"
description = "Print projectile IDs",
position = 2,
section = generalSection
)
default boolean debug()
{
return false;
}
}

@ConfigItem(
keyName = "trioMode",
name = "Trio mode",
description = "While incoming Huey projectiles still use the correct protect vs type, after impact (requires Disable after impact) switches to your pillar role: Fixed or Autobalance protection from teammates' overheads.",
position = 0,
section = trioSection
)
default boolean trioMode()
{
return false;
}

@ConfigItem(
keyName = "trioRoleStyle",
name = "Role style",
description = "Fixed: always use the protection prayer below. Autobalance: among other players in radius, count melee / missiles / magic overheads — you pray the least-covered protection.",
position = 1,
section = trioSection
)
default TrioRoleStyle trioRoleStyle()
{
return TrioRoleStyle.FIXED;
}

@ConfigItem(
keyName = "trioFixedProtection",
name = "Fixed protection",
description = "Used when Role style is Fixed.",
position = 2,
section = trioSection
)
default TrioFixedProtection trioFixedProtection()
{
return TrioFixedProtection.PROTECT_RANGE;
}

@ConfigItem(
keyName = "trioRadius",
name = "Autobalance radius",
description = "Tiles from your tile to include other players when autobalancing (they must still be loaded).",
position = 3,
section = trioSection
)
default int trioRadius()
{
return 15;
}

enum TrioRoleStyle
{
FIXED,
AUTOBALANCE
}

enum TrioFixedProtection
{
PROTECT_MELEE(Rs2PrayerEnum.PROTECT_MELEE),
PROTECT_RANGE(Rs2PrayerEnum.PROTECT_RANGE),
PROTECT_MAGIC(Rs2PrayerEnum.PROTECT_MAGIC);

private final Rs2PrayerEnum prayer;

TrioFixedProtection(Rs2PrayerEnum prayer)
{
this.prayer = prayer;
}

public Rs2PrayerEnum getPrayer()
{
return prayer;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
import lombok.extern.slf4j.Slf4j;

import net.runelite.api.Client;
import net.runelite.api.HeadIcon;
import net.runelite.api.Player;
import net.runelite.api.Projectile;
import net.runelite.api.WorldView;
import net.runelite.api.coords.WorldPoint;

import net.runelite.api.events.ProjectileMoved;

Expand Down Expand Up @@ -35,7 +39,7 @@
)
public class HueyPrayerPlugin extends Plugin
{
static final String VERSION = "1.0.4";
static final String VERSION = "1.0.7";
@Inject
private Client client;

Expand Down Expand Up @@ -129,8 +133,7 @@ public void onProjectileMoved(ProjectileMoved event)
incomingHueyProjectiles.remove(projectile);
if (incomingHueyProjectiles.isEmpty())
{
Rs2Prayer.disableAllPrayers();
currentPrayer = null;
onHueyProjectilePhaseEnded();
}
}
return;
Expand Down Expand Up @@ -173,14 +176,158 @@ private void switchPrayer(Rs2PrayerEnum prayer)
{
int tick = client.getTickCount();

// prevent spam + duplicate toggles
if (currentPrayer == prayer) return;
if (tick == lastSwitchTick) return;
if (Rs2Prayer.isPrayerActive(prayer))
{
currentPrayer = prayer;
return;
}

if (tick == lastSwitchTick)
{
return;
}

Rs2Prayer.disableAllPrayers();
Rs2Prayer.toggle(prayer, true);

currentPrayer = prayer;
lastSwitchTick = tick;
}

/**
* Last Huey projectile toward us has landed — either clear prayers or switch to trio pillar protection.
*/
private void onHueyProjectilePhaseEnded()
{
if (config.trioMode())
{
Rs2PrayerEnum pillar = resolveTrioProtectionPrayer();
if (pillar != null)
{
switchPrayer(pillar);
}
return;
}
Rs2Prayer.disableAllPrayers();
currentPrayer = null;
}

/**
* Fixed or autobalance protection for pillar charging (after projectiles, not during).
*/
private Rs2PrayerEnum resolveTrioProtectionPrayer()
{
if (config.trioRoleStyle() == HueyPrayerConfig.TrioRoleStyle.FIXED)
{
return config.trioFixedProtection().getPrayer();
}
return pickAutobalanceProtectionPrayer();
}

private Rs2PrayerEnum pickAutobalanceProtectionPrayer()
{
Player local = client.getLocalPlayer();
if (local == null)
{
return null;
}
WorldPoint localPoint = local.getWorldLocation();
WorldView worldView = client.getTopLevelWorldView();
if (worldView == null)
{
return null;
}

int melee = 0;
int ranged = 0;
int magic = 0;
int radius = config.trioRadius();
if (radius < 1)
{
radius = 1;
}

for (Player p : worldView.players())
{
if (p == null)
{
continue;
}
if (p == local)
{
continue;
}
WorldPoint wp = p.getWorldLocation();
if (wp == null)
{
continue;
}
if (wp.distanceTo(localPoint) > radius)
{
continue;
}
HeadIcon overhead = p.getOverheadIcon();
if (overhead == HeadIcon.MELEE)
{
melee++;
}
else if (overhead == HeadIcon.RANGED)
{
ranged++;
}
else if (overhead == HeadIcon.MAGIC)
{
magic++;
}
}

if (melee == 0)
{
if (ranged == 0)
{
if (magic == 0)
{
return protectionMatchingLocalOverhead(local);
}
}
}

int minCount = melee;
if (ranged < minCount)
{
minCount = ranged;
}
if (magic < minCount)
{
minCount = magic;
}

if (melee == minCount)
{
return Rs2PrayerEnum.PROTECT_MELEE;
}
if (ranged == minCount)
{
return Rs2PrayerEnum.PROTECT_RANGE;
}
return Rs2PrayerEnum.PROTECT_MAGIC;
}

private static Rs2PrayerEnum protectionMatchingLocalOverhead(Player local)
{
HeadIcon overhead = local.getOverheadIcon();
if (overhead == HeadIcon.MELEE)
{
return Rs2PrayerEnum.PROTECT_MELEE;
}
if (overhead == HeadIcon.RANGED)
{
return Rs2PrayerEnum.PROTECT_RANGE;
}
if (overhead == HeadIcon.MAGIC)
{
return Rs2PrayerEnum.PROTECT_MAGIC;
}
return Rs2PrayerEnum.PROTECT_MELEE;
}
}
Loading
Loading