TimeTracking: Add farming notifications
This commit is contained in:
@@ -152,6 +152,11 @@ public class ConfigManager
|
||||
scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public String getRSProfileKey()
|
||||
{
|
||||
return rsProfileKey;
|
||||
}
|
||||
|
||||
public final void switchSession(AccountSession session)
|
||||
{
|
||||
// Ensure existing config is saved
|
||||
|
||||
@@ -41,6 +41,7 @@ public interface TimeTrackingConfig extends Config
|
||||
String TIMERS = "timers";
|
||||
String STOPWATCHES = "stopwatches";
|
||||
String PREFER_SOONEST = "preferSoonest";
|
||||
String NOTIFY = "notify";
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "timeFormatMode",
|
||||
|
||||
@@ -139,7 +139,7 @@ public class TimeTrackingPlugin extends Plugin
|
||||
clientToolbar.addNavigation(navButton);
|
||||
|
||||
panelUpdateFuture = executorService.scheduleAtFixedRate(this::updatePanel, 200, 200, TimeUnit.MILLISECONDS);
|
||||
notifierFuture = executorService.scheduleAtFixedRate(this::checkCompletion, 0, 10, TimeUnit.SECONDS);
|
||||
notifierFuture = executorService.scheduleAtFixedRate(this::checkCompletion, 10, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -270,6 +270,8 @@ public class TimeTrackingPlugin extends Plugin
|
||||
{
|
||||
panel.update();
|
||||
}
|
||||
|
||||
farmingTracker.checkCompletion();
|
||||
}
|
||||
|
||||
private void updatePanel()
|
||||
|
||||
@@ -29,22 +29,29 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.components.ThinProgressBar;
|
||||
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
public class TimeablePanel<T> extends JPanel
|
||||
{
|
||||
private final T timeable;
|
||||
private final JLabel icon = new JLabel();
|
||||
private final JLabel farmingContractIcon = new JLabel();
|
||||
private final JToggleButton notifyButton = new JToggleButton();
|
||||
private final JLabel estimate = new JLabel();
|
||||
private final ThinProgressBar progress = new ThinProgressBar();
|
||||
private final JLabel text;
|
||||
@@ -79,8 +86,29 @@ public class TimeablePanel<T> extends JPanel
|
||||
infoPanel.add(text);
|
||||
infoPanel.add(estimate);
|
||||
|
||||
ImageIcon notifyIcon = new ImageIcon(ImageUtil.loadImageResource(TimeTrackingPlugin.class, "notify_icon.png"));
|
||||
ImageIcon notifySelectedIcon = new ImageIcon(ImageUtil.loadImageResource(TimeTrackingPlugin.class, "notify_selected_icon.png"));
|
||||
|
||||
notifyButton.setPreferredSize(new Dimension(30, 16));
|
||||
notifyButton.setBorder(new EmptyBorder(0, 0, 0, 10));
|
||||
notifyButton.setIcon(notifyIcon);
|
||||
notifyButton.setSelectedIcon(notifySelectedIcon);
|
||||
SwingUtil.removeButtonDecorations(notifyButton);
|
||||
SwingUtil.addModalTooltip(notifyButton, "Disable notifications", "Enable notifications");
|
||||
|
||||
JPanel notifyPanel = new JPanel();
|
||||
notifyPanel.setLayout(new BorderLayout());
|
||||
notifyPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
notifyPanel.add(notifyButton, BorderLayout.CENTER);
|
||||
|
||||
JPanel iconPanel = new JPanel();
|
||||
iconPanel.setLayout(new BorderLayout());
|
||||
iconPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
iconPanel.add(notifyPanel, BorderLayout.EAST);
|
||||
iconPanel.add(farmingContractIcon, BorderLayout.WEST);
|
||||
|
||||
topContainer.add(iconPanel, BorderLayout.EAST);
|
||||
topContainer.add(icon, BorderLayout.WEST);
|
||||
topContainer.add(farmingContractIcon, BorderLayout.EAST);
|
||||
topContainer.add(infoPanel, BorderLayout.CENTER);
|
||||
|
||||
progress.setValue(0);
|
||||
|
||||
@@ -29,6 +29,7 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.client.plugins.timetracking.TimeTrackingConfig;
|
||||
|
||||
@RequiredArgsConstructor(
|
||||
access = AccessLevel.PACKAGE
|
||||
@@ -41,4 +42,14 @@ class FarmingPatch
|
||||
private final String name;
|
||||
private final Varbits varbit;
|
||||
private final PatchImplementation implementation;
|
||||
}
|
||||
|
||||
String configKey()
|
||||
{
|
||||
return region.getRegionID() + "." + varbit.getId();
|
||||
}
|
||||
|
||||
String notifyConfigKey()
|
||||
{
|
||||
return TimeTrackingConfig.NOTIFY + "." + region.getRegionID() + "." + varbit.getId();
|
||||
}
|
||||
}
|
||||
@@ -33,13 +33,15 @@ public class FarmingRegion
|
||||
{
|
||||
private final String name;
|
||||
private final int regionID;
|
||||
private final boolean definite;
|
||||
private final FarmingPatch[] patches;
|
||||
private final Varbits[] varbits;
|
||||
|
||||
FarmingRegion(String name, int regionID, FarmingPatch... patches)
|
||||
FarmingRegion(String name, int regionID, boolean definite, FarmingPatch... patches)
|
||||
{
|
||||
this.name = name;
|
||||
this.regionID = regionID;
|
||||
this.definite = definite;
|
||||
this.patches = patches;
|
||||
this.varbits = new Varbits[patches.length];
|
||||
for (int i = 0; i < patches.length; i++)
|
||||
|
||||
@@ -33,8 +33,11 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.TabContentPanel;
|
||||
import net.runelite.client.plugins.timetracking.TimeTrackingConfig;
|
||||
@@ -42,10 +45,12 @@ import net.runelite.client.plugins.timetracking.TimeablePanel;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
|
||||
@Slf4j
|
||||
public class FarmingTabPanel extends TabContentPanel
|
||||
{
|
||||
private final FarmingTracker farmingTracker;
|
||||
private final ItemManager itemManager;
|
||||
private final ConfigManager configManager;
|
||||
private final TimeTrackingConfig config;
|
||||
private final List<TimeablePanel<FarmingPatch>> patchPanels;
|
||||
private final FarmingContractManager farmingContractManager;
|
||||
@@ -53,6 +58,7 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
FarmingTabPanel(
|
||||
FarmingTracker farmingTracker,
|
||||
ItemManager itemManager,
|
||||
ConfigManager configManager,
|
||||
TimeTrackingConfig config,
|
||||
Set<FarmingPatch> patches,
|
||||
FarmingContractManager farmingContractManager
|
||||
@@ -60,6 +66,7 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
{
|
||||
this.farmingTracker = farmingTracker;
|
||||
this.itemManager = itemManager;
|
||||
this.configManager = configManager;
|
||||
this.config = config;
|
||||
this.patchPanels = new ArrayList<>();
|
||||
this.farmingContractManager = farmingContractManager;
|
||||
@@ -103,6 +110,18 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
lastImpl = patch.getImplementation();
|
||||
}
|
||||
|
||||
// Set toggle state of notification menu on icon click;
|
||||
JToggleButton toggleNotify = p.getNotifyButton();
|
||||
String configKey = patch.notifyConfigKey();
|
||||
|
||||
toggleNotify.addActionListener(e ->
|
||||
{
|
||||
if (configManager.getRSProfileKey() != null)
|
||||
{
|
||||
configManager.setRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, configKey, toggleNotify.isSelected());
|
||||
}
|
||||
});
|
||||
|
||||
patchPanels.add(p);
|
||||
add(p, c);
|
||||
c.gridy++;
|
||||
@@ -197,18 +216,26 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
{
|
||||
panel.getProgress().setVisible(false);
|
||||
}
|
||||
JLabel farmingContractIcon = panel.getFarmingContractIcon();
|
||||
if (farmingContractManager.shouldHighlightFarmingTabPanel(patch))
|
||||
{
|
||||
itemManager.getImage(ItemID.SEED_PACK).addTo(farmingContractIcon);
|
||||
farmingContractIcon.setToolTipText(farmingContractManager.getContract().getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
farmingContractIcon.setIcon(null);
|
||||
farmingContractIcon.setToolTipText("");
|
||||
}
|
||||
}
|
||||
|
||||
JLabel farmingContractIcon = panel.getFarmingContractIcon();
|
||||
if (farmingContractManager.shouldHighlightFarmingTabPanel(patch))
|
||||
{
|
||||
itemManager.getImage(ItemID.SEED_PACK).addTo(farmingContractIcon);
|
||||
farmingContractIcon.setToolTipText(farmingContractManager.getContract().getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
farmingContractIcon.setIcon(null);
|
||||
farmingContractIcon.setToolTipText("");
|
||||
}
|
||||
|
||||
String configKey = patch.notifyConfigKey();
|
||||
JToggleButton toggleNotify = panel.getNotifyButton();
|
||||
boolean notifyEnabled = Boolean.TRUE
|
||||
.equals(configManager.getRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, configKey, Boolean.class));
|
||||
|
||||
toggleNotify.setSelected(notifyEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,20 +29,28 @@ import com.google.inject.Singleton;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.vars.Autoweed;
|
||||
import net.runelite.api.widgets.WidgetModalMode;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneScapeProfile;
|
||||
import net.runelite.client.config.RuneScapeProfileType;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.SummaryState;
|
||||
import net.runelite.client.plugins.timetracking.Tab;
|
||||
import net.runelite.client.plugins.timetracking.TimeTrackingConfig;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
@@ -53,6 +61,7 @@ public class FarmingTracker
|
||||
private final ConfigManager configManager;
|
||||
private final TimeTrackingConfig config;
|
||||
private final FarmingWorld farmingWorld;
|
||||
private final Notifier notifier;
|
||||
|
||||
private final Map<Tab, SummaryState> summaries = new EnumMap<>(Tab.class);
|
||||
|
||||
@@ -61,23 +70,26 @@ public class FarmingTracker
|
||||
* or {@code -1} if we have no data about any patch of the given type.
|
||||
*/
|
||||
private final Map<Tab, Long> completionTimes = new EnumMap<>(Tab.class);
|
||||
Map<ProfilePatch, Boolean> wasNotified = new HashMap<>();
|
||||
|
||||
private boolean newRegionLoaded;
|
||||
private Collection<FarmingRegion> lastRegions;
|
||||
private boolean firstNotifyCheck = true;
|
||||
|
||||
@Inject
|
||||
private FarmingTracker(Client client, ItemManager itemManager, ConfigManager configManager, TimeTrackingConfig config, FarmingWorld farmingWorld)
|
||||
private FarmingTracker(Client client, ItemManager itemManager, ConfigManager configManager, TimeTrackingConfig config, FarmingWorld farmingWorld, Notifier notifier)
|
||||
{
|
||||
this.client = client;
|
||||
this.itemManager = itemManager;
|
||||
this.configManager = configManager;
|
||||
this.config = config;
|
||||
this.farmingWorld = farmingWorld;
|
||||
this.notifier = notifier;
|
||||
}
|
||||
|
||||
public FarmingTabPanel createTabPanel(Tab tab, FarmingContractManager farmingContractManager)
|
||||
{
|
||||
return new FarmingTabPanel(this, itemManager, config, farmingWorld.getTabs().get(tab), farmingContractManager);
|
||||
return new FarmingTabPanel(this, itemManager, configManager, config, farmingWorld.getTabs().get(tab), farmingContractManager);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +142,7 @@ public class FarmingTracker
|
||||
{
|
||||
// Write the config value if it doesn't match what is current, or it is more than 5 minutes old
|
||||
Varbits varbit = patch.getVarbit();
|
||||
String key = region.getRegionID() + "." + varbit.getId();
|
||||
String key = patch.configKey();
|
||||
String strVarbit = Integer.toString(client.getVar(varbit));
|
||||
String storedValue = configManager.getRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, key);
|
||||
|
||||
@@ -189,6 +201,12 @@ public class FarmingTracker
|
||||
configManager.setRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.FARM_TICK_OFFSET, offsetMins);
|
||||
}
|
||||
}
|
||||
if (currentPatchState.getTickRate() != 0
|
||||
// Don't set wasNotified to false if witnessing a check-health action
|
||||
&& !(previousPatchState.getCropState() == CropState.GROWING && currentPatchState.getCropState() == CropState.HARVESTABLE && currentPatchState.getProduce().getPatchImplementation().isHealthCheckRequired()))
|
||||
{
|
||||
wasNotified.put(new ProfilePatch(patch, configManager.getRSProfileKey()), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -258,17 +276,23 @@ public class FarmingTracker
|
||||
|
||||
@Nullable
|
||||
public PatchPrediction predictPatch(FarmingPatch patch)
|
||||
{
|
||||
return predictPatch(patch, configManager.getRSProfileKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PatchPrediction predictPatch(FarmingPatch patch, String profile)
|
||||
{
|
||||
long unixNow = Instant.now().getEpochSecond();
|
||||
|
||||
boolean autoweed = Integer.toString(Autoweed.ON.ordinal())
|
||||
.equals(configManager.getRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.AUTOWEED));
|
||||
.equals(configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile, TimeTrackingConfig.AUTOWEED));
|
||||
|
||||
boolean botanist = Boolean.TRUE
|
||||
.equals(configManager.getRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.BOTANIST, Boolean.class));
|
||||
.equals(configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile, TimeTrackingConfig.BOTANIST, Boolean.class));
|
||||
|
||||
String key = patch.getRegion().getRegionID() + "." + patch.getVarbit().getId();
|
||||
String storedValue = configManager.getRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, key);
|
||||
String key = patch.configKey();
|
||||
String storedValue = configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile, key);
|
||||
|
||||
if (storedValue == null)
|
||||
{
|
||||
@@ -323,11 +347,11 @@ public class FarmingTracker
|
||||
long doneEstimate = 0;
|
||||
if (tickrate > 0)
|
||||
{
|
||||
long tickNow = getTickTime(tickrate, 0, unixNow);
|
||||
long tickTime = getTickTime(tickrate, 0, unixTime);
|
||||
long tickNow = getTickTime(tickrate, 0, unixNow, profile);
|
||||
long tickTime = getTickTime(tickrate, 0, unixTime, profile);
|
||||
int delta = (int) (tickNow - tickTime) / (tickrate * 60);
|
||||
|
||||
doneEstimate = getTickTime(tickrate, stages - 1 - stage, tickTime);
|
||||
doneEstimate = getTickTime(tickrate, stages - 1 - stage, tickTime, profile);
|
||||
|
||||
stage += delta;
|
||||
if (stage >= stages)
|
||||
@@ -347,13 +371,13 @@ public class FarmingTracker
|
||||
|
||||
public long getTickTime(int tickRate, int ticks)
|
||||
{
|
||||
return getTickTime(tickRate, ticks, Instant.now().getEpochSecond());
|
||||
return getTickTime(tickRate, ticks, Instant.now().getEpochSecond(), configManager.getRSProfileKey());
|
||||
}
|
||||
|
||||
public long getTickTime(int tickRate, int ticks, long requestedTime)
|
||||
public long getTickTime(int tickRate, int ticks, long requestedTime, String profile)
|
||||
{
|
||||
Integer offsetPrecisionMins = configManager.getRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.FARM_TICK_OFFSET_PRECISION, int.class);
|
||||
Integer offsetTimeMins = configManager.getRSProfileConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.FARM_TICK_OFFSET, int.class);
|
||||
Integer offsetPrecisionMins = configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile, TimeTrackingConfig.FARM_TICK_OFFSET_PRECISION, int.class);
|
||||
Integer offsetTimeMins = configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile, TimeTrackingConfig.FARM_TICK_OFFSET, int.class);
|
||||
|
||||
//All offsets are negative but are stored as positive
|
||||
long calculatedOffsetTime = 0L;
|
||||
@@ -465,4 +489,124 @@ public class FarmingTracker
|
||||
completionTimes.put(tab.getKey(), completionTime);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkCompletion()
|
||||
{
|
||||
List<RuneScapeProfile> rsProfiles = configManager.getRSProfiles();
|
||||
long unixNow = Instant.now().getEpochSecond();
|
||||
|
||||
for (RuneScapeProfile profile : rsProfiles)
|
||||
{
|
||||
Integer offsetPrecisionMins = configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile.getKey(), TimeTrackingConfig.FARM_TICK_OFFSET_PRECISION, int.class);
|
||||
Integer offsetTimeMins = configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile.getKey(), TimeTrackingConfig.FARM_TICK_OFFSET, int.class);
|
||||
|
||||
RuneScapeProfileType profileType = profile.getType();
|
||||
|
||||
for (Map.Entry<Tab, Set<FarmingPatch>> tab : farmingWorld.getTabs().entrySet())
|
||||
{
|
||||
for (FarmingPatch patch : tab.getValue())
|
||||
{
|
||||
ProfilePatch profilePatch = new ProfilePatch(patch, profile.getKey());
|
||||
boolean patchNotified = (wasNotified.get(profilePatch) != null ? wasNotified.get(profilePatch) : false);
|
||||
String configKey = patch.notifyConfigKey();
|
||||
boolean shouldNotify = Boolean.TRUE
|
||||
.equals(configManager.getConfiguration(TimeTrackingConfig.CONFIG_GROUP, profile.getKey(), configKey, Boolean.class));
|
||||
PatchPrediction prediction = predictPatch(patch, profile.getKey());
|
||||
|
||||
if (prediction == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int tickRate = prediction.getProduce().getTickrate();
|
||||
|
||||
if (offsetPrecisionMins == null || offsetTimeMins == null || (offsetPrecisionMins < tickRate && offsetPrecisionMins < 40) || prediction.getProduce() == Produce.WEEDS
|
||||
|| unixNow <= prediction.getDoneEstimate() || patchNotified || prediction.getCropState() == CropState.FILLING)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
wasNotified.put(profilePatch, true);
|
||||
|
||||
if (!firstNotifyCheck && shouldNotify)
|
||||
{
|
||||
final StringBuilder notificationStringBuilder = new StringBuilder();
|
||||
// Same RS account
|
||||
if (client.getGameState() == GameState.LOGGED_IN && profile.getDisplayName().equals(client.getLocalPlayer().getName()))
|
||||
{
|
||||
// Same RS account but different profile type
|
||||
if (profileType != RuneScapeProfileType.getCurrent(client))
|
||||
{
|
||||
notificationStringBuilder.append("(")
|
||||
.append(Text.titleCase(profile.getType()))
|
||||
.append(") ");
|
||||
}
|
||||
// Same RS account AND profile falls through here so no bracketed prefix is added
|
||||
}
|
||||
else
|
||||
{
|
||||
// Different RS account AND profile type
|
||||
if (profileType != RuneScapeProfileType.getCurrent(client) || client.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
//Don't print profile type when logged out if is STANDARD
|
||||
if (client.getGameState() == GameState.LOGIN_SCREEN && profileType == RuneScapeProfileType.STANDARD)
|
||||
{
|
||||
notificationStringBuilder.append("(")
|
||||
.append(profile.getDisplayName())
|
||||
.append(") ");
|
||||
}
|
||||
else
|
||||
{
|
||||
notificationStringBuilder.append("(")
|
||||
.append(profile.getDisplayName())
|
||||
.append(" - ")
|
||||
.append(Text.titleCase(profile.getType()))
|
||||
.append(") ");
|
||||
}
|
||||
}
|
||||
// Different RS account but same profile type
|
||||
else
|
||||
{
|
||||
notificationStringBuilder.append("(")
|
||||
.append(profile.getDisplayName())
|
||||
.append(") ");
|
||||
}
|
||||
}
|
||||
|
||||
notificationStringBuilder
|
||||
.append("Your ")
|
||||
.append(prediction.getProduce().getName());
|
||||
|
||||
switch (prediction.getCropState())
|
||||
{
|
||||
case HARVESTABLE:
|
||||
case GROWING:
|
||||
if (prediction.getProduce().getName().toLowerCase(Locale.ENGLISH).contains("compost"))
|
||||
{
|
||||
notificationStringBuilder.append(" is ready to collect in ");
|
||||
}
|
||||
else
|
||||
{
|
||||
notificationStringBuilder.append(" is ready to harvest in ");
|
||||
}
|
||||
break;
|
||||
case DISEASED:
|
||||
notificationStringBuilder.append(" has become diseased in ");
|
||||
break;
|
||||
case DEAD:
|
||||
notificationStringBuilder.append(" has died in ");
|
||||
break;
|
||||
}
|
||||
|
||||
notificationStringBuilder.append(patch.getRegion().isDefinite() ? "the " : "")
|
||||
.append(patch.getRegion().getName())
|
||||
.append(".");
|
||||
|
||||
notifier.notify(notificationStringBuilder.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
firstNotifyCheck = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,14 +64,14 @@ class FarmingWorld
|
||||
{
|
||||
// Some of these patches get updated in multiple regions.
|
||||
// It may be worth it to add a specialization for these patches
|
||||
add(new FarmingRegion("Al Kharid", 13106,
|
||||
add(new FarmingRegion("Al Kharid", 13106, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.CACTUS)
|
||||
), 13362, 13105);
|
||||
|
||||
add(new FarmingRegion("Ardougne", 10290,
|
||||
add(new FarmingRegion("Ardougne", 10290, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH)
|
||||
), 10546);
|
||||
add(new FarmingRegion("Ardougne", 10548,
|
||||
add(new FarmingRegion("Ardougne", 10548, false,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -79,12 +79,12 @@ class FarmingWorld
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.COMPOST)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Brimhaven", 11058,
|
||||
add(new FarmingRegion("Brimhaven", 11058, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.SPIRIT_TREE)
|
||||
), 11057);
|
||||
|
||||
add(new FarmingRegion("Catherby", 11062,
|
||||
add(new FarmingRegion("Catherby", 11062, false,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -103,7 +103,7 @@ class FarmingWorld
|
||||
return true;
|
||||
}
|
||||
}, 11061, 11318, 11317);
|
||||
add(new FarmingRegion("Catherby", 11317,
|
||||
add(new FarmingRegion("Catherby", 11317, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE)
|
||||
)
|
||||
{
|
||||
@@ -115,27 +115,27 @@ class FarmingWorld
|
||||
}
|
||||
});
|
||||
|
||||
add(new FarmingRegion("Champions' Guild", 12596,
|
||||
add(new FarmingRegion("Champions' Guild", 12596, true,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Draynor Manor", 12340,
|
||||
add(new FarmingRegion("Draynor Manor", 12340, false,
|
||||
new FarmingPatch("Belladonna", Varbits.FARMING_4771, PatchImplementation.BELLADONNA)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Entrana", 11060,
|
||||
add(new FarmingRegion("Entrana", 11060, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
), 11316);
|
||||
|
||||
add(new FarmingRegion("Etceteria", 10300,
|
||||
add(new FarmingRegion("Etceteria", 10300, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.SPIRIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Falador", 11828,
|
||||
add(new FarmingRegion("Falador", 11828, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
), 12084);
|
||||
add(new FarmingRegion("Falador", 12083,
|
||||
add(new FarmingRegion("Falador", 12083, false,
|
||||
new FarmingPatch("North West", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South East", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -151,7 +151,7 @@ class FarmingWorld
|
||||
}
|
||||
});
|
||||
|
||||
add(new FarmingRegion("Fossil Island", 14651,
|
||||
add(new FarmingRegion("Fossil Island", 14651, false,
|
||||
new FarmingPatch("East", Varbits.FARMING_4771, PatchImplementation.HARDWOOD_TREE),
|
||||
new FarmingPatch("Middle", Varbits.FARMING_4772, PatchImplementation.HARDWOOD_TREE),
|
||||
new FarmingPatch("West", Varbits.FARMING_4773, PatchImplementation.HARDWOOD_TREE)
|
||||
@@ -179,22 +179,22 @@ class FarmingWorld
|
||||
return loc.getPlane() == 0;
|
||||
}
|
||||
}, 14907, 14908, 15164, 14652, 14906, 14650, 15162, 15163);
|
||||
add(new FarmingRegion("Seaweed", 15008,
|
||||
add(new FarmingRegion("Seaweed", 15008, false,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.SEAWEED),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.SEAWEED)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Gnome Stronghold", 9781,
|
||||
add(new FarmingRegion("Gnome Stronghold", 9781, true,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.FRUIT_TREE)
|
||||
), 9782, 9526, 9525);
|
||||
|
||||
add(new FarmingRegion("Harmony", 15148,
|
||||
add(new FarmingRegion("Harmony", 15148, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.HERB)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Kourend", 6967,
|
||||
add(new FarmingRegion("Kourend", 6967, false,
|
||||
new FarmingPatch("North East", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South West", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -202,7 +202,7 @@ class FarmingWorld
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.COMPOST),
|
||||
new FarmingPatch("", Varbits.FARMING_7904, PatchImplementation.SPIRIT_TREE)
|
||||
), 6711);
|
||||
add(new FarmingRegion("Kourend", 7223,
|
||||
add(new FarmingRegion("Kourend", 7223, false,
|
||||
new FarmingPatch("East 1", Varbits.GRAPES_4953, PatchImplementation.GRAPES),
|
||||
new FarmingPatch("East 2", Varbits.GRAPES_4954, PatchImplementation.GRAPES),
|
||||
new FarmingPatch("East 3", Varbits.GRAPES_4955, PatchImplementation.GRAPES),
|
||||
@@ -217,21 +217,21 @@ class FarmingWorld
|
||||
new FarmingPatch("West 6", Varbits.GRAPES_4964, PatchImplementation.GRAPES)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Lletya", 9265,
|
||||
add(new FarmingRegion("Lletya", 9265, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE)
|
||||
), 11103);
|
||||
|
||||
add(new FarmingRegion("Lumbridge", 12851,
|
||||
add(new FarmingRegion("Lumbridge", 12851, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
));
|
||||
add(new FarmingRegion("Lumbridge", 12594,
|
||||
add(new FarmingRegion("Lumbridge", 12594, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
), 12850);
|
||||
|
||||
add(new FarmingRegion("Morytania", 13622,
|
||||
add(new FarmingRegion("Morytania", 13622, false,
|
||||
new FarmingPatch("Mushroom", Varbits.FARMING_4771, PatchImplementation.MUSHROOM)
|
||||
), 13878);
|
||||
add(new FarmingRegion("Morytania", 14391,
|
||||
add(new FarmingRegion("Morytania", 14391, false,
|
||||
new FarmingPatch("North West", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South East", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -239,7 +239,7 @@ class FarmingWorld
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.COMPOST)
|
||||
), 14390);
|
||||
|
||||
add(new FarmingRegion("Port Sarim", 12082,
|
||||
add(new FarmingRegion("Port Sarim", 12082, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.SPIRIT_TREE)
|
||||
)
|
||||
{
|
||||
@@ -250,48 +250,48 @@ class FarmingWorld
|
||||
}
|
||||
}, 12083);
|
||||
|
||||
add(new FarmingRegion("Rimmington", 11570,
|
||||
add(new FarmingRegion("Rimmington", 11570, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH)
|
||||
), 11826);
|
||||
|
||||
add(new FarmingRegion("Seers' Village", 10551,
|
||||
add(new FarmingRegion("Seers' Village", 10551, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
), 10550);
|
||||
|
||||
add(new FarmingRegion("Tai Bwo Wannai", 11056,
|
||||
add(new FarmingRegion("Tai Bwo Wannai", 11056, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.CALQUAT)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Taverley", 11573,
|
||||
add(new FarmingRegion("Taverley", 11573, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
), 11829);
|
||||
|
||||
add(new FarmingRegion("Tree Gnome Village", 9777,
|
||||
add(new FarmingRegion("Tree Gnome Village", 9777, true,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE)
|
||||
), 10033);
|
||||
|
||||
add(new FarmingRegion("Troll Stronghold", 11321,
|
||||
add(new FarmingRegion("Troll Stronghold", 11321, true,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HERB)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Varrock", 12854,
|
||||
add(new FarmingRegion("Varrock", 12854, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
), 12853);
|
||||
|
||||
add(new FarmingRegion("Yanille", 10288,
|
||||
add(new FarmingRegion("Yanille", 10288, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Weiss", 11325,
|
||||
add(new FarmingRegion("Weiss", 11325, false,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HERB)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Farming Guild", 5021,
|
||||
add(new FarmingRegion("Farming Guild", 5021, true,
|
||||
new FarmingPatch("Hespori", Varbits.FARMING_7908, PatchImplementation.HESPORI)
|
||||
));
|
||||
|
||||
//Full 3x3 region area centered on farming guild
|
||||
add(farmingGuildRegion = new FarmingRegion("Farming Guild", 4922,
|
||||
add(farmingGuildRegion = new FarmingRegion("Farming Guild", 4922, true,
|
||||
new FarmingPatch("", Varbits.FARMING_7905, PatchImplementation.TREE),
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.HERB),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.BUSH),
|
||||
@@ -308,7 +308,7 @@ class FarmingWorld
|
||||
), 5177, 5178, 5179, 4921, 4923, 4665, 4666, 4667);
|
||||
|
||||
//All of Prifddinas, and all of Prifddinas Underground
|
||||
add(new FarmingRegion("Prifddinas", 13151,
|
||||
add(new FarmingRegion("Prifddinas", 13151, false,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Hannah Ryan <https://github.com/loldudester>
|
||||
* 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.timetracking.farming;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
class ProfilePatch
|
||||
{
|
||||
FarmingPatch patch;
|
||||
String rsProfileKey;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 463 B |
Binary file not shown.
|
After Width: | Height: | Size: 310 B |
Reference in New Issue
Block a user