runelite-client: Remove Demonic Gorilla Plugin
as per Jagex's wishes
This commit is contained in:
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.demonicgorilla;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.runelite.api.Actor;
|
|
||||||
import net.runelite.api.HeadIcon;
|
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.api.NPCComposition;
|
|
||||||
import net.runelite.api.coords.WorldArea;
|
|
||||||
|
|
||||||
public class DemonicGorilla
|
|
||||||
{
|
|
||||||
static final int MAX_ATTACK_RANGE = 10; // Needs <= 10 tiles to reach target
|
|
||||||
static final int ATTACK_RATE = 5; // 5 ticks between each attack
|
|
||||||
static final int ATTACKS_PER_SWITCH = 3; // 3 unsuccessful attacks per style switch
|
|
||||||
|
|
||||||
static final int PROJECTILE_MAGIC_SPEED = 8; // Travels 8 tiles per tick
|
|
||||||
static final int PROJECTILE_RANGED_SPEED = 6; // Travels 6 tiles per tick
|
|
||||||
static final int PROJECTILE_MAGIC_DELAY = 12; // Requires an extra 12 tiles
|
|
||||||
static final int PROJECTILE_RANGED_DELAY = 9; // Requires an extra 9 tiles
|
|
||||||
|
|
||||||
public static final AttackStyle[] ALL_REGULAR_ATTACK_STYLES =
|
|
||||||
{
|
|
||||||
AttackStyle.MELEE,
|
|
||||||
AttackStyle.RANGED,
|
|
||||||
AttackStyle.MAGIC
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AttackStyle
|
|
||||||
{
|
|
||||||
MAGIC,
|
|
||||||
RANGED,
|
|
||||||
MELEE,
|
|
||||||
BOULDER
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private NPC npc;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private List<AttackStyle> nextPosibleAttackStyles;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private int attacksUntilSwitch;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private int nextAttackTick;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private int lastTickAnimation;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private WorldArea lastWorldArea;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private boolean initiatedCombat;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private Actor lastTickInteracting;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private boolean takenDamageRecently;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private int recentProjectileId;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private boolean changedPrayerThisTick;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private boolean changedAttackStyleThisTick;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private boolean changedAttackStyleLastTick;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private HeadIcon lastTickOverheadIcon;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private int disabledMeleeMovementForTicks;
|
|
||||||
|
|
||||||
public DemonicGorilla(NPC npc)
|
|
||||||
{
|
|
||||||
this.npc = npc;
|
|
||||||
this.nextPosibleAttackStyles = Arrays.asList(ALL_REGULAR_ATTACK_STYLES);
|
|
||||||
this.nextAttackTick = -100;
|
|
||||||
this.attacksUntilSwitch = ATTACKS_PER_SWITCH;
|
|
||||||
this.recentProjectileId = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeadIcon getOverheadIcon()
|
|
||||||
{
|
|
||||||
NPCComposition composition = this.npc.getComposition();
|
|
||||||
if (composition != null)
|
|
||||||
{
|
|
||||||
return composition.getOverheadIcon();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.demonicgorilla;
|
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.geom.Arc2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.Perspective;
|
|
||||||
import net.runelite.api.Point;
|
|
||||||
import net.runelite.api.Skill;
|
|
||||||
import net.runelite.api.coords.LocalPoint;
|
|
||||||
import net.runelite.client.game.SkillIconManager;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
|
||||||
|
|
||||||
public class DemonicGorillaOverlay extends Overlay
|
|
||||||
{
|
|
||||||
private static final Color COLOR_ICON_BACKGROUND = new Color(0, 0, 0, 128);
|
|
||||||
private static final Color COLOR_ICON_BORDER = new Color(0, 0, 0, 255);
|
|
||||||
private static final Color COLOR_ICON_BORDER_FILL = new Color(219, 175, 0, 255);
|
|
||||||
private static final int OVERLAY_ICON_DISTANCE = 50;
|
|
||||||
private static final int OVERLAY_ICON_MARGIN = 8;
|
|
||||||
|
|
||||||
private Client client;
|
|
||||||
private DemonicGorillaPlugin plugin;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private SkillIconManager iconManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public DemonicGorillaOverlay(Client client, DemonicGorillaPlugin plugin)
|
|
||||||
{
|
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
|
||||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
|
||||||
this.client = client;
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BufferedImage getIcon(DemonicGorilla.AttackStyle attackStyle)
|
|
||||||
{
|
|
||||||
switch (attackStyle)
|
|
||||||
{
|
|
||||||
case MELEE: return iconManager.getSkillImage(Skill.ATTACK);
|
|
||||||
case RANGED: return iconManager.getSkillImage(Skill.RANGED);
|
|
||||||
case MAGIC: return iconManager.getSkillImage(Skill.MAGIC);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
for (DemonicGorilla gorilla : plugin.getGorillas().values())
|
|
||||||
{
|
|
||||||
if (gorilla.getNpc().getInteracting() == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoint lp = gorilla.getNpc().getLocalLocation();
|
|
||||||
if (lp != null)
|
|
||||||
{
|
|
||||||
Point point = Perspective.localToCanvas(client, lp, client.getPlane(),
|
|
||||||
gorilla.getNpc().getLogicalHeight() + 16);
|
|
||||||
if (point != null)
|
|
||||||
{
|
|
||||||
point = new Point(point.getX(), point.getY());
|
|
||||||
|
|
||||||
List<DemonicGorilla.AttackStyle> attackStyles = gorilla.getNextPosibleAttackStyles();
|
|
||||||
List<BufferedImage> icons = new ArrayList<>();
|
|
||||||
int totalWidth = (attackStyles.size() - 1) * OVERLAY_ICON_MARGIN;
|
|
||||||
for (DemonicGorilla.AttackStyle attackStyle : attackStyles)
|
|
||||||
{
|
|
||||||
BufferedImage icon = getIcon(attackStyle);
|
|
||||||
icons.add(icon);
|
|
||||||
totalWidth += icon.getWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
int bgPadding = 4;
|
|
||||||
int currentPosX = 0;
|
|
||||||
for (BufferedImage icon : icons)
|
|
||||||
{
|
|
||||||
graphics.setStroke(new BasicStroke(2));
|
|
||||||
graphics.setColor(COLOR_ICON_BACKGROUND);
|
|
||||||
graphics.fillOval(
|
|
||||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
|
||||||
icon.getWidth() + bgPadding * 2,
|
|
||||||
icon.getHeight() + bgPadding * 2);
|
|
||||||
|
|
||||||
graphics.setColor(COLOR_ICON_BORDER);
|
|
||||||
graphics.drawOval(
|
|
||||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
|
||||||
icon.getWidth() + bgPadding * 2,
|
|
||||||
icon.getHeight() + bgPadding * 2);
|
|
||||||
|
|
||||||
graphics.drawImage(
|
|
||||||
icon,
|
|
||||||
point.getX() - totalWidth / 2 + currentPosX,
|
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
|
|
||||||
null);
|
|
||||||
|
|
||||||
graphics.setColor(COLOR_ICON_BORDER_FILL);
|
|
||||||
Arc2D.Double arc = new Arc2D.Double(
|
|
||||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
|
||||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
|
||||||
icon.getWidth() + bgPadding * 2,
|
|
||||||
icon.getHeight() + bgPadding * 2,
|
|
||||||
90.0,
|
|
||||||
-360.0 * (DemonicGorilla.ATTACKS_PER_SWITCH -
|
|
||||||
gorilla.getAttacksUntilSwitch()) / DemonicGorilla.ATTACKS_PER_SWITCH,
|
|
||||||
Arc2D.OPEN);
|
|
||||||
graphics.draw(arc);
|
|
||||||
|
|
||||||
currentPosX += icon.getWidth() + OVERLAY_ICON_MARGIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,716 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.demonicgorilla;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.AnimationID;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.GameState;
|
|
||||||
import net.runelite.api.HeadIcon;
|
|
||||||
import net.runelite.api.Hitsplat;
|
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.api.NpcID;
|
|
||||||
import net.runelite.api.Player;
|
|
||||||
import net.runelite.api.Projectile;
|
|
||||||
import net.runelite.api.ProjectileID;
|
|
||||||
import net.runelite.api.coords.WorldArea;
|
|
||||||
import net.runelite.api.coords.WorldPoint;
|
|
||||||
import net.runelite.api.events.GameStateChanged;
|
|
||||||
import net.runelite.api.events.GameTick;
|
|
||||||
import net.runelite.api.events.HitsplatApplied;
|
|
||||||
import net.runelite.api.events.NpcDespawned;
|
|
||||||
import net.runelite.api.events.NpcSpawned;
|
|
||||||
import net.runelite.api.events.PlayerDespawned;
|
|
||||||
import net.runelite.api.events.PlayerSpawned;
|
|
||||||
import net.runelite.api.events.ProjectileMoved;
|
|
||||||
import net.runelite.client.callback.ClientThread;
|
|
||||||
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 = "Demonic Gorillas",
|
|
||||||
description = "Count demonic gorilla attacks and display their next possible attack styles",
|
|
||||||
tags = {"combat", "overlay", "pve", "pvm"}
|
|
||||||
)
|
|
||||||
public class DemonicGorillaPlugin extends Plugin
|
|
||||||
{
|
|
||||||
@Inject
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private OverlayManager overlayManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private DemonicGorillaOverlay overlay;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ClientThread clientThread;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private Map<NPC, DemonicGorilla> gorillas;
|
|
||||||
|
|
||||||
private List<WorldPoint> recentBoulders;
|
|
||||||
|
|
||||||
private List<PendingGorillaAttack> pendingAttacks;
|
|
||||||
|
|
||||||
private Map<Player, MemorizedPlayer> memorizedPlayers;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void startUp() throws Exception
|
|
||||||
{
|
|
||||||
overlayManager.add(overlay);
|
|
||||||
gorillas = new HashMap<>();
|
|
||||||
recentBoulders = new ArrayList<>();
|
|
||||||
pendingAttacks = new ArrayList<>();
|
|
||||||
memorizedPlayers = new HashMap<>();
|
|
||||||
clientThread.invoke(this::reset); // Updates the list of gorillas and players
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void shutDown() throws Exception
|
|
||||||
{
|
|
||||||
overlayManager.remove(overlay);
|
|
||||||
gorillas = null;
|
|
||||||
recentBoulders = null;
|
|
||||||
pendingAttacks = null;
|
|
||||||
memorizedPlayers = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clear()
|
|
||||||
{
|
|
||||||
recentBoulders.clear();
|
|
||||||
pendingAttacks.clear();
|
|
||||||
memorizedPlayers.clear();
|
|
||||||
gorillas.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reset()
|
|
||||||
{
|
|
||||||
recentBoulders.clear();
|
|
||||||
pendingAttacks.clear();
|
|
||||||
resetGorillas();
|
|
||||||
resetPlayers();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetGorillas()
|
|
||||||
{
|
|
||||||
gorillas.clear();
|
|
||||||
for (NPC npc : client.getNpcs())
|
|
||||||
{
|
|
||||||
if (isNpcGorilla(npc.getId()))
|
|
||||||
{
|
|
||||||
gorillas.put(npc, new DemonicGorilla(npc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetPlayers()
|
|
||||||
{
|
|
||||||
memorizedPlayers.clear();
|
|
||||||
for (Player player : client.getPlayers())
|
|
||||||
{
|
|
||||||
memorizedPlayers.put(player, new MemorizedPlayer(player));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isNpcGorilla(int npcId)
|
|
||||||
{
|
|
||||||
return npcId == NpcID.DEMONIC_GORILLA ||
|
|
||||||
npcId == NpcID.DEMONIC_GORILLA_7145 ||
|
|
||||||
npcId == NpcID.DEMONIC_GORILLA_7146 ||
|
|
||||||
npcId == NpcID.DEMONIC_GORILLA_7147 ||
|
|
||||||
npcId == NpcID.DEMONIC_GORILLA_7148 ||
|
|
||||||
npcId == NpcID.DEMONIC_GORILLA_7149;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkGorillaAttackStyleSwitch(DemonicGorilla gorilla,
|
|
||||||
final DemonicGorilla.AttackStyle... protectedStyles)
|
|
||||||
{
|
|
||||||
if (gorilla.getAttacksUntilSwitch() <= 0 ||
|
|
||||||
gorilla.getNextPosibleAttackStyles().isEmpty())
|
|
||||||
{
|
|
||||||
gorilla.setNextPosibleAttackStyles(Arrays
|
|
||||||
.stream(DemonicGorilla.ALL_REGULAR_ATTACK_STYLES)
|
|
||||||
.filter(x -> Arrays.stream(protectedStyles).noneMatch(y -> x == y))
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
gorilla.setAttacksUntilSwitch(DemonicGorilla.ATTACKS_PER_SWITCH);
|
|
||||||
gorilla.setChangedAttackStyleThisTick(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DemonicGorilla.AttackStyle getProtectedStyle(Player player)
|
|
||||||
{
|
|
||||||
HeadIcon headIcon = player.getOverheadIcon();
|
|
||||||
if (headIcon == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
switch (headIcon)
|
|
||||||
{
|
|
||||||
case MELEE:
|
|
||||||
return DemonicGorilla.AttackStyle.MELEE;
|
|
||||||
case RANGED:
|
|
||||||
return DemonicGorilla.AttackStyle.RANGED;
|
|
||||||
case MAGIC:
|
|
||||||
return DemonicGorilla.AttackStyle.MAGIC;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onGorillaAttack(DemonicGorilla gorilla, final DemonicGorilla.AttackStyle attackStyle)
|
|
||||||
{
|
|
||||||
gorilla.setInitiatedCombat(true);
|
|
||||||
|
|
||||||
Player target = (Player)gorilla.getNpc().getInteracting();
|
|
||||||
|
|
||||||
DemonicGorilla.AttackStyle protectedStyle = null;
|
|
||||||
if (target != null)
|
|
||||||
{
|
|
||||||
protectedStyle = getProtectedStyle(target);
|
|
||||||
}
|
|
||||||
boolean correctPrayer =
|
|
||||||
target == null || // If player is out of memory, assume prayer was correct
|
|
||||||
attackStyle == protectedStyle;
|
|
||||||
|
|
||||||
if (attackStyle == DemonicGorilla.AttackStyle.BOULDER)
|
|
||||||
{
|
|
||||||
// The gorilla can't throw boulders when it's meleeing
|
|
||||||
gorilla.setNextPosibleAttackStyles(gorilla
|
|
||||||
.getNextPosibleAttackStyles()
|
|
||||||
.stream()
|
|
||||||
.filter(x -> x != DemonicGorilla.AttackStyle.MELEE)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (correctPrayer)
|
|
||||||
{
|
|
||||||
gorilla.setAttacksUntilSwitch(gorilla.getAttacksUntilSwitch() - 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We're not sure if the attack will hit a 0 or not,
|
|
||||||
// so we don't know if we should decrease the counter or not,
|
|
||||||
// so we keep track of the attack here until the damage splat
|
|
||||||
// has appeared on the player.
|
|
||||||
|
|
||||||
int damagesOnTick = client.getTickCount();
|
|
||||||
if (attackStyle == DemonicGorilla.AttackStyle.MAGIC)
|
|
||||||
{
|
|
||||||
MemorizedPlayer mp = memorizedPlayers.get(target);
|
|
||||||
WorldArea lastPlayerArea = mp.getLastWorldArea();
|
|
||||||
if (lastPlayerArea != null)
|
|
||||||
{
|
|
||||||
int dist = gorilla.getNpc().getWorldArea().distanceTo(lastPlayerArea);
|
|
||||||
damagesOnTick += (dist + DemonicGorilla.PROJECTILE_MAGIC_DELAY) /
|
|
||||||
DemonicGorilla.PROJECTILE_MAGIC_SPEED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (attackStyle == DemonicGorilla.AttackStyle.RANGED)
|
|
||||||
{
|
|
||||||
MemorizedPlayer mp = memorizedPlayers.get(target);
|
|
||||||
WorldArea lastPlayerArea = mp.getLastWorldArea();
|
|
||||||
if (lastPlayerArea != null)
|
|
||||||
{
|
|
||||||
int dist = gorilla.getNpc().getWorldArea().distanceTo(lastPlayerArea);
|
|
||||||
damagesOnTick += (dist + DemonicGorilla.PROJECTILE_RANGED_DELAY) /
|
|
||||||
DemonicGorilla.PROJECTILE_RANGED_SPEED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pendingAttacks.add(new PendingGorillaAttack(gorilla, attackStyle, target, damagesOnTick));
|
|
||||||
}
|
|
||||||
|
|
||||||
gorilla.setNextPosibleAttackStyles(gorilla
|
|
||||||
.getNextPosibleAttackStyles()
|
|
||||||
.stream()
|
|
||||||
.filter(x -> x == attackStyle)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
|
|
||||||
if (gorilla.getNextPosibleAttackStyles().isEmpty())
|
|
||||||
{
|
|
||||||
// Sometimes the gorilla can switch attack style before it's supposed to
|
|
||||||
// if someone was fighting it earlier and then left, so we just
|
|
||||||
// reset the counter in that case.
|
|
||||||
|
|
||||||
gorilla.setNextPosibleAttackStyles(Arrays
|
|
||||||
.stream(DemonicGorilla.ALL_REGULAR_ATTACK_STYLES)
|
|
||||||
.filter(x -> x == attackStyle)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
gorilla.setAttacksUntilSwitch(DemonicGorilla.ATTACKS_PER_SWITCH -
|
|
||||||
(correctPrayer ? 1 : 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkGorillaAttackStyleSwitch(gorilla, protectedStyle);
|
|
||||||
|
|
||||||
int tickCounter = client.getTickCount();
|
|
||||||
gorilla.setNextAttackTick(tickCounter + DemonicGorilla.ATTACK_RATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkGorillaAttacks()
|
|
||||||
{
|
|
||||||
int tickCounter = client.getTickCount();
|
|
||||||
for (DemonicGorilla gorilla : gorillas.values())
|
|
||||||
{
|
|
||||||
Player interacting = (Player)gorilla.getNpc().getInteracting();
|
|
||||||
MemorizedPlayer mp = memorizedPlayers.get(interacting);
|
|
||||||
|
|
||||||
if (gorilla.getLastTickInteracting() != null && interacting == null)
|
|
||||||
{
|
|
||||||
gorilla.setInitiatedCombat(false);
|
|
||||||
}
|
|
||||||
else if (mp != null && mp.getLastWorldArea() != null &&
|
|
||||||
!gorilla.isInitiatedCombat() &&
|
|
||||||
tickCounter < gorilla.getNextAttackTick() &&
|
|
||||||
gorilla.getNpc().getWorldArea().isInMeleeDistance(mp.getLastWorldArea()))
|
|
||||||
{
|
|
||||||
gorilla.setInitiatedCombat(true);
|
|
||||||
gorilla.setNextAttackTick(tickCounter + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int animationId = gorilla.getNpc().getAnimation();
|
|
||||||
|
|
||||||
if (gorilla.isTakenDamageRecently() &&
|
|
||||||
tickCounter >= gorilla.getNextAttackTick() + 4)
|
|
||||||
{
|
|
||||||
// The gorilla was flinched, so its next attack gets delayed
|
|
||||||
gorilla.setNextAttackTick(tickCounter + DemonicGorilla.ATTACK_RATE / 2);
|
|
||||||
gorilla.setInitiatedCombat(true);
|
|
||||||
|
|
||||||
if (mp != null && mp.getLastWorldArea() != null &&
|
|
||||||
!gorilla.getNpc().getWorldArea().isInMeleeDistance(mp.getLastWorldArea()) &&
|
|
||||||
!gorilla.getNpc().getWorldArea().intersectsWith(mp.getLastWorldArea()))
|
|
||||||
{
|
|
||||||
// Gorillas stop meleeing when they get flinched
|
|
||||||
// and the target isn't in melee distance
|
|
||||||
gorilla.setNextPosibleAttackStyles(gorilla
|
|
||||||
.getNextPosibleAttackStyles()
|
|
||||||
.stream()
|
|
||||||
.filter(x -> x != DemonicGorilla.AttackStyle.MELEE)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
checkGorillaAttackStyleSwitch(gorilla, DemonicGorilla.AttackStyle.MELEE,
|
|
||||||
getProtectedStyle(interacting));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (animationId != gorilla.getLastTickAnimation())
|
|
||||||
{
|
|
||||||
if (animationId == AnimationID.DEMONIC_GORILLA_MELEE_ATTACK)
|
|
||||||
{
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.MELEE);
|
|
||||||
}
|
|
||||||
else if (animationId == AnimationID.DEMONIC_GORILLA_MAGIC_ATTACK)
|
|
||||||
{
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.MAGIC);
|
|
||||||
}
|
|
||||||
else if (animationId == AnimationID.DEMONIC_GORILLA_RANGED_ATTACK)
|
|
||||||
{
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.RANGED);
|
|
||||||
}
|
|
||||||
else if (animationId == AnimationID.DEMONIC_GORILLA_AOE_ATTACK && interacting != null)
|
|
||||||
{
|
|
||||||
// Note that AoE animation is the same as prayer switch animation
|
|
||||||
// so we need to check if the prayer was switched or not.
|
|
||||||
// It also does this animation when it spawns, so
|
|
||||||
// we need the interacting != null check.
|
|
||||||
|
|
||||||
if (gorilla.getOverheadIcon() == gorilla.getLastTickOverheadIcon())
|
|
||||||
{
|
|
||||||
// Confirmed, the gorilla used the AoE attack
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.BOULDER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (tickCounter >= gorilla.getNextAttackTick())
|
|
||||||
{
|
|
||||||
gorilla.setChangedPrayerThisTick(true);
|
|
||||||
|
|
||||||
// This part is more complicated because the gorilla may have
|
|
||||||
// used an attack, but the prayer switch animation takes
|
|
||||||
// priority over normal attack animations.
|
|
||||||
|
|
||||||
int projectileId = gorilla.getRecentProjectileId();
|
|
||||||
if (projectileId == ProjectileID.DEMONIC_GORILLA_MAGIC)
|
|
||||||
{
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.MAGIC);
|
|
||||||
}
|
|
||||||
else if (projectileId == ProjectileID.DEMONIC_GORILLA_RANGED)
|
|
||||||
{
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.RANGED);
|
|
||||||
}
|
|
||||||
else if (mp != null)
|
|
||||||
{
|
|
||||||
WorldArea lastPlayerArea = mp.getLastWorldArea();
|
|
||||||
if (lastPlayerArea != null &&
|
|
||||||
interacting != null && recentBoulders.stream()
|
|
||||||
.anyMatch(x -> x.distanceTo(lastPlayerArea) == 0))
|
|
||||||
{
|
|
||||||
// A boulder started falling on the gorillas target,
|
|
||||||
// so we assume it was the gorilla who shot it
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.BOULDER);
|
|
||||||
}
|
|
||||||
else if (!mp.getRecentHitsplats().isEmpty())
|
|
||||||
{
|
|
||||||
// It wasn't any of the three other attacks,
|
|
||||||
// but the player took damage, so we assume
|
|
||||||
// it's a melee attack
|
|
||||||
onGorillaAttack(gorilla, DemonicGorilla.AttackStyle.MELEE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The next attack tick is always delayed if the
|
|
||||||
// gorilla switched prayer
|
|
||||||
gorilla.setNextAttackTick(tickCounter + DemonicGorilla.ATTACK_RATE);
|
|
||||||
gorilla.setChangedPrayerThisTick(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gorilla.getDisabledMeleeMovementForTicks() > 0)
|
|
||||||
{
|
|
||||||
gorilla.setDisabledMeleeMovementForTicks(gorilla.getDisabledMeleeMovementForTicks() - 1);
|
|
||||||
}
|
|
||||||
else if (gorilla.isInitiatedCombat() &&
|
|
||||||
gorilla.getNpc().getInteracting() != null &&
|
|
||||||
!gorilla.isChangedAttackStyleThisTick() &&
|
|
||||||
gorilla.getNextPosibleAttackStyles().size() >= 2 &&
|
|
||||||
gorilla.getNextPosibleAttackStyles().stream()
|
|
||||||
.anyMatch(x -> x == DemonicGorilla.AttackStyle.MELEE))
|
|
||||||
{
|
|
||||||
// If melee is a possibility, we can check if the gorilla
|
|
||||||
// is or isn't moving toward the player to determine if
|
|
||||||
// it is actually attempting to melee or not.
|
|
||||||
// We only run this check if the gorilla is in combat
|
|
||||||
// because otherwise it attempts to travel to melee
|
|
||||||
// distance before attacking its target.
|
|
||||||
|
|
||||||
if (mp != null && mp.getLastWorldArea() != null && gorilla.getLastWorldArea() != null)
|
|
||||||
{
|
|
||||||
WorldArea predictedNewArea = gorilla.getLastWorldArea().calculateNextTravellingPoint(
|
|
||||||
client, mp.getLastWorldArea(), true, x ->
|
|
||||||
{
|
|
||||||
// Gorillas can't normally walk through other gorillas
|
|
||||||
// or other players
|
|
||||||
final WorldArea area1 = new WorldArea(x, 1, 1);
|
|
||||||
return area1 != null &&
|
|
||||||
gorillas.values().stream().noneMatch(y ->
|
|
||||||
{
|
|
||||||
if (y == gorilla)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final WorldArea area2 =
|
|
||||||
y.getNpc().getIndex() < gorilla.getNpc().getIndex() ?
|
|
||||||
y.getNpc().getWorldArea() : y.getLastWorldArea();
|
|
||||||
return area2 != null && area1.intersectsWith(area2);
|
|
||||||
}) &&
|
|
||||||
memorizedPlayers.values().stream().noneMatch(y ->
|
|
||||||
{
|
|
||||||
final WorldArea area2 = y.getLastWorldArea();
|
|
||||||
return area2 != null && area1.intersectsWith(area2);
|
|
||||||
});
|
|
||||||
|
|
||||||
// There is a special case where if a player walked through
|
|
||||||
// a gorilla, or a player walked through another player,
|
|
||||||
// the tiles that were walked through becomes
|
|
||||||
// walkable, but I didn't feel like it's necessary to handle
|
|
||||||
// that special case as it should rarely happen.
|
|
||||||
});
|
|
||||||
if (predictedNewArea != null)
|
|
||||||
{
|
|
||||||
int distance = gorilla.getNpc().getWorldArea().distanceTo(mp.getLastWorldArea());
|
|
||||||
WorldPoint predictedMovement = predictedNewArea.toWorldPoint();
|
|
||||||
if (distance <= DemonicGorilla.MAX_ATTACK_RANGE &&
|
|
||||||
mp != null &&
|
|
||||||
mp.getLastWorldArea().hasLineOfSightTo(client, gorilla.getLastWorldArea()))
|
|
||||||
{
|
|
||||||
if (predictedMovement.distanceTo(gorilla.getLastWorldArea().toWorldPoint()) != 0)
|
|
||||||
{
|
|
||||||
if (predictedMovement.distanceTo(gorilla.getNpc().getWorldLocation()) == 0)
|
|
||||||
{
|
|
||||||
gorilla.setNextPosibleAttackStyles(gorilla
|
|
||||||
.getNextPosibleAttackStyles()
|
|
||||||
.stream()
|
|
||||||
.filter(x -> x == DemonicGorilla.AttackStyle.MELEE)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gorilla.setNextPosibleAttackStyles(gorilla
|
|
||||||
.getNextPosibleAttackStyles()
|
|
||||||
.stream()
|
|
||||||
.filter(x -> x != DemonicGorilla.AttackStyle.MELEE)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (tickCounter >= gorilla.getNextAttackTick() &&
|
|
||||||
gorilla.getRecentProjectileId() == -1 &&
|
|
||||||
recentBoulders.stream().noneMatch(x -> x.distanceTo(mp.getLastWorldArea()) == 0))
|
|
||||||
{
|
|
||||||
gorilla.setNextPosibleAttackStyles(gorilla
|
|
||||||
.getNextPosibleAttackStyles()
|
|
||||||
.stream()
|
|
||||||
.filter(x -> x == DemonicGorilla.AttackStyle.MELEE)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gorilla.isTakenDamageRecently())
|
|
||||||
{
|
|
||||||
gorilla.setInitiatedCombat(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gorilla.getOverheadIcon() != gorilla.getLastTickOverheadIcon())
|
|
||||||
{
|
|
||||||
if (gorilla.isChangedAttackStyleLastTick() ||
|
|
||||||
gorilla.isChangedAttackStyleThisTick())
|
|
||||||
{
|
|
||||||
// Apparently if it changes attack style and changes
|
|
||||||
// prayer on the same tick or 1 tick apart, it won't
|
|
||||||
// be able to move for the next 2 ticks if it attempts
|
|
||||||
// to melee
|
|
||||||
gorilla.setDisabledMeleeMovementForTicks(2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If it didn't change attack style lately,
|
|
||||||
// it's only for the next 1 tick
|
|
||||||
gorilla.setDisabledMeleeMovementForTicks(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gorilla.setLastTickAnimation(gorilla.getNpc().getAnimation());
|
|
||||||
gorilla.setLastWorldArea(gorilla.getNpc().getWorldArea());
|
|
||||||
gorilla.setLastTickInteracting(gorilla.getNpc().getInteracting());
|
|
||||||
gorilla.setTakenDamageRecently(false);
|
|
||||||
gorilla.setChangedPrayerThisTick(false);
|
|
||||||
gorilla.setChangedAttackStyleLastTick(gorilla.isChangedAttackStyleThisTick());
|
|
||||||
gorilla.setChangedAttackStyleThisTick(false);
|
|
||||||
gorilla.setLastTickOverheadIcon(gorilla.getOverheadIcon());
|
|
||||||
gorilla.setRecentProjectileId(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onProjectileMoved(ProjectileMoved event)
|
|
||||||
{
|
|
||||||
Projectile projectile = event.getProjectile();
|
|
||||||
int projectileId = projectile.getId();
|
|
||||||
if (projectileId != ProjectileID.DEMONIC_GORILLA_RANGED &&
|
|
||||||
projectileId != ProjectileID.DEMONIC_GORILLA_MAGIC &&
|
|
||||||
projectileId != ProjectileID.DEMONIC_GORILLA_BOULDER)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The event fires once before the projectile starts moving,
|
|
||||||
// and we only want to check each projectile once
|
|
||||||
if (client.getGameCycle() >= projectile.getStartMovementCycle())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (projectileId == ProjectileID.DEMONIC_GORILLA_BOULDER)
|
|
||||||
{
|
|
||||||
recentBoulders.add(WorldPoint.fromLocal(client, event.getPosition()));
|
|
||||||
}
|
|
||||||
else if (projectileId == ProjectileID.DEMONIC_GORILLA_MAGIC ||
|
|
||||||
projectileId == ProjectileID.DEMONIC_GORILLA_RANGED)
|
|
||||||
{
|
|
||||||
WorldPoint projectileSourcePosition = WorldPoint.fromLocal(
|
|
||||||
client, projectile.getX1(), projectile.getY1(), client.getPlane());
|
|
||||||
for (DemonicGorilla gorilla : gorillas.values())
|
|
||||||
{
|
|
||||||
if (gorilla.getNpc().getWorldLocation().distanceTo(projectileSourcePosition) == 0)
|
|
||||||
{
|
|
||||||
gorilla.setRecentProjectileId(projectile.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkPendingAttacks()
|
|
||||||
{
|
|
||||||
Iterator<PendingGorillaAttack> it = pendingAttacks.iterator();
|
|
||||||
int tickCounter = client.getTickCount();
|
|
||||||
while (it.hasNext())
|
|
||||||
{
|
|
||||||
PendingGorillaAttack attack = it.next();
|
|
||||||
if (tickCounter >= attack.getFinishesOnTick())
|
|
||||||
{
|
|
||||||
boolean shouldDecreaseCounter = false;
|
|
||||||
DemonicGorilla gorilla = attack.getAttacker();
|
|
||||||
MemorizedPlayer target = memorizedPlayers.get(attack.getTarget());
|
|
||||||
if (target == null)
|
|
||||||
{
|
|
||||||
// Player went out of memory, so assume the hit was a 0
|
|
||||||
shouldDecreaseCounter = true;
|
|
||||||
}
|
|
||||||
else if (target.getRecentHitsplats().isEmpty())
|
|
||||||
{
|
|
||||||
// No hitsplats was applied. This may happen in some cases
|
|
||||||
// where the player was out of memory while the
|
|
||||||
// projectile was travelling. So we assume the hit was a 0.
|
|
||||||
shouldDecreaseCounter = true;
|
|
||||||
}
|
|
||||||
else if (target.getRecentHitsplats().stream()
|
|
||||||
.anyMatch(x -> x.getHitsplatType() == Hitsplat.HitsplatType.BLOCK))
|
|
||||||
{
|
|
||||||
// A blue hitsplat appeared, so we assume the gorilla hit a 0
|
|
||||||
shouldDecreaseCounter = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldDecreaseCounter)
|
|
||||||
{
|
|
||||||
gorilla.setAttacksUntilSwitch(gorilla.getAttacksUntilSwitch() - 1);
|
|
||||||
checkGorillaAttackStyleSwitch(gorilla);
|
|
||||||
}
|
|
||||||
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePlayers()
|
|
||||||
{
|
|
||||||
for (MemorizedPlayer mp : memorizedPlayers.values())
|
|
||||||
{
|
|
||||||
mp.setLastWorldArea(mp.getPlayer().getWorldArea());
|
|
||||||
mp.getRecentHitsplats().clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onHitsplatApplied(HitsplatApplied event)
|
|
||||||
{
|
|
||||||
if (gorillas.isEmpty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getActor() instanceof Player)
|
|
||||||
{
|
|
||||||
Player player = (Player)event.getActor();
|
|
||||||
MemorizedPlayer mp = memorizedPlayers.get(player);
|
|
||||||
if (mp != null)
|
|
||||||
{
|
|
||||||
mp.getRecentHitsplats().add(event.getHitsplat());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event.getActor() instanceof NPC)
|
|
||||||
{
|
|
||||||
DemonicGorilla gorilla = gorillas.get(event.getActor());
|
|
||||||
Hitsplat.HitsplatType hitsplatType = event.getHitsplat().getHitsplatType();
|
|
||||||
if (gorilla != null && (hitsplatType == Hitsplat.HitsplatType.BLOCK ||
|
|
||||||
hitsplatType == Hitsplat.HitsplatType.DAMAGE))
|
|
||||||
{
|
|
||||||
gorilla.setTakenDamageRecently(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onGameStateChanged(GameStateChanged event)
|
|
||||||
{
|
|
||||||
GameState gs = event.getGameState();
|
|
||||||
if (gs == GameState.LOGGING_IN ||
|
|
||||||
gs == GameState.CONNECTION_LOST ||
|
|
||||||
gs == GameState.HOPPING)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onPlayerSpawned(PlayerSpawned event)
|
|
||||||
{
|
|
||||||
if (gorillas.isEmpty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
memorizedPlayers.put(player, new MemorizedPlayer(player));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onPlayerDespawned(PlayerDespawned event)
|
|
||||||
{
|
|
||||||
if (gorillas.isEmpty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memorizedPlayers.remove(event.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onNpcSpawned(NpcSpawned event)
|
|
||||||
{
|
|
||||||
NPC npc = event.getNpc();
|
|
||||||
if (isNpcGorilla(npc.getId()))
|
|
||||||
{
|
|
||||||
if (gorillas.isEmpty())
|
|
||||||
{
|
|
||||||
// Players are not kept track of when there are no gorillas in
|
|
||||||
// memory, so we need to add the players that were already in memory.
|
|
||||||
resetPlayers();
|
|
||||||
}
|
|
||||||
|
|
||||||
gorillas.put(npc, new DemonicGorilla(npc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onNpcDespawned(NpcDespawned event)
|
|
||||||
{
|
|
||||||
if (gorillas.remove(event.getNpc()) != null && gorillas.isEmpty())
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onGameTick(GameTick event)
|
|
||||||
{
|
|
||||||
checkGorillaAttacks();
|
|
||||||
checkPendingAttacks();
|
|
||||||
updatePlayers();
|
|
||||||
recentBoulders.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.demonicgorilla;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.runelite.api.Hitsplat;
|
|
||||||
import net.runelite.api.Player;
|
|
||||||
import net.runelite.api.coords.WorldArea;
|
|
||||||
|
|
||||||
public class MemorizedPlayer
|
|
||||||
{
|
|
||||||
@Getter
|
|
||||||
private Player player;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private WorldArea lastWorldArea;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private List<Hitsplat> recentHitsplats;
|
|
||||||
|
|
||||||
public MemorizedPlayer(Player player)
|
|
||||||
{
|
|
||||||
this.player = player;
|
|
||||||
this.recentHitsplats = new ArrayList<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.demonicgorilla;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.Player;
|
|
||||||
|
|
||||||
public class PendingGorillaAttack
|
|
||||||
{
|
|
||||||
@Getter
|
|
||||||
private DemonicGorilla attacker;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private DemonicGorilla.AttackStyle attackStyle;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private Player target;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private int finishesOnTick;
|
|
||||||
|
|
||||||
public PendingGorillaAttack(DemonicGorilla attacker, DemonicGorilla.AttackStyle attackStyle,
|
|
||||||
Player target, int finishesOnTick)
|
|
||||||
{
|
|
||||||
this.attacker = attacker;
|
|
||||||
this.attackStyle = attackStyle;
|
|
||||||
this.target = target;
|
|
||||||
this.finishesOnTick = finishesOnTick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user