npcstatus: Add custom attack speed option. Some fixes/improvements.

Implement custom attack speed as config option, useful because the npc
stats data we have from wiki isn't 100% correct, or isn't even there.
Add minimum attackrange of 1.
Enable timer when the player is interacting with their target.
Add default attack speed of 4 when wiki doesn't provide the data.
Fix splash flinching while using a better method to implement it, using
the function "onSpotAnimationChanged".
Remove deprecated variable "lastspotanimation".
Remove unused variable "lastTickUpdate".
This commit is contained in:
GeChallengeM
2019-07-09 22:50:23 +02:00
parent 9a98431ddb
commit 68b623e5b7
4 changed files with 91 additions and 32 deletions

View File

@@ -52,8 +52,6 @@ class MemorizedNPC
private WorldArea lastnpcarea; private WorldArea lastnpcarea;
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private Actor lastinteracted; private Actor lastinteracted;
@Setter(AccessLevel.PACKAGE)
private int lastspotanimation;
MemorizedNPC(final NPC npc, final int attackSpeed, final WorldArea worldArea) MemorizedNPC(final NPC npc, final int attackSpeed, final WorldArea worldArea)
{ {
@@ -67,7 +65,6 @@ class MemorizedNPC
this.status = Status.OUT_OF_COMBAT; this.status = Status.OUT_OF_COMBAT;
this.lastnpcarea = worldArea; this.lastnpcarea = worldArea;
this.lastinteracted = null; this.lastinteracted = null;
this.lastspotanimation = -1;
} }
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)

View File

@@ -27,17 +27,49 @@ package net.runelite.client.plugins.npcstatus;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Range;
@ConfigGroup("npcstatus") @ConfigGroup("npcstatus")
public interface NpcStatusConfig extends Config public interface NpcStatusConfig extends Config
{ {
@Range(
min = 1
)
@ConfigItem( @ConfigItem(
keyName = "AttackRange", keyName = "AttackRange",
name = "NPC Attack range", name = "NPC attack range",
description = "The attack range of the NPC" description = "The attack range of the NPC.",
position = 1
) )
default int getRange() default int getRange()
{ {
return 1; return 1;
} }
@ConfigItem(
keyName = "CustomAttSpeedEnabled",
name = "Custom attack speed",
description = "Use this if the timer is wrong.",
position = 2
)
default boolean isCustomAttSpeed()
{
return false;
}
@Range(
min = 1
)
@ConfigItem(
keyName = "CustomAttSpeed",
name = "Custom NPC att speed",
description = "The attack speed of the NPC (amount of ticks between their attacks).",
position = 3,
hidden = true,
unhide = "CustomAttSpeedEnabled"
)
default int getCustomAttSpeed()
{
return 4;
}
} }

View File

@@ -55,7 +55,7 @@ public class NpcStatusOverlay extends Overlay
{ {
for (MemorizedNPC npc : plugin.getMemorizedNPCs()) for (MemorizedNPC npc : plugin.getMemorizedNPCs())
{ {
if (npc.getNpc().getInteracting() == null) if ((npc.getNpc().getInteracting() == null && client.getLocalPlayer().getInteracting() == null))
{ {
continue; continue;
} }

View File

@@ -25,7 +25,6 @@
package net.runelite.client.plugins.npcstatus; package net.runelite.client.plugins.npcstatus;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -46,6 +45,7 @@ import net.runelite.api.events.GameTick;
import net.runelite.api.events.HitsplatApplied; import net.runelite.api.events.HitsplatApplied;
import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.NpcSpawned;
import net.runelite.api.events.SpotAnimationChanged;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.NPCManager; import net.runelite.client.game.NPCManager;
@@ -65,9 +65,6 @@ import net.runelite.client.ui.overlay.OverlayManager;
@Singleton @Singleton
public class NpcStatusPlugin extends Plugin public class NpcStatusPlugin extends Plugin
{ {
@Getter(AccessLevel.PACKAGE)
private final Set<MemorizedNPC> memorizedNPCs = new HashSet<>();
@Inject @Inject
private Client client; private Client client;
@@ -84,12 +81,17 @@ public class NpcStatusPlugin extends Plugin
private NpcStatusOverlay npcStatusOverlay; private NpcStatusOverlay npcStatusOverlay;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private Instant lastTickUpdate; private final Set<MemorizedNPC> memorizedNPCs = new HashSet<>();
private WorldArea lastPlayerLocation; @Getter(AccessLevel.PACKAGE)
private boolean isCustomAttSpeed;
private int getCustomAttSpeed;
private int getRange; private int getRange;
private WorldArea lastPlayerLocation;
@Provides @Provides
NpcStatusConfig provideConfig(ConfigManager configManager) NpcStatusConfig provideConfig(ConfigManager configManager)
{ {
@@ -120,7 +122,12 @@ public class NpcStatusPlugin extends Plugin
{ {
return; return;
} }
memorizedNPCs.add(new MemorizedNPC(npc, npcManager.getAttackSpeed(npc.getId()), npc.getWorldArea())); int AttackSpeed = npcManager.getAttackSpeed(npc.getId());
if (AttackSpeed == 0)
{
AttackSpeed = 4;
}
memorizedNPCs.add(new MemorizedNPC(npc, AttackSpeed, npc.getWorldArea()));
} }
@Subscribe @Subscribe
@@ -156,18 +163,48 @@ public class NpcStatusPlugin extends Plugin
{ {
mn.setStatus(MemorizedNPC.Status.FLINCHING); mn.setStatus(MemorizedNPC.Status.FLINCHING);
mn.setCombatTimerEnd(-1); mn.setCombatTimerEnd(-1);
mn.setFlinchTimerEnd(client.getTickCount() + mn.getAttackSpeed() / 2 + 1); if (isCustomAttSpeed())
{
mn.setFlinchTimerEnd(client.getTickCount() + getCustomAttSpeed / 2 + 1);
}
else
{
mn.setFlinchTimerEnd(client.getTickCount() + mn.getAttackSpeed() / 2 + 1);
}
} }
} }
} }
} }
@Subscribe
public void onSpotAnimationChanged(SpotAnimationChanged event)
{
if ((event.getActor().getSpotAnimation() == GraphicID.SPLASH) && event.getActor() instanceof NPC)
{
for (MemorizedNPC mn : memorizedNPCs)
{
if (mn.getStatus() == MemorizedNPC.Status.OUT_OF_COMBAT || (mn.getStatus() == MemorizedNPC.Status.IN_COMBAT && mn.getCombatTimerEnd() - client.getTickCount() < 2) || mn.getLastinteracted() == null)
{
mn.setStatus(MemorizedNPC.Status.FLINCHING);
mn.setCombatTimerEnd(-1);
if (isCustomAttSpeed())
{
mn.setFlinchTimerEnd(client.getTickCount() + getCustomAttSpeed / 2 + 2);
}
else
{
mn.setFlinchTimerEnd(client.getTickCount() + mn.getAttackSpeed() / 2 + 2);
}
}
}
}
}
private void checkStatus() private void checkStatus()
{ {
for (MemorizedNPC npc : memorizedNPCs) for (MemorizedNPC npc : memorizedNPCs)
{ {
final int ATTACK_SPEED = npc.getAttackSpeed();
final double CombatTime = npc.getCombatTimerEnd() - client.getTickCount(); final double CombatTime = npc.getCombatTimerEnd() - client.getTickCount();
final double FlinchTime = npc.getFlinchTimerEnd() - client.getTickCount(); final double FlinchTime = npc.getFlinchTimerEnd() - client.getTickCount();
if (npc.getNpc().getWorldArea() == null) if (npc.getNpc().getWorldArea() == null)
@@ -176,19 +213,6 @@ public class NpcStatusPlugin extends Plugin
} }
if (npc.getNpc().getInteracting() == client.getLocalPlayer()) if (npc.getNpc().getInteracting() == client.getLocalPlayer())
{ {
if (npc.getLastspotanimation() == GraphicID.SPLASH && npc.getNpc().getSpotAnimation() == GraphicID.SPLASH) //For splash flinching
{
npc.setLastspotanimation(-1);
if ((npc.getStatus() == MemorizedNPC.Status.OUT_OF_COMBAT) || npc.getLastinteracted() == null)
{
npc.setStatus(MemorizedNPC.Status.FLINCHING);
npc.setCombatTimerEnd(-1);
npc.setFlinchTimerEnd(client.getTickCount() + ATTACK_SPEED / 2 + 1);
npc.setLastnpcarea(npc.getNpc().getWorldArea());
npc.setLastinteracted(npc.getNpc().getInteracting());
continue;
}
}
//Checks: will the NPC attack this tick? //Checks: will the NPC attack this tick?
if (((npc.getNpc().getWorldArea().canMelee(client, lastPlayerLocation) && this.getRange == 1) //Separate mechanics for meleerange-only NPC's because they have extra collisiondata checks (fences etc.) and can't attack diagonally if (((npc.getNpc().getWorldArea().canMelee(client, lastPlayerLocation) && this.getRange == 1) //Separate mechanics for meleerange-only NPC's because they have extra collisiondata checks (fences etc.) and can't attack diagonally
|| (lastPlayerLocation.hasLineOfSightTo(client, npc.getNpc().getWorldArea()) && npc.getNpc().getWorldArea().distanceTo(lastPlayerLocation) <= this.getRange && this.getRange > 1)) || (lastPlayerLocation.hasLineOfSightTo(client, npc.getNpc().getWorldArea()) && npc.getNpc().getWorldArea().distanceTo(lastPlayerLocation) <= this.getRange && this.getRange > 1))
@@ -196,11 +220,17 @@ public class NpcStatusPlugin extends Plugin
&& npc.getNpc().getAnimation() != -1 //Failsafe, attacking NPC's always have an animation. && npc.getNpc().getAnimation() != -1 //Failsafe, attacking NPC's always have an animation.
&& !(npc.getLastnpcarea().distanceTo(lastPlayerLocation) == 0 && npc.getLastnpcarea() != npc.getNpc().getWorldArea())) //Weird mechanic: NPC's can't attack on the tick they do a random move && !(npc.getLastnpcarea().distanceTo(lastPlayerLocation) == 0 && npc.getLastnpcarea() != npc.getNpc().getWorldArea())) //Weird mechanic: NPC's can't attack on the tick they do a random move
{ {
npc.setCombatTimerEnd(client.getTickCount() + ATTACK_SPEED + 8);
npc.setStatus(MemorizedNPC.Status.IN_COMBAT_DELAY); npc.setStatus(MemorizedNPC.Status.IN_COMBAT_DELAY);
npc.setLastnpcarea(npc.getNpc().getWorldArea()); npc.setLastnpcarea(npc.getNpc().getWorldArea());
npc.setLastspotanimation(npc.getNpc().getSpotAnimation());
npc.setLastinteracted(npc.getNpc().getInteracting()); npc.setLastinteracted(npc.getNpc().getInteracting());
if (isCustomAttSpeed())
{
npc.setCombatTimerEnd(client.getTickCount() + getCustomAttSpeed + 8);
}
else
{
npc.setCombatTimerEnd(client.getTickCount() + npc.getAttackSpeed() + 8);
}
continue; continue;
} }
} }
@@ -226,7 +256,6 @@ public class NpcStatusPlugin extends Plugin
} }
} }
npc.setLastnpcarea(npc.getNpc().getWorldArea()); npc.setLastnpcarea(npc.getNpc().getWorldArea());
npc.setLastspotanimation(npc.getNpc().getSpotAnimation());
npc.setLastinteracted(npc.getNpc().getInteracting()); npc.setLastinteracted(npc.getNpc().getInteracting());
} }
} }
@@ -234,7 +263,6 @@ public class NpcStatusPlugin extends Plugin
@Subscribe @Subscribe
public void onGameTick(GameTick event) public void onGameTick(GameTick event)
{ {
lastTickUpdate = Instant.now();
checkStatus(); checkStatus();
lastPlayerLocation = client.getLocalPlayer().getWorldArea(); lastPlayerLocation = client.getLocalPlayer().getWorldArea();
} }
@@ -248,5 +276,7 @@ public class NpcStatusPlugin extends Plugin
} }
this.getRange = config.getRange(); this.getRange = config.getRange();
this.isCustomAttSpeed = config.isCustomAttSpeed();
this.getCustomAttSpeed = config.getCustomAttSpeed();
} }
} }