project: add missing api components (#2935)

* api: add missing api components

api: add missing api components

* oops

* .
This commit is contained in:
Kyle
2021-02-22 23:59:40 +00:00
committed by GitHub
parent 0d33d3d356
commit b58482938e
10 changed files with 949 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package net.runelite.api.events;
import lombok.Value;
import net.runelite.api.Player;
/**
* This will fire whenever the {@link net.runelite.api.PlayerComposition} hash changes.
*/
@Value
public class PlayerCompositionChanged
{
Player player;
}

View File

@@ -493,6 +493,9 @@ public enum WidgetInfo
PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER),
PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE),
PVP_FOG_OVERLAY(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.FOG_OVERLAY),
PVP_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.PVP_WIDGET_CONTAINER),
PVP_WILDERNESS_LEVEL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.WILDERNESS_LEVEL),
PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO),

View File

@@ -0,0 +1,33 @@
package com.openosrs.client.events;
import lombok.Value;
import net.runelite.api.Player;
import com.openosrs.client.game.AttackStyle;
/**
* This will fire when {@link com.openosrs.client.game.PlayerManager} detects
* a change in the player appearance that resulted in the shifting of an attack style.
* For example, ranged str went to 0, but melee str went to 108.
*/
@Value
public class AttackStyleChanged
{
/**
* The player that changed styles.
*/
Player player;
/**
* Can be Unknown(nullable)
*
* @see com.openosrs.client.game.AttackStyle
*/
AttackStyle oldStyle;
/**
* Can be Unknown(nullable)
*
* @see com.openosrs.client.game.AttackStyle
*/
AttackStyle newStyle;
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* 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 com.openosrs.client.game;
import java.awt.Color;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.Prayer;
@AllArgsConstructor
@Getter
public enum AttackStyle
{
MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC),
RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES),
MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE),
UNKNOWN("Unknown", Color.WHITE, null);
private String name;
private Color color;
private Prayer prayer;
}

View File

@@ -0,0 +1,24 @@
package com.openosrs.client.game;
import lombok.Value;
@Value
public class CombatStats
{
int magicAttack;
int magicDefence;
int magicStr;
int meleeAtkCrush;
int meleeAtkSlash;
int meleeAtkStab;
int meleeAttack;
int meleeDefCrush;
int meleeDefence;
int meleeDefSlash;
int meleeDefStab;
int meleeStr;
int rangeAttack;
int rangeDefence;
int rangeStr;
int speed;
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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 com.openosrs.client.game;
import com.google.common.collect.ImmutableMap;
import javax.annotation.Nullable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.ItemID;
/**
* Some non tradeable items are kept on death inside low level wilderness (1-20) but are turned into a broken variant.
* <p>
* The non-broken variant will be shown inside the interface.
*/
@AllArgsConstructor
@Getter
public enum ItemReclaimCost
{
// Capes
FIRE_CAPE(ItemID.FIRE_CAPE, 50000),
FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE, 99000),
INFERNAL_CAPE(ItemID.INFERNAL_CAPE, 50000),
INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE, 99000),
AVAS_ASSEMBLER(ItemID.AVAS_ASSEMBLER, 75000),
ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE, 99000),
IMBUED_GUTHIX_CAPE(ItemID.IMBUED_GUTHIX_CAPE, 75000),
IMBUED_GUTHIX_MAX_CAPE(ItemID.GUTHIX_MAX_CAPE, 99000),
IMBUED_SARADOMIN_CAPE(ItemID.IMBUED_SARADOMIN_CAPE, 75000),
IMBUED_SARADOMIN_MAX_CAPE(ItemID.SARADOMIN_MAX_CAPE, 99000),
IMBUED_ZAMORAK_CAPE(ItemID.IMBUED_ZAMORAK_CAPE, 75000),
IMBUED_ZAMORAK_MAX_CAPE(ItemID.ZAMORAK_MAX_CAPE, 99000),
// Defenders
BRONZE_DEFENDER(ItemID.BRONZE_DEFENDER, 1000),
IRON_DEFENDER(ItemID.IRON_DEFENDER, 2000),
STEEL_DEFENDER(ItemID.STEEL_DEFENDER, 2500),
BLACK_DEFENDER(ItemID.BLACK_DEFENDER, 5000),
MITHRIL_DEFENDER(ItemID.MITHRIL_DEFENDER, 15000),
ADAMANT_DEFENDER(ItemID.ADAMANT_DEFENDER, 25000),
RUNE_DEFENDER(ItemID.RUNE_DEFENDER, 35000),
DRAGON_DEFENDER(ItemID.DRAGON_DEFENDER, 40000),
AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER, 1000000),
// Void
VOID_MAGE_HELM(ItemID.VOID_MAGE_HELM, 40000),
VOID_RANGER_HELM(ItemID.VOID_RANGER_HELM, 40000),
VOID_MELEE_HELM(ItemID.VOID_MELEE_HELM, 40000),
VOID_KNIGHT_TOP(ItemID.VOID_KNIGHT_TOP, 45000),
VOID_KNIGHT_ROBE(ItemID.VOID_KNIGHT_ROBE, 45000),
VOID_KNIGHT_GLOVES(ItemID.VOID_KNIGHT_GLOVES, 30000),
ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP, 50000),
ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE, 50000),
// Barb Assault
FIGHTER_HAT(ItemID.FIGHTER_HAT, 45000),
RANGER_HAT(ItemID.RANGER_HAT, 45000),
HEALER_HAT(ItemID.HEALER_HAT, 45000),
FIGHTER_TORSO(ItemID.FIGHTER_TORSO, 50000),
PENANCE_SKIRT(ItemID.PENANCE_SKIRT, 20000),
// Castle Wars
SARADOMIN_HALO(ItemID.SARADOMIN_HALO, 25000),
ZAMORAK_HALO(ItemID.ZAMORAK_HALO, 25000),
GUTHIX_HALO(ItemID.GUTHIX_HALO, 25000),
DECORATIVE_MAGIC_HAT(ItemID.DECORATIVE_ARMOUR_11898, 5000),
DECORATIVE_MAGIC_ROBE_TOP(ItemID.DECORATIVE_ARMOUR_11896, 5000),
DECORATIVE_MAGIC_ROBE_LEGS(ItemID.DECORATIVE_ARMOUR_11897, 5000),
DECORATIVE_RANGE_TOP(ItemID.DECORATIVE_ARMOUR_11899, 5000),
DECORATIVE_RANGE_BOTTOM(ItemID.DECORATIVE_ARMOUR_11900, 5000),
DECORATIVE_RANGE_QUIVER(ItemID.DECORATIVE_ARMOUR_11901, 5000),
GOLD_DECORATIVE_HELM(ItemID.DECORATIVE_HELM_4511, 5000),
GOLD_DECORATIVE_BODY(ItemID.DECORATIVE_ARMOUR_4509, 5000),
GOLD_DECORATIVE_LEGS(ItemID.DECORATIVE_ARMOUR_4510, 5000),
GOLD_DECORATIVE_SKIRT(ItemID.DECORATIVE_ARMOUR_11895, 5000),
GOLD_DECORATIVE_SHIELD(ItemID.DECORATIVE_SHIELD_4512, 5000),
GOLD_DECORATIVE_SWORD(ItemID.DECORATIVE_SWORD_4508, 5000),
// Granite Maul
GRANITE_MAUL(ItemID.GRANITE_MAUL_24225, 375000),
GRANITE_MAUL_OR(ItemID.GRANITE_MAUL_24227, 375000);
private static final ImmutableMap<Integer, ItemReclaimCost> idMap;
static
{
ImmutableMap.Builder<Integer, ItemReclaimCost> builder = ImmutableMap.builder();
for (ItemReclaimCost items : values())
{
builder.put(items.itemID, items);
}
idMap = builder.build();
}
private final int itemID;
private final int value;
@Nullable
public static ItemReclaimCost of(int itemId)
{
return idMap.get(itemId);
}
public static boolean breaksOnDeath(int itemId)
{
return idMap.containsKey(itemId);
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* 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 com.openosrs.client.game;
import java.util.LinkedHashMap;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import net.runelite.api.Player;
import net.runelite.http.api.hiscore.HiscoreResult;
@Getter
@Setter
@ToString(exclude = "player")
public class PlayerContainer
{
private AttackStyle attackStyle;
private AttackStyle weakness;
private HiscoreResult skills;
private LinkedHashMap<Integer, Integer> gear;
private LinkedHashMap<Integer, Integer> riskedGear;
private MeleeStyle meleeStyle;
private Player player;
private String location;
private String name;
private String targetString;
private CombatStats combatStats;
private boolean httpRetry;
private boolean hiscoresRequested;
private boolean scouted;
private boolean attacking;
private boolean friend;
private boolean clan;
private int hpLevel;
private int potionBoost;
private int prayerLevel;
private int risk;
private int scoutTimer;
private int shield;
private int timer;
private int weapon;
private int wildyLevel;
PlayerContainer(Player player)
{
this.attackStyle = AttackStyle.UNKNOWN;
this.gear = new LinkedHashMap<>();
this.hpLevel = 0;
this.location = "N/A";
this.meleeStyle = MeleeStyle.STAB;
this.name = player.getName();
this.player = player;
this.riskedGear = new LinkedHashMap<>();
this.scoutTimer = 500;
this.scouted = false;
this.skills = null;
this.targetString = "";
this.weakness = AttackStyle.UNKNOWN;
}
void reset()
{
setMeleeStyle(MeleeStyle.NONE);
if (getTimer() > 0)
{
setTimer(getTimer() - 1);
if (getTimer() == 0)
{
setAttacking(false);
}
}
}
@Getter(AccessLevel.PACKAGE)
enum MeleeStyle
{
CRUSH,
SLASH,
STAB,
NONE
}
}

View File

@@ -0,0 +1,551 @@
package com.openosrs.client.game;
import com.openosrs.client.events.AttackStyleChanged;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.ItemComposition;
import net.runelite.api.ItemID;
import net.runelite.api.NPC;
import net.runelite.api.Player;
import net.runelite.api.WorldType;
import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.PlayerCompositionChanged;
import net.runelite.api.events.PlayerDespawned;
import net.runelite.api.kit.KitType;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.FriendChatManager;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.ItemMapping;
import net.runelite.client.util.PvPUtil;
import net.runelite.http.api.hiscore.HiscoreClient;
import net.runelite.http.api.hiscore.HiscoreResult;
import net.runelite.http.api.item.ItemEquipmentStats;
import net.runelite.http.api.item.ItemStats;
import okhttp3.OkHttpClient;
@Singleton
@Slf4j
@SuppressWarnings("unused")
public class PlayerManager
{
private final HiscoreClient hiscoreClient;
private final Client client;
private final ItemManager itemManager;
private final EventBus eventBus;
private final FriendChatManager friendChatManager;
private final Map<String, PlayerContainer> playerMap = new ConcurrentHashMap<>();
private final Map<String, HiscoreResult> resultCache = new ConcurrentHashMap<>();
private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
@Inject
PlayerManager(
final Client client,
final EventBus eventBus,
final ItemManager itemManager,
final FriendChatManager friendChatManager,
final OkHttpClient okHttpClient
)
{
this.client = client;
this.itemManager = itemManager;
this.eventBus = eventBus;
this.friendChatManager = friendChatManager;
this.hiscoreClient = new HiscoreClient(okHttpClient);
eventBus.register(this);
}
/**
* @return Collection of {@link PlayerContainer} that are attacking you, this can be empty.
*/
public Set<PlayerContainer> getAllAttackers()
{
Set<PlayerContainer> result = new HashSet<>();
for (PlayerContainer playerContainer : playerMap.values())
{
if (playerContainer.isAttacking())
{
result.add(playerContainer);
}
}
return Collections.unmodifiableSet(result);
}
/**
* @return Collection of {@link PlayerContainer}, this can be empty.
*/
public Collection<PlayerContainer> getPlayerContainers()
{
return playerMap.values();
}
/**
* @param name Players name.
* @return {@link PlayerContainer} if provided with proper name, else null.
*/
@Nullable
public PlayerContainer getPlayer(String name)
{
return playerMap.get(name);
}
/**
* @param player Player object.
* @return {@link PlayerContainer} if provided with proper name, else null.
*/
@Nullable
public PlayerContainer getPlayer(Player player)
{
if (player == null)
{
return null;
}
return playerMap.get(player.getName());
}
/**
* This will keep submitting an http request until it successfully updates.
*
* @param name The player name you wish to update.
*/
public void updateStats(String name)
{
final PlayerContainer p = playerMap.get(name);
if (p == null)
{
return;
}
updateStats(p.getPlayer());
}
/**
* This will keep submitting an http request until it successfully updates.
*
* @param requestedPlayer The player object you wish to update.
*/
public void updateStats(Player requestedPlayer)
{
if (requestedPlayer == null)
{
return;
}
final PlayerContainer player = playerMap.get(requestedPlayer.getName());
if (player == null)
{
return;
}
if (resultCache.containsKey(player.getName()))
{
player.setSkills(resultCache.get(player.getName()));
player.setPrayerLevel(player.getSkills().getPrayer().getLevel());
player.setHpLevel(player.getSkills().getHitpoints().getLevel());
return;
}
if (player.isHiscoresRequested() && !player.isHttpRetry())
{
return;
}
player.setHiscoresRequested(true);
executorService.submit(() ->
{
int timeout = 0;
HiscoreResult result;
do
{
try
{
result = hiscoreClient.lookup(player.getName());
}
catch (IOException ex)
{
if (timeout == 10)
{
log.error("HiScore Lookup timed out on: {}", player.getName());
player.setHttpRetry(true);
return;
}
result = null;
timeout++;
try
{
Thread.sleep(1000);
}
catch (InterruptedException ignored)
{
}
}
}
while (result == null);
resultCache.put(player.getName(), result);
player.setSkills(result);
player.setPrayerLevel(player.getSkills().getPrayer().getLevel());
player.setHpLevel(player.getSkills().getHitpoints().getLevel());
player.setHttpRetry(false);
player.setHiscoresRequested(false);
});
}
@Subscribe
private void onAppearenceChanged(PlayerCompositionChanged event)
{
PlayerContainer player = playerMap.computeIfAbsent(event.getPlayer().getName(), s -> new PlayerContainer(event.getPlayer()));
update(player);
player.setFriend(client.isFriended(player.getName(), false));
player.setClan(friendChatManager.isMember(player.getName()));
}
@Subscribe
private void onPlayerDespawned(PlayerDespawned event)
{
playerMap.remove(event.getPlayer().getName());
}
@Subscribe
private void onAnimationChanged(AnimationChanged event)
{
final Actor actor = event.getActor();
if (actor.getInteracting() != client.getLocalPlayer() || !(actor instanceof Player) || actor.getAnimation() == -1)
{
return;
}
final PlayerContainer player = playerMap.get(actor.getName());
if (player == null)
{
return;
}
assert player.getPlayer() == actor;
if (player.getSkills() == null)
{
updateStats(player.getPlayer());
}
player.setAttacking(true);
player.setTimer(8);
}
private void update(PlayerContainer player)
{
player.setRisk(0);
updatePlayerGear(player);
updateAttackStyle(player);
updateWeakness(player);
player.setLocation(WorldLocation.location(player.getPlayer().getWorldLocation()));
player.setWildyLevel(PvPUtil.getWildernessLevelFrom(player.getPlayer().getWorldLocation()));
player.setTargetString(targetStringBuilder(player));
}
private void updatePlayerGear(PlayerContainer player)
{
final Map<Integer, Integer> prices = new HashMap<>();
if (player.getPlayer().getPlayerComposition() == null)
{
return;
}
int magicAttack = 0,
magicDefence = 0,
magicStr = 0,
meleeAtkCrush = 0,
meleeAtkStab = 0,
meleeAtkSlash = 0,
meleeDefCrush = 0,
meleeDefStab = 0,
meleeDefSlash = 0,
meleeStr = 0,
rangeAttack = 0,
rangeDefence = 0,
rangeStr = 0,
speed = 0;
for (KitType kitType : KitType.values())
{
if (kitType.equals(KitType.RING) || kitType.equals(KitType.AMMUNITION))
{
continue;
}
final int id = player.getPlayer().getPlayerComposition().getEquipmentId(kitType);
if (id == -1)
{
continue;
}
if (kitType.equals(KitType.WEAPON))
{
player.setWeapon(id);
switch (id)
{
case ItemID.HEAVY_BALLISTA:
case ItemID.HEAVY_BALLISTA_23630:
case ItemID.LIGHT_BALLISTA:
rangeStr += 150;
break;
case ItemID.MAPLE_LONGBOW:
case ItemID.MAPLE_SHORTBOW:
rangeStr += 31;
break;
case ItemID.MAGIC_SHORTBOW:
case ItemID.MAGIC_SHORTBOW_20558:
case ItemID.MAGIC_SHORTBOW_I:
rangeStr += +55;
break;
case ItemID.DARK_BOW:
case ItemID.DARK_BOW_12765:
case ItemID.DARK_BOW_12766:
case ItemID.DARK_BOW_12767:
case ItemID.DARK_BOW_12768:
case ItemID.DARK_BOW_20408:
rangeStr += +60;
break;
case ItemID.RUNE_CROSSBOW:
case ItemID.RUNE_CROSSBOW_23601:
rangeStr += +117;
break;
case ItemID.DRAGON_CROSSBOW:
case ItemID.ARMADYL_CROSSBOW:
case ItemID.ARMADYL_CROSSBOW_23611:
rangeStr += +122;
break;
}
}
final ItemStats item = itemManager.getItemStats(id, false);
final ItemComposition itemComposition = itemManager.getItemComposition(id);
if (item == null)
{
log.debug("Item is null: {}", id);
continue;
}
final ItemEquipmentStats stats = item.getEquipment();
speed += stats.getAspeed();
meleeAtkCrush += stats.getAcrush();
meleeAtkStab += stats.getAstab();
meleeAtkSlash += stats.getAslash();
meleeDefCrush += stats.getDcrush();
meleeDefStab += stats.getDstab();
meleeDefSlash += stats.getDslash();
magicAttack += stats.getAmagic();
rangeAttack += stats.getArange();
magicDefence += stats.getDmagic();
rangeDefence += stats.getDrange();
rangeStr += stats.getRstr();
meleeStr += stats.getStr();
magicStr += stats.getMdmg();
if (ItemReclaimCost.breaksOnDeath(id))
{
prices.put(id, itemManager.getRepairValue(id));
log.debug("Item has a broken value: Id {}, Value {}", id, itemManager.getRepairValue(id));
continue;
}
if (!itemComposition.isTradeable() && !ItemMapping.isMapped(id))
{
prices.put(id, itemComposition.getPrice());
}
else if (itemComposition.isTradeable())
{
prices.put(id, itemManager.getItemPrice(id, false));
}
}
player.setCombatStats(new CombatStats(
magicAttack,
magicDefence,
magicStr,
meleeAtkCrush,
meleeAtkSlash,
meleeAtkStab,
(meleeAtkCrush + meleeAtkSlash + meleeAtkStab) / 3,
meleeDefCrush,
(meleeDefCrush + meleeDefSlash + meleeDefStab) / 3,
meleeDefSlash,
meleeDefStab,
meleeStr,
rangeAttack,
rangeDefence,
rangeStr,
speed
));
updateGear(player, prices);
updateMeleeStyle(player);
}
private void updateGear(PlayerContainer player, Map<Integer, Integer> prices)
{
player.setGear(prices.entrySet()
.stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new))
);
player.setRiskedGear(prices.entrySet()
.stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new))
);
if (client.getWorldType().stream().noneMatch(x -> x == WorldType.HIGH_RISK))
{
if (player.getPlayer().getSkullIcon() == null)
{
removeEntries(player.getRiskedGear(), player.getPrayerLevel() < 25 ? 3 : 4);
}
else
{
removeEntries(player.getRiskedGear(), player.getPrayerLevel() < 25 ? 0 : 1);
}
}
int risk = 0;
for (int val : player.getRiskedGear().values())
risk += val;
player.setRisk(risk);
}
private void updateMeleeStyle(PlayerContainer player)
{
final CombatStats stats = player.getCombatStats();
if (stats.getMeleeAtkCrush() >= stats.getMeleeAtkSlash() && stats.getMeleeAtkCrush() >= stats.getMeleeAtkStab())
{
player.setMeleeStyle(PlayerContainer.MeleeStyle.CRUSH);
}
else if (stats.getMeleeAtkSlash() >= stats.getMeleeAtkCrush() && stats.getMeleeAtkSlash() >= stats.getMeleeAtkStab())
{
player.setMeleeStyle(PlayerContainer.MeleeStyle.SLASH);
}
else
{
player.setMeleeStyle(PlayerContainer.MeleeStyle.STAB);
}
}
private void updateAttackStyle(PlayerContainer player)
{
final AttackStyle oldStyle = player.getAttackStyle();
boolean staff = false;
for (int id : player.getGear().keySet())
{
ItemComposition def = itemManager.getItemComposition(id);
if (def.getName().toLowerCase().contains("staff"))
{
player.setAttackStyle(AttackStyle.MAGE);
if (oldStyle != player.getAttackStyle())
{
eventBus.post(new AttackStyleChanged(
player.getPlayer(), oldStyle, player.getAttackStyle())
);
}
return;
}
}
final CombatStats stats = player.getCombatStats();
if (stats.getMagicStr() >= stats.getRangeStr() && stats.getMagicStr() >= stats.getMeleeStr())
{
player.setAttackStyle(AttackStyle.MAGE);
}
else if (stats.getRangeStr() >= stats.getMagicStr() && stats.getRangeStr() >= stats.getMeleeStr())
{
player.setAttackStyle(AttackStyle.RANGE);
}
else
{
player.setAttackStyle(AttackStyle.MELEE);
}
if (oldStyle != player.getAttackStyle())
{
eventBus.post(new AttackStyleChanged(
player.getPlayer(), oldStyle, player.getAttackStyle())
);
}
}
private void updateWeakness(PlayerContainer player)
{
final CombatStats stats = player.getCombatStats();
if (stats.getMagicDefence() <= stats.getRangeDefence() && stats.getMagicDefence() <= stats.getMeleeDefence())
{
player.setWeakness(AttackStyle.MAGE);
}
else if (stats.getRangeDefence() <= stats.getMagicDefence() && stats.getRangeDefence() <= stats.getMeleeDefence())
{
player.setWeakness(AttackStyle.RANGE);
}
else
{
player.setWeakness(AttackStyle.MELEE);
}
}
private static void removeEntries(LinkedHashMap<Integer, Integer> map, int quantity)
{
final Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
for (int i = 0; it.hasNext() && i < quantity; i++)
{
it.next();
it.remove(); // LinkedHashMap iterator supports this
}
}
private String targetStringBuilder(PlayerContainer player)
{
if (player.getPlayer().getInteracting() != null)
{
Actor actor = player.getPlayer().getInteracting();
if (actor instanceof Player)
{
return "(Player) " + actor.getName();
}
else if (actor instanceof NPC)
{
return "(NPC) " + actor.getName();
}
}
return "No Target Detected";
}
}

View File

@@ -28,6 +28,7 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.openosrs.client.game.ItemReclaimCost;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
@@ -349,6 +350,41 @@ public class ItemManager
return price;
}
public int getAlchValue(ItemComposition composition)
{
if (composition.getId() == COINS_995)
{
return 1;
}
if (composition.getId() == PLATINUM_TOKEN)
{
return 1000;
}
return Math.max(1, composition.getHaPrice());
}
public int getRepairValue(int itemId)
{
return getRepairValue(itemId, false);
}
private int getRepairValue(int itemId, boolean fullValue)
{
final ItemReclaimCost b = ItemReclaimCost.of(itemId);
if (b != null)
{
if (fullValue || b.getItemID() == GRANITE_MAUL_24225 || b.getItemID() == GRANITE_MAUL_24227)
{
return b.getValue();
}
return (int) (b.getValue() * (75.0f / 100.0f));
}
return 0;
}
/**
* Look up an item's stats
* @param itemId item id

View File

@@ -369,4 +369,9 @@ public enum ItemMapping
return mapping;
}
public static boolean isMapped(int itemId)
{
return MAPPINGS.containsValue(itemId);
}
}