Merge pull request #13086 from loldudester/farming-notifications

TimeTracking: Add farming notifications
This commit is contained in:
Abex
2021-02-06 13:58:39 -07:00
committed by GitHub
12 changed files with 323 additions and 68 deletions

View File

@@ -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

View File

@@ -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",

View File

@@ -29,7 +29,6 @@ import com.google.inject.Inject;
import com.google.inject.Provides;
import java.awt.image.BufferedImage;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -58,7 +57,6 @@ import net.runelite.client.plugins.timetracking.clocks.ClockManager;
import net.runelite.client.plugins.timetracking.farming.FarmingContractManager;
import net.runelite.client.plugins.timetracking.farming.FarmingTracker;
import net.runelite.client.plugins.timetracking.hunter.BirdHouseTracker;
import net.runelite.client.task.Schedule;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@@ -102,6 +100,8 @@ public class TimeTrackingPlugin extends Plugin
private ScheduledFuture panelUpdateFuture;
private ScheduledFuture notifierFuture;
private TimeTrackingPanel panel;
private NavigationButton navButton;
@@ -139,6 +139,7 @@ public class TimeTrackingPlugin extends Plugin
clientToolbar.addNavigation(navButton);
panelUpdateFuture = executorService.scheduleAtFixedRate(this::updatePanel, 200, 200, TimeUnit.MILLISECONDS);
notifierFuture = executorService.scheduleAtFixedRate(this::checkCompletion, 10, 10, TimeUnit.SECONDS);
}
@Override
@@ -153,6 +154,7 @@ public class TimeTrackingPlugin extends Plugin
panelUpdateFuture = null;
}
notifierFuture.cancel(true);
clientToolbar.removeNavigation(navButton);
infoBoxManager.removeInfoBox(farmingContractManager.getInfoBox());
farmingContractManager.setInfoBox(null);
@@ -260,8 +262,7 @@ public class TimeTrackingPlugin extends Plugin
}
}
@Schedule(period = 10, unit = ChronoUnit.SECONDS)
public void checkCompletion()
private void checkCompletion()
{
boolean birdHouseDataChanged = birdHouseTracker.checkCompletion();
@@ -269,6 +270,8 @@ public class TimeTrackingPlugin extends Plugin
{
panel.update();
}
farmingTracker.checkCompletion();
}
private void updatePanel()

View File

@@ -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);

View File

@@ -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();
}
}

View File

@@ -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++)

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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),

View File

@@ -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