Merge pull request #369 from sdburns1998/NPCStats-damagedrop

Plugin: xp drop change damage -> scraped npcstats and xpmodifier
This commit is contained in:
Lucwousin
2019-05-27 14:09:24 +02:00
committed by GitHub
14 changed files with 36108 additions and 1356 deletions

View File

@@ -32,6 +32,13 @@ import net.runelite.client.config.ConfigItem;
@ConfigGroup("xpdrop")
public interface XpDropConfig extends Config
{
enum DamageMode
{
NONE,
ABOVE_OPPONENT,
IN_XP_DROP
}
@ConfigItem(
keyName = "hideSkillIcons",
name = "Hide skill icons",
@@ -93,9 +100,9 @@ public interface XpDropConfig extends Config
description = "Show what you hit next to the XP drop",
position = 5
)
default boolean showDamage()
default DamageMode showDamage()
{
return false;
return DamageMode.NONE;
}
@ConfigItem(

View File

@@ -51,7 +51,7 @@ class XpDropOverlay extends Overlay
@Override
public Dimension render(Graphics2D graphics)
{
if (config.showDamage())
if (plugin.getTickShow() > 0)
{
final Actor opponent = plugin.getLastOpponent();
if (opponent != null)

View File

@@ -1,4 +1,6 @@
/*
* Copyright (c) 2019, Owain van Brakel <https://github.com/Owain94>
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* Copyright (c) 2018, Cameron <https://github.com/noremac201>, SoyChai <https://github.com/SoyChai>
* All rights reserved.
*
@@ -25,8 +27,6 @@
package net.runelite.client.plugins.experiencedrop;
import com.google.inject.Provides;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Map;
@@ -36,43 +36,29 @@ import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.NPC;
import net.runelite.api.Player;
import static net.runelite.api.ScriptID.XPDROP_DISABLED;
import net.runelite.api.Skill;
import net.runelite.api.SpriteID;
import net.runelite.api.VarPlayer;
import net.runelite.api.Varbits;
import net.runelite.api.WorldType;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.ExperienceChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.InteractingChanged;
import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.WidgetHiddenChanged;
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.eventbus.Subscribe;
import net.runelite.client.game.HiscoreManager;
import net.runelite.client.game.NPCManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.attackstyles.AttackStyle;
import static net.runelite.client.plugins.attackstyles.AttackStyle.ACCURATE;
import static net.runelite.client.plugins.attackstyles.AttackStyle.AGGRESSIVE;
import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING;
import static net.runelite.client.plugins.attackstyles.AttackStyle.CONTROLLED;
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE;
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE_CASTING;
import static net.runelite.client.plugins.attackstyles.AttackStyle.LONGRANGE;
import static net.runelite.client.plugins.attackstyles.AttackStyle.OTHER;
import static net.runelite.client.plugins.attackstyles.AttackStyle.RANGING;
import net.runelite.client.plugins.attackstyles.WeaponType;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.Text;
import net.runelite.http.api.hiscore.HiscoreEndpoint;
import net.runelite.http.api.hiscore.HiscoreResult;
import net.runelite.client.util.ColorUtil;
@PluginDescriptor(
name = "XP Drop",
@@ -82,7 +68,8 @@ import net.runelite.http.api.hiscore.HiscoreResult;
public class XpDropPlugin extends Plugin
{
private static final int XPDROP_PADDING = 2; // space between xp drop icons
private static final Duration WAIT = Duration.ofSeconds(5);
private static final double HITPOINT_RATIO = 1.33; // Base rate of hp xp per point damage
private static final double DMM_MULTIPLIER_RATIO = 10;
@Inject
private Client client;
@@ -90,29 +77,8 @@ public class XpDropPlugin extends Plugin
@Inject
private XpDropConfig config;
private int tickCounter = 0;
private int previousExpGained;
private boolean hasHit = false;
private boolean hasDropped = false;
private boolean correctPrayer;
private Skill lastSkill = null;
private Map<Skill, Integer> previousSkillExpTable = new EnumMap<>(Skill.class);
private PrayerType currentTickPrayer;
private AttackStyle attackStyle;
private int attackStyleVarbit = -1;
private int equippedWeaponTypeVarbit = -1;
private int castingModeVarbit = -1;
private int opponentHealth = -1;
private int xpGains = 0;
private AttackStyle[] offensiveStyles = {ACCURATE, AGGRESSIVE, DEFENSIVE, CONTROLLED, RANGING, LONGRANGE, CASTING, DEFENSIVE_CASTING};
@Getter(AccessLevel.PACKAGE)
private int damage = 0;
@Getter(AccessLevel.PACKAGE)
private Actor lastOpponent;
private Instant lastTime;
@Inject
private NPCManager npcManager;
@Inject
private OverlayManager overlayManager;
@@ -120,11 +86,23 @@ public class XpDropPlugin extends Plugin
@Inject
private XpDropOverlay overlay;
@Inject
private NPCManager npcManager;
@Getter(AccessLevel.PACKAGE)
private int damage = 0;
@Inject
private HiscoreManager hiscoreManager;
@Getter(AccessLevel.PACKAGE)
private int tickShow = 0;
@Getter(AccessLevel.PACKAGE)
private Actor lastOpponent;
private int tickCounter = 0;
private int previousExpGained;
private boolean hasDropped = false;
private boolean correctPrayer;
private Skill lastSkill = null;
private Map<Skill, Integer> previousSkillExpTable = new EnumMap<>(Skill.class);
private PrayerType currentTickPrayer;
private XpDropConfig.DamageMode damageMode;
@Provides
XpDropConfig provideConfig(ConfigManager configManager)
@@ -135,20 +113,56 @@ public class XpDropPlugin extends Plugin
@Override
protected void startUp() throws Exception
{
lastOpponent = null;
overlayManager.add(overlay);
if (client.getGameState() == GameState.LOGGED_IN)
damageMode = config.showDamage();
if (damageMode == XpDropConfig.DamageMode.ABOVE_OPPONENT)
{
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
updateAttackStyle(
equippedWeaponTypeVarbit,
attackStyleVarbit,
castingModeVarbit);
overlayManager.add(overlay);
}
}
@Override
protected void shutDown() throws Exception
{
overlayManager.remove(overlay);
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals("xpdrop"))
{
return;
}
if (damageMode != XpDropConfig.DamageMode.ABOVE_OPPONENT)
{
damageMode = config.showDamage();
if (damageMode == XpDropConfig.DamageMode.ABOVE_OPPONENT)
{
overlayManager.add(overlay);
}
}
else
{
damageMode = config.showDamage();
if (damageMode != XpDropConfig.DamageMode.ABOVE_OPPONENT)
{
overlayManager.remove(overlay);
}
}
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
damage = 0;
tickShow = 0;
}
@Subscribe
public void onWidgetHiddenChanged(WidgetHiddenChanged event)
{
@@ -277,40 +291,11 @@ public class XpDropPlugin extends Plugin
@Subscribe
public void onGameTick(GameTick tick)
{
// Detect hitting a 0
if (lastOpponent != null)
{
int health = calculateHealth(lastOpponent);
if (health != -1 && opponentHealth != -1 && health == opponentHealth && hasHit)
{
damage = 0;
hasHit = false;
}
}
lastOpponent = client.getLocalPlayer().getInteracting();
// Handle getting XP gains
if (hasDropped)
if (tickShow > 0)
{
if (xpGains != 0 && attackStyle.getSkills().length > 1 && attackStyle != LONGRANGE)
{
damage = (int) (xpGains / (attackStyle.getSkills().length * 1.3));
}
else if (xpGains != 0)
{
damage = xpGains / 4;
}
xpGains = 0;
hasDropped = false;
}
// Clear opponent
if (lastOpponent != null && lastTime != null && client.getLocalPlayer().getInteracting() == null)
{
if (Duration.between(lastTime, Instant.now()).compareTo(WAIT) > 0)
{
lastOpponent = null;
}
tickShow--;
}
currentTickPrayer = getActivePrayerType();
@@ -350,120 +335,95 @@ public class XpDropPlugin extends Plugin
Integer previous = previousSkillExpTable.put(skill, xp);
if (previous != null)
{
opponentHealth = calculateHealth(lastOpponent);
previousExpGained = xp - previous;
if (skill != Skill.HITPOINTS && Arrays.stream(offensiveStyles).anyMatch(attackStyle::equals))
{
xpGains += previousExpGained;
}
hasDropped = true;
hasHit = true;
}
}
private void updateAttackStyle(int equippedWeaponType, int attackStyleIndex, int castingMode)
{
AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponType).getAttackStyles();
if (attackStyleIndex < attackStyles.length)
{
attackStyle = attackStyles[attackStyleIndex];
if (attackStyle == null)
{
attackStyle = OTHER;
}
else if ((attackStyle == CASTING) && (castingMode == 1))
{
attackStyle = DEFENSIVE_CASTING;
}
}
}
@Subscribe
public void onInteractingChanged(InteractingChanged event)
public void onScriptCallbackEvent(ScriptCallbackEvent e)
{
if (event.getSource() != client.getLocalPlayer())
if (config.showDamage() == XpDropConfig.DamageMode.NONE)
{
return;
}
Actor opponent = event.getTarget();
final String eventName = e.getEventName();
if (opponent == null)
// Handles Fake XP drops (Ironman, DMM Cap, 200m xp, etc)
if (eventName.equals("fakeXpDrop"))
{
lastTime = Instant.now();
return;
}
else if (opponent.getName().equalsIgnoreCase("fishing spot"))
{
lastTime = Instant.now().minus(WAIT);
return;
}
final int[] intStack = client.getIntStack();
final int intStackSize = client.getIntStackSize();
damage = 0;
lastOpponent = opponent;
opponentHealth = calculateHealth(opponent);
}
final int skillId = intStack[intStackSize - 2];
final Skill skill = Skill.values()[skillId];
private int calculateHealth(Actor target)
{
if (target == null || target.getName() == null)
{
return -1;
}
final int healthScale = target.getHealth();
final int healthRatio = target.getHealthRatio();
final String targetName = Text.removeTags(target.getName());
Integer maxHealth = -1;
if (target instanceof NPC)
{
maxHealth = npcManager.getHealth(targetName, target.getCombatLevel());
}
else if (target instanceof Player)
{
final HiscoreResult hiscoreResult = hiscoreManager.lookupAsync(targetName, HiscoreEndpoint.NORMAL);
if (hiscoreResult != null)
if (skill.equals(Skill.HITPOINTS))
{
final int hp = hiscoreResult.getHitpoints().getLevel();
if (hp > 0)
{
maxHealth = hp;
}
final int exp = intStack[intStackSize - 1];
calculateDamageDealt(exp);
}
}
if (healthRatio < 0 || healthScale <= 0 || maxHealth == null)
client.setIntStackSize(intStackSize - 2);
}
else if (eventName.equals("hpXpGained"))
{
return -1;
}
final int[] intStack = client.getIntStack();
final int intStackSize = client.getIntStackSize();
return (int) ((maxHealth * healthRatio / healthScale) + 0.5f);
final int exp = intStack[intStackSize - 1];
calculateDamageDealt(exp);
}
else if (eventName.equals("xpDropAddDamage") &&
damageMode == XpDropConfig.DamageMode.IN_XP_DROP &&
damage > 0)
{
final String[] stringStack = client.getStringStack();
final int stringStackSize = client.getStringStackSize();
StringBuilder builder = new StringBuilder()
.append(stringStack[stringStackSize - 1])
.append(ColorUtil.colorTag(config.getDamageColor()))
.append(" (").append(damage).append(")");
stringStack[stringStackSize - 1] = builder.toString();
}
}
@Subscribe
public void onVarbitChanged(VarbitChanged event)
private void calculateDamageDealt(int diff)
{
if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE))
double damageDealt = diff / HITPOINT_RATIO;
// DeadMan mode has an XP modifier
if (client.getWorldType().contains(WorldType.DEADMAN))
{
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit,
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
damageDealt = damageDealt / DMM_MULTIPLIER_RATIO;
}
if (equippedWeaponTypeVarbit == -1 || equippedWeaponTypeVarbit != client.getVar(Varbits.EQUIPPED_WEAPON_TYPE))
// Some NPCs have an XP modifier, account for it here.
Actor a = client.getLocalPlayer().getInteracting();
if (!(a instanceof NPC) && !(a instanceof Player))
{
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
updateAttackStyle(equippedWeaponTypeVarbit, client.getVar(VarPlayer.ATTACK_STYLE),
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
// If we are interacting with nothing we may have clicked away at the perfect time fall back to last tick
if (!(lastOpponent instanceof NPC) && !(lastOpponent instanceof Player))
{
damage = (int) Math.rint(damageDealt);
tickShow = 3;
return;
}
a = lastOpponent;
}
if (castingModeVarbit == -1 || castingModeVarbit != client.getVar(Varbits.DEFENSIVE_CASTING_MODE))
if (a instanceof Player)
{
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), client.getVar(VarPlayer.ATTACK_STYLE),
castingModeVarbit);
damage = (int) Math.rint(damageDealt);
tickShow = 3;
return;
}
NPC target = (NPC) a;
damage = (int) Math.rint(damageDealt / npcManager.getXpModifier(target.getId()));
tickShow = 3;
}
}

View File

@@ -114,7 +114,7 @@ class OpponentInfoOverlay extends Overlay
lastMaxHealth = null;
if (opponent instanceof NPC)
{
lastMaxHealth = npcManager.getHealth(opponentName, opponent.getCombatLevel());
lastMaxHealth = npcManager.getHealth(((NPC) opponent).getId());
}
else if (opponent instanceof Player)
{

View File

@@ -39,7 +39,6 @@ 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;
import net.runelite.client.util.Text;
class TargetWeaknessOverlay extends Overlay
{
@@ -99,8 +98,7 @@ class TargetWeaknessOverlay extends Overlay
final int healthScale = target.getHealth();
final int healthRatio = target.getHealthRatio();
final String targetName = Text.removeTags(target.getName());
final Integer maxHealth = npcManager.getHealth(targetName, target.getCombatLevel());
final Integer maxHealth = npcManager.getHealth(target.getId());
if (healthRatio < 0 || healthScale <= 0 || maxHealth == null)
{

View File

@@ -326,7 +326,7 @@ public class XpTrackerPlugin extends Plugin
if (interacting instanceof NPC && COMBAT.contains(skill))
{
final NPC npc = (NPC) interacting;
xpState.updateNpcExperience(skill, npc, npcManager.getHealth(npc.getName(), npc.getCombatLevel()));
xpState.updateNpcExperience(skill, npc, npcManager.getHealth(npc.getId()));
}
final XpUpdateResult updateResult = xpState.updateSkill(skill, currentXp, startGoalXp, endGoalXp);
@@ -358,7 +358,7 @@ public class XpTrackerPlugin extends Plugin
for (Skill skill : COMBAT)
{
final XpUpdateResult updateResult = xpState.updateNpcKills(skill, npc, npcManager.getHealth(npc.getName(), npc.getCombatLevel()));
final XpUpdateResult updateResult = xpState.updateNpcKills(skill, npc, npcManager.getHealth(npc.getId()));
final boolean updated = XpUpdateResult.UPDATED.equals(updateResult);
xpPanel.updateSkillExperience(updated, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill));
}