SuppliesTracker: Prayer, farming, and bug fixes (#2167)

* Farming, prayer, bug fixes

* Fix jewellery tooltip

* rename Skills to skills
This commit is contained in:
Dozer
2020-01-02 04:26:01 -06:00
committed by Kyle
parent 78a92baaa1
commit 4b7597019b
7 changed files with 334 additions and 50 deletions

View File

@@ -360,4 +360,7 @@ public final class AnimationID
public static final int SURGE_SPELL_ANIMATION = 7855; public static final int SURGE_SPELL_ANIMATION = 7855;
public static final int HIGH_ALCH_ANIMATION = 713; public static final int HIGH_ALCH_ANIMATION = 713;
public static final int LUNAR_HUMIDIFY = 6294; public static final int LUNAR_HUMIDIFY = 6294;
public static final int PRAY_AT_ALTAR = 645;
public static final int ENSOULED_HEADS_ANIMATION = 7198;
} }

View File

@@ -44,7 +44,9 @@ public enum ItemType
TELEPORT("Teleports"), TELEPORT("Teleports"),
COINS("Coins"), COINS("Coins"),
JEWELLERY("Jewellery"), JEWELLERY("Jewellery"),
CHARGES("Charges"); CHARGES("Charges"),
FARMING("Farming"),
PRAYER("Prayer");
@Getter(AccessLevel.PUBLIC) @Getter(AccessLevel.PUBLIC)
private String label; private String label;
@@ -63,34 +65,44 @@ public enum ItemType
{ {
return ItemType.POTION; return ItemType.POTION;
} }
if (item.getName().toLowerCase().contains("bolt") || item.getName().toLowerCase().contains("dart") else if ((item.getName().toLowerCase().contains("bones") && !item.getName().toLowerCase().contains(" to ")) ||
|| item.getName().toLowerCase().contains(" arrow") || item.getName().toLowerCase().contains("javelin") item.getName().toLowerCase().contains("ensouled"))
|| item.getName().toLowerCase().contains("knive") || item.getName().toLowerCase().contains("throwing") {
|| item.getName().toLowerCase().contains("zulrah's scale") || item.getName().toLowerCase().contains("cannonball") return ItemType.PRAYER;
|| item.getName().toLowerCase().contains("knife") || item.getName().toLowerCase().contains("chinchompa")) }
else if (item.getName().toLowerCase().contains("bolt") || item.getName().toLowerCase().contains("dart")
|| item.getName().toLowerCase().contains(" arrow") || item.getName().toLowerCase().contains("javelin")
|| item.getName().toLowerCase().contains("knive") || item.getName().toLowerCase().contains("throwing")
|| item.getName().toLowerCase().contains("zulrah's scale") || item.getName().toLowerCase().contains("cannonball")
|| item.getName().toLowerCase().contains("knife"))
{ {
return ItemType.AMMO; return ItemType.AMMO;
} }
if (item.getName().toLowerCase().contains("rune")) else if (item.getName().toLowerCase().contains("rune"))
{ {
return ItemType.RUNE; return ItemType.RUNE;
} }
if (item.getName().toLowerCase().contains("teleport")) else if (item.getName().toLowerCase().contains("teleport"))
{ {
return ItemType.TELEPORT; return ItemType.TELEPORT;
} }
if (item.getId() == COINS_995) else if (item.getId() == COINS_995)
{ {
return ItemType.COINS; return ItemType.COINS;
} }
if (item.getName().toLowerCase().contains("ring of") || item.getName().toLowerCase().contains("amulet") || else if (item.getName().toLowerCase().contains("ring of") || item.getName().toLowerCase().contains("amulet") ||
item.getName().toLowerCase().contains("bracelet") || item.getName().toLowerCase().contains("necklace")) item.getName().toLowerCase().contains("bracelet") || item.getName().toLowerCase().contains("necklace"))
{ {
return ItemType.JEWELLERY; return ItemType.JEWELLERY;
} }
if (item.getId() == SCYTHE_OF_VITUR || item.getId() == SANGUINESTI_STAFF || else if (item.getName().toLowerCase().contains(" sapling") || item.getName().toLowerCase().contains(" seed") ||
item.getId() == TRIDENT_OF_THE_SEAS || item.getId() == TRIDENT_OF_THE_SWAMP || item.getName().toLowerCase().contains("compost") || item.getName().toLowerCase().contains("plant cure"))
item.getId() == BLADE_OF_SAELDOR) {
return ItemType.FARMING;
}
else if (item.getId() == SCYTHE_OF_VITUR || item.getId() == SANGUINESTI_STAFF ||
item.getId() == TRIDENT_OF_THE_SEAS || item.getId() == TRIDENT_OF_THE_SWAMP ||
item.getId() == BLADE_OF_SAELDOR)
{ {
return ItemType.CHARGES; return ItemType.CHARGES;
} }

View File

@@ -68,6 +68,8 @@ import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginType;
import static net.runelite.client.plugins.suppliestracker.ActionType.*; import static net.runelite.client.plugins.suppliestracker.ActionType.*;
import net.runelite.client.plugins.suppliestracker.skills.Farming;
import net.runelite.client.plugins.suppliestracker.skills.Prayer;
import net.runelite.client.plugins.suppliestracker.ui.SuppliesTrackerPanel; import net.runelite.client.plugins.suppliestracker.ui.SuppliesTrackerPanel;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
@@ -123,8 +125,8 @@ public class SuppliesTrackerPlugin extends Plugin
//Hold Supply Data //Hold Supply Data
private final Map<Integer, SuppliesTrackerItem> suppliesEntry = new HashMap<>(); private final Map<Integer, SuppliesTrackerItem> suppliesEntry = new HashMap<>();
private final Deque<MenuAction> actionStack = new ArrayDeque<>(); private final Deque<MenuAction> actionStack = new ArrayDeque<>();
//Item arrays //Item arrays
private final String[] RAIDS_CONSUMABLES = new String[]{"xeric's", "elder", "twisted", "revitalisation", "overload", "prayer enhance", "pysk", "suphi", "leckish", "brawk", "mycil", "roqed", "kyren", "guanic", "prael", "giral", "phluxia", "kryket", "murng", "psykk", "egniol"}; private final String[] RAIDS_CONSUMABLES = new String[]{"xeric's", "elder", "twisted", "revitalisation", "overload", "prayer enhance", "pysk", "suphi", "leckish", "brawk", "mycil", "roqed", "kyren", "guanic", "prael", "giral", "phluxia", "kryket", "murng", "psykk", "egniol"};
private final int[] TRIDENT_OF_THE_SEAS_IDS = new int[]{TRIDENT_OF_THE_SEAS, TRIDENT_OF_THE_SEAS_E, TRIDENT_OF_THE_SEAS_FULL}; private final int[] TRIDENT_OF_THE_SEAS_IDS = new int[]{TRIDENT_OF_THE_SEAS, TRIDENT_OF_THE_SEAS_E, TRIDENT_OF_THE_SEAS_FULL};
@@ -156,8 +158,22 @@ public class SuppliesTrackerPlugin extends Plugin
private int amountused3 = 0; private int amountused3 = 0;
private boolean magicXpChanged = false; private boolean magicXpChanged = false;
private boolean skipTick = false; private boolean skipTick = false;
private boolean noXpCast = false;
private int magicXp = 0; private int magicXp = 0;
//prayer stuff
private Prayer prayer;
private boolean prayerAltarAnimationCheck = false;
private int prayerXp = 0;
private int boneId = 0;
private boolean skipBone = false;
private int longTickWait = 0;
private int ensouledHeadId = 0;
//farming stuff
private Farming farming;
private ItemContainer old; private ItemContainer old;
private int ammoId = 0; private int ammoId = 0;
private int ammoAmount = 0; private int ammoAmount = 0;
@@ -181,7 +197,6 @@ public class SuppliesTrackerPlugin extends Plugin
private SuppliesTrackerConfig config; private SuppliesTrackerConfig config;
@Inject @Inject
private Client client; private Client client;
private boolean noXpCast = false;
/** /**
* Checks if item name is potion * Checks if item name is potion
@@ -218,6 +233,8 @@ public class SuppliesTrackerPlugin extends Plugin
{ {
panel = new SuppliesTrackerPanel(itemManager, this); panel = new SuppliesTrackerPanel(itemManager, this);
farming = new Farming(this, itemManager);
prayer = new Prayer(this, itemManager);
final BufferedImage header = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); final BufferedImage header = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png");
panel.loadHeaderIcon(header); panel.loadHeaderIcon(header);
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png");
@@ -256,6 +273,20 @@ public class SuppliesTrackerPlugin extends Plugin
magicXp = event.getXp(); magicXp = event.getXp();
} }
} }
if (event.getSkill().name().toLowerCase().equals("prayer"))
{
if (prayerXp != event.getXp())
{
if (prayerAltarAnimationCheck)
{
if (!skipBone)
{
prayer.build();
}
}
prayerXp = event.getXp();
}
}
} }
@Subscribe @Subscribe
@@ -282,6 +313,21 @@ public class SuppliesTrackerPlugin extends Plugin
ticks = 0; ticks = 0;
} }
//reset skip bone for dark altar
skipBone = false;
//Waits to reset prayer animation check. needed for 1 ticking or
//in case animation gets interrupted
if (longTickWait > 0)
{
longTickWait = longTickWait - 1;
}
else if (prayerAltarAnimationCheck)
{
prayerAltarAnimationCheck = false;
}
if (skipTick) if (skipTick)
{ {
skipTick = false; skipTick = false;
@@ -576,7 +622,19 @@ public class SuppliesTrackerPlugin extends Plugin
break; break;
case ONEHAND_SLASH_SWORD_ANIMATION: case ONEHAND_SLASH_SWORD_ANIMATION:
case ONEHAND_STAB_SWORD_ANIMATION: case ONEHAND_STAB_SWORD_ANIMATION:
buildChargesEntries(BLADE_OF_SAELDOR); if (mainHand == BLADE_OF_SAELDOR) buildChargesEntries(BLADE_OF_SAELDOR);
break;
case USING_GILDED_ALTAR:
case PRAY_AT_ALTAR:
prayerAltarAnimationCheck = true;
longTickWait = 5;
break;
case ENSOULED_HEADS_ANIMATION:
if (ensouledHeadId != 0)
{
buildEntries(ensouledHeadId);
ensouledHeadId = 0;
}
break; break;
} }
} }
@@ -738,25 +796,7 @@ public class SuppliesTrackerPlugin extends Plugin
@Subscribe @Subscribe
private void onMenuOptionClicked(final MenuOptionClicked event) private void onMenuOptionClicked(final MenuOptionClicked event)
{ {
// Fix for house pool
switch (event.getMenuOpcode())
{
case ITEM_FIRST_OPTION:
case ITEM_SECOND_OPTION:
case ITEM_THIRD_OPTION:
case ITEM_FOURTH_OPTION:
case ITEM_FIFTH_OPTION:
case EXAMINE_ITEM_BANK_EQ:
case WIDGET_FIRST_OPTION:
case WIDGET_SECOND_OPTION:
case WIDGET_THIRD_OPTION:
case WIDGET_FOURTH_OPTION:
case WIDGET_FIFTH_OPTION:
case WIDGET_DEFAULT:
break;
default:
return;
}
// Uses stacks to push/pop for tick eating // Uses stacks to push/pop for tick eating
// Create pattern to find eat/drink at beginning // Create pattern to find eat/drink at beginning
Pattern eatPattern = Pattern.compile(EAT_PATTERN); Pattern eatPattern = Pattern.compile(EAT_PATTERN);
@@ -772,6 +812,24 @@ public class SuppliesTrackerPlugin extends Plugin
return false; return false;
})) }))
{ {
switch (event.getMenuOpcode())
{
case ITEM_FIRST_OPTION:
case ITEM_SECOND_OPTION:
case ITEM_THIRD_OPTION:
case ITEM_FOURTH_OPTION:
case ITEM_FIFTH_OPTION:
case EXAMINE_ITEM_BANK_EQ:
case WIDGET_FIRST_OPTION:
case WIDGET_SECOND_OPTION:
case WIDGET_THIRD_OPTION:
case WIDGET_FOURTH_OPTION:
case WIDGET_FIFTH_OPTION:
case WIDGET_DEFAULT:
break;
default:
return;
}
old = client.getItemContainer(InventoryID.INVENTORY); old = client.getItemContainer(InventoryID.INVENTORY);
int slot = event.getParam0(); int slot = event.getParam0();
if (old.getItems() != null) if (old.getItems() != null)
@@ -818,6 +876,33 @@ public class SuppliesTrackerPlugin extends Plugin
} }
if (event.getTarget().toLowerCase().equals("use"))
{
if (itemManager.getItemDefinition(event.getIdentifier()).getName().toLowerCase().contains("compost"))
{
farming.setBucketId(event.getIdentifier());
}
else
{
farming.setPlantId(event.getIdentifier());
}
}
if (event.getTarget().equals("Use") || event.getOption().toLowerCase().contains("bury"))
{
if (itemManager.getItemDefinition(event.getIdentifier()).getName().toLowerCase().contains("bones"))
{
prayer.setBonesId(event.getIdentifier());
boneId = event.getIdentifier();
}
}
if (event.getOption().equals("Reanimate") && event.getMenuOpcode().name().equals("ITEM_USE_ON_WIDGET"))
{
ensouledHeadId = event.getIdentifier();
}
//Adds tracking to Master Scroll Book //Adds tracking to Master Scroll Book
if (event.getOption().toLowerCase().equals("activate")) if (event.getOption().toLowerCase().equals("activate"))
{ {
@@ -879,9 +964,27 @@ public class SuppliesTrackerPlugin extends Plugin
void onChatMessage(ChatMessage event) void onChatMessage(ChatMessage event)
{ {
String message = event.getMessage(); String message = event.getMessage();
if (event.getType() == ChatMessageType.GAMEMESSAGE || event.getType() == ChatMessageType.SPAM) if (event.getType() == ChatMessageType.GAMEMESSAGE || event.getType() == ChatMessageType.SPAM)
{ {
if (message.toLowerCase().contains("your amulet has") || if (message.toLowerCase().contains("you plant "))
{
farming.OnChatPlant(message.toLowerCase());
}
else if (message.toLowerCase().contains("you treat "))
{
farming.setEndlessBucket(message);
farming.OnChatTreat(message.toLowerCase());
}
else if (message.toLowerCase().contains("you bury the bones"))
{
prayer.OnChat(message);
}
else if (message.toLowerCase().contains("dark lord"))
{
skipBone = true;
}
else if (message.toLowerCase().contains("your amulet has") ||
message.toLowerCase().contains("your amulet's last charge")) message.toLowerCase().contains("your amulet's last charge"))
{ {
buildChargesEntries(AMULET_OF_GLORY6); buildChargesEntries(AMULET_OF_GLORY6);
@@ -957,7 +1060,7 @@ public class SuppliesTrackerPlugin extends Plugin
* *
* @param itemId the id of the item * @param itemId the id of the item
*/ */
private void buildEntries(int itemId) public void buildEntries(int itemId)
{ {
buildEntries(itemId, 1); buildEntries(itemId, 1);
} }
@@ -968,7 +1071,7 @@ public class SuppliesTrackerPlugin extends Plugin
* @param itemId the id of the item * @param itemId the id of the item
* @param count the amount of the item to add to the tracker * @param count the amount of the item to add to the tracker
*/ */
private void buildEntries(int itemId, int count) public void buildEntries(int itemId, int count)
{ {
final ItemDefinition itemComposition = itemManager.getItemDefinition(itemId); final ItemDefinition itemComposition = itemManager.getItemDefinition(itemId);
String name = itemComposition.getName(); String name = itemComposition.getName();
@@ -1219,18 +1322,19 @@ public class SuppliesTrackerPlugin extends Plugin
{ {
if (magicXpChanged || noXpCast) if (magicXpChanged || noXpCast)
{ {
if (amountused1 != 0) if (amountused1 != 0 && amountused1 < 20)
{ {
buildEntries(Runes.getRune(rune1).getItemId(), amountused1); buildEntries(Runes.getRune(rune1).getItemId(), amountused1);
} }
if (amountused2 != 0) if (amountused2 != 0 && amountused2 < 20)
{ {
buildEntries(Runes.getRune(rune2).getItemId(), amountused2); buildEntries(Runes.getRune(rune2).getItemId(), amountused2);
} }
if (amountused3 != 0) if (amountused3 != 0 && amountused3 < 20)
{ {
buildEntries(Runes.getRune(rune3).getItemId(), amountused3); buildEntries(Runes.getRune(rune3).getItemId(), amountused3);
} }
} }
} }
} }

View File

@@ -0,0 +1,95 @@
package net.runelite.client.plugins.suppliestracker.skills;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.suppliestracker.SuppliesTrackerPlugin;
import javax.inject.Singleton;
import static net.runelite.api.ItemID.*;
@Singleton
public class Farming
{
private SuppliesTrackerPlugin plugin;
private ItemManager itemManager;
private int plantId = 0;
private int compostId = 0;
private int bucketId = 0;
private final int[] ALLOTMENT_SEEDS = new int[]{POTATO_SEED, ONION_SEED, CABBAGE_SEED, TOMATO_SEED, SWEETCORN_SEED, STRAWBERRY_SEED, WATERMELON_SEED, SNAPE_GRASS_SEED};
public Farming(SuppliesTrackerPlugin plugin, ItemManager itemManager)
{
this.plugin = plugin;
this.itemManager = itemManager;
}
public void OnChatPlant(String message)
{
if (plantId <= 0)
{
return;
}
String name = itemManager.getItemDefinition(plantId).getName().toLowerCase();
if ( name.contains(" seed") || name.contains(" sapling"))
{
for (int seedId: ALLOTMENT_SEEDS)
{
if (plantId == seedId)
{
plugin.buildEntries(plantId, 3);
return;
}
}
plugin.buildEntries(plantId);
}
}
public void OnChatTreat(String message)
{
if (bucketId <= 0)
{
return;
}
String name = itemManager.getItemDefinition(bucketId).getName().toLowerCase();
if (name.contains(" compost") || name.contains("plant cure"))
{
if (bucketId == BOTTOMLESS_COMPOST_BUCKET || bucketId == BOTTOMLESS_COMPOST_BUCKET_22997)
{
plugin.buildEntries(compostId);
}
else
{
plugin.buildEntries(bucketId);
}
}
}
public void setPlantId(int plantId)
{
this.plantId = plantId;
}
public void setBucketId(int bucketId)
{
this.bucketId = bucketId;
}
public void setEndlessBucket(String message)
{
if (message.toLowerCase().contains("ultracompost"))
{
compostId = ULTRACOMPOST;
}
else if (message.toLowerCase().contains("supercompost"))
{
compostId = SUPERCOMPOST;
}
else
{
compostId = COMPOST;
}
}
}

View File

@@ -0,0 +1,43 @@
package net.runelite.client.plugins.suppliestracker.skills;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.suppliestracker.SuppliesTrackerPlugin;
import javax.inject.Singleton;
@Singleton
public class Prayer
{
private SuppliesTrackerPlugin plugin;
private ItemManager itemManager;
private int bonesId = 0;
public Prayer(SuppliesTrackerPlugin plugin, ItemManager itemManager)
{
this.plugin = plugin;
this.itemManager = itemManager;
}
public void OnChat(String message)
{
String name = itemManager.getItemDefinition(bonesId).getName().toLowerCase();
if (bonesId <= 0 || !name.contains("bones"))
{
return;
}
if (message.toLowerCase().contains("you bury the bones"))
{
plugin.buildEntries(bonesId);
}
}
public void build()
{
plugin.buildEntries(bonesId);
}
public void setBonesId(int bonesId)
{
this.bonesId = bonesId;
}
}

View File

@@ -334,10 +334,11 @@ public abstract class SuppliesBox extends JPanel
if (name.toLowerCase().contains("glory")) if (name.toLowerCase().contains("glory"))
{ {
long price = (((itemManager.getItemPrice(AMULET_OF_GLORY6) - (itemManager.getItemPrice(AMULET_OF_GLORY))) * qty) / 6);
tooltip.append("Amulet of Glory(6) x ") tooltip.append("Amulet of Glory(6) x ")
.append(qty) .append(qty)
.append("/6 (") .append("/6 (")
.append(QuantityFormatter.quantityToStackSize((itemManager.getItemPrice(AMULET_OF_GLORY6) * qty) / 6)) .append(QuantityFormatter.quantityToStackSize(price))
.append("gp)"); .append("gp)");
} }
else if (name.toLowerCase().contains("dueling")) else if (name.toLowerCase().contains("dueling"))
@@ -350,18 +351,20 @@ public abstract class SuppliesBox extends JPanel
} }
else if (name.toLowerCase().contains("wealth")) else if (name.toLowerCase().contains("wealth"))
{ {
long price = (((itemManager.getItemPrice(RING_OF_WEALTH_5) - (itemManager.getItemPrice(RING_OF_WEALTH))) * qty) / 5);
tooltip.append("Ring of Wealth(5) x ") tooltip.append("Ring of Wealth(5) x ")
.append(qty) .append(qty)
.append("/5 (") .append("/5 (")
.append(QuantityFormatter.quantityToStackSize((itemManager.getItemPrice(RING_OF_WEALTH_5) * qty) / 5)) .append(QuantityFormatter.quantityToStackSize(price))
.append("gp)"); .append("gp)");
} }
else if (name.toLowerCase().contains("combat")) else if (name.toLowerCase().contains("combat"))
{ {
long price = (((itemManager.getItemPrice(COMBAT_BRACELET6) - (itemManager.getItemPrice(COMBAT_BRACELET))) * qty) / 6);
tooltip.append("Combat Bracelet(6) x ") tooltip.append("Combat Bracelet(6) x ")
.append(qty) .append(qty)
.append("/6 (") .append("/6 (")
.append(QuantityFormatter.quantityToStackSize((itemManager.getItemPrice(COMBAT_BRACELET6) * qty) / 6)) .append(QuantityFormatter.quantityToStackSize(price))
.append("gp)"); .append("gp)");
} }
else if (name.toLowerCase().contains("games")) else if (name.toLowerCase().contains("games"))
@@ -374,10 +377,11 @@ public abstract class SuppliesBox extends JPanel
} }
else if (name.toLowerCase().contains("skills")) else if (name.toLowerCase().contains("skills"))
{ {
long price = (((itemManager.getItemPrice(SKILLS_NECKLACE6) - (itemManager.getItemPrice(SKILLS_NECKLACE))) * qty) / 6);
tooltip.append("Skills Necklace(6) x ") tooltip.append("Skills Necklace(6) x ")
.append(qty) .append(qty)
.append("/6 (") .append("/6 (")
.append(QuantityFormatter.quantityToStackSize((itemManager.getItemPrice(SKILLS_NECKLACE6) * qty) / 6)) .append(QuantityFormatter.quantityToStackSize(price))
.append("gp)"); .append("gp)");
} }
else if (name.toLowerCase().contains("passage")) else if (name.toLowerCase().contains("passage"))

View File

@@ -5,17 +5,16 @@
<p>Uses a formula to estimate usage since there is no way to get info from blowpipe automatically.&nbsp;</p> <p>Uses a formula to estimate usage since there is no way to get info from blowpipe automatically.&nbsp;</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<h4>Weapon charges:</h4> <h4>Weapon charges:</h4>
<p>(Default disabled to enable check box in configs) Weapons charges groups items used in weapons charged in a box with <p>(Default disabled to enable check box in configs) Weapons charges groups items used in weapons charged in a box with the weapons icon. Tooltip shows the items used.&nbsp;</p>
the weapons icon. Tooltip shows the items used.&nbsp;</p>
<p>Current supported weapons:</p> <p>Current supported weapons:</p>
<ol> <ol>
<li>Scythe</li> <li>Scythe</li>
<li>Tridents</li> <li>Tridents</li>
<li>Sang staff</li> <li>Sang staff</li>
<li>Blade of Saeldor</li>
</ol> </ol>
<p>&nbsp;</p> <p>&nbsp;</p>
<p><span style="color: #ff0000;"><em>Supplies tracker may not be 100% accurate. Tick eating with Karambwan can be missed if they aren't eaten the same tick as other food.</em></span> <p><span style="color: #ff0000;"><em>Supplies tracker may not be 100% accurate. Tick eating with Karambwan can be missed if they aren't eaten the same tick as other food.</em></span></p>
</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<p>Current tracking capabilities:</p> <p>Current tracking capabilities:</p>
<p>Supplies (food, potions, teleport tablets, teleport scrolls)</p> <p>Supplies (food, potions, teleport tablets, teleport scrolls)</p>
@@ -23,7 +22,31 @@
<p>Runes (Rune Pouch support added in 1.5)</p> <p>Runes (Rune Pouch support added in 1.5)</p>
<p>Jewellery</p> <p>Jewellery</p>
<p>Weapons charges</p> <p>Weapons charges</p>
<p>Farming (saplings, seeds, compost, and plant cure)</p>
<p>Prayer (bones and ensouled heads. Chaos altar, gilded altar, and burying bones)</p>
<h3 style="text-align: center;">Changelog</h3> <h3 style="text-align: center;">Changelog</h3>
<h2>1.8</h2>
<p>Prayer added:
<li>POH altar</li>
<li>Chaos Altar</li>
<li>Ensouled heads</li>
<li>Bury bones</li></p>
<p>Fixed bottomless buckets showing in farming supplies</p>
<p>Small bugs with prices</p>
<p>Changed dragonstone jewellery to only add cost of charges [(cost of full - cost of empty)/number of max charges]</p>
<h2>1.7</h2>
<p>Added farming:
<br>-Saplings
<br>-Seeds
<br>-Compost
<br>-and plant cure</p>
<p>fixed one handed swords showing as Blade of Saeldor</p>
<p>Added check to rune pouch to help with bugs</p>
<h2>1.6</h2>
<p>Added standard spell tracking</p>
<p>Auto cast tracking</p>
<p>Chinchompas no longer steal food</p>
<p>Runes now properly used when player gets no xp</p>
<h2>1.5</h2> <h2>1.5</h2>
<p>Added Rune pouch support!</p> <p>Added Rune pouch support!</p>
<p>Null items shouldn't show anymore</p> <p>Null items shouldn't show anymore</p>