timetracking: add farming contract functionality
Co-authored-by: Koekkruimels <lifeinvader-dev@outlook.com>
This commit is contained in:
@@ -31,6 +31,7 @@ import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
@@ -47,7 +48,12 @@ class OverviewItemPanel extends JPanel
|
||||
|
||||
private static final Color HOVER_COLOR = ColorScheme.DARKER_GRAY_HOVER_COLOR;
|
||||
|
||||
private final JPanel textContainer;
|
||||
private final JLabel statusLabel;
|
||||
private final JLabel arrowLabel;
|
||||
private final BooleanSupplier isSelectable;
|
||||
|
||||
private boolean isHighlighted;
|
||||
|
||||
static
|
||||
{
|
||||
@@ -56,16 +62,23 @@ class OverviewItemPanel extends JPanel
|
||||
|
||||
OverviewItemPanel(ItemManager itemManager, TimeTrackingPanel pluginPanel, Tab tab, String title)
|
||||
{
|
||||
this(itemManager, () -> pluginPanel.switchTab(tab), () -> true, tab.getItemID(), title);
|
||||
}
|
||||
|
||||
OverviewItemPanel(ItemManager itemManager, Runnable onTabSwitched, BooleanSupplier isSelectable, int iconItemID, String title)
|
||||
{
|
||||
this.isSelectable = isSelectable;
|
||||
|
||||
setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(7, 7, 7, 7));
|
||||
|
||||
JLabel iconLabel = new JLabel();
|
||||
iconLabel.setMinimumSize(new Dimension(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT));
|
||||
itemManager.getImage(tab.getItemID()).addTo(iconLabel);
|
||||
itemManager.getImage(iconItemID).addTo(iconLabel);
|
||||
add(iconLabel, BorderLayout.WEST);
|
||||
|
||||
JPanel textContainer = new JPanel();
|
||||
textContainer = new JPanel();
|
||||
textContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
textContainer.setLayout(new GridLayout(2, 1));
|
||||
textContainer.setBorder(new EmptyBorder(5, 7, 5, 7));
|
||||
@@ -75,32 +88,27 @@ class OverviewItemPanel extends JPanel
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
pluginPanel.switchTab(tab);
|
||||
setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
textContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
onTabSwitched.run();
|
||||
|
||||
setHighlighted(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
setBackground(HOVER_COLOR);
|
||||
textContainer.setBackground(HOVER_COLOR);
|
||||
setHighlighted(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
setBackground(HOVER_COLOR);
|
||||
textContainer.setBackground(HOVER_COLOR);
|
||||
setCursor(new Cursor(Cursor.HAND_CURSOR));
|
||||
setHighlighted(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
textContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
||||
setHighlighted(false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -117,7 +125,8 @@ class OverviewItemPanel extends JPanel
|
||||
|
||||
add(textContainer, BorderLayout.CENTER);
|
||||
|
||||
JLabel arrowLabel = new JLabel(ARROW_RIGHT_ICON);
|
||||
arrowLabel = new JLabel(ARROW_RIGHT_ICON);
|
||||
arrowLabel.setVisible(isSelectable.getAsBoolean());
|
||||
add(arrowLabel, BorderLayout.EAST);
|
||||
}
|
||||
|
||||
@@ -125,5 +134,26 @@ class OverviewItemPanel extends JPanel
|
||||
{
|
||||
statusLabel.setText(text);
|
||||
statusLabel.setForeground(color);
|
||||
|
||||
arrowLabel.setVisible(isSelectable.getAsBoolean());
|
||||
|
||||
if (isHighlighted && !isSelectable.getAsBoolean())
|
||||
{
|
||||
setHighlighted(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHighlighted(boolean highlighted)
|
||||
{
|
||||
if (highlighted && !isSelectable.getAsBoolean())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setBackground(highlighted ? HOVER_COLOR : ColorScheme.DARKER_GRAY_COLOR);
|
||||
setCursor(new Cursor(highlighted && getMousePosition(true) != null ? Cursor.HAND_CURSOR : Cursor.DEFAULT_CURSOR));
|
||||
textContainer.setBackground(highlighted ? HOVER_COLOR : ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
isHighlighted = highlighted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,11 @@ import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
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.ui.ColorScheme;
|
||||
@@ -43,19 +46,23 @@ class OverviewTabPanel extends TabContentPanel
|
||||
private final FarmingTracker farmingTracker;
|
||||
private final BirdHouseTracker birdHouseTracker;
|
||||
private final ClockManager clockManager;
|
||||
private final FarmingContractManager farmingContractManager;
|
||||
|
||||
private final OverviewItemPanel timerOverview;
|
||||
private final OverviewItemPanel stopwatchOverview;
|
||||
private final Map<Tab, OverviewItemPanel> farmingOverviews;
|
||||
private final OverviewItemPanel birdHouseOverview;
|
||||
private final OverviewItemPanel farmingContractOverview;
|
||||
|
||||
OverviewTabPanel(ItemManager itemManager, TimeTrackingConfig config, TimeTrackingPanel pluginPanel,
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager)
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager,
|
||||
FarmingContractManager farmingContractManager)
|
||||
{
|
||||
this.config = config;
|
||||
this.farmingTracker = farmingTracker;
|
||||
this.birdHouseTracker = birdHouseTracker;
|
||||
this.clockManager = clockManager;
|
||||
this.farmingContractManager = farmingContractManager;
|
||||
|
||||
setLayout(new GridLayout(0, 1, 0, 8));
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
@@ -80,6 +87,10 @@ class OverviewTabPanel extends TabContentPanel
|
||||
return p;
|
||||
}
|
||||
));
|
||||
|
||||
farmingContractOverview = new OverviewItemPanel(itemManager, () -> pluginPanel.switchTab(farmingContractManager.getContractTab()),
|
||||
farmingContractManager::hasContract, ItemID.SEED_PACK, "Farming Contract");
|
||||
add(farmingContractOverview);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,12 +124,14 @@ class OverviewTabPanel extends TabContentPanel
|
||||
}
|
||||
|
||||
farmingOverviews.forEach((patchType, panel) ->
|
||||
updateItemPanel(panel, farmingTracker.getSummary(patchType), farmingTracker.getCompletionTime(patchType)));
|
||||
updateItemPanel(panel, farmingTracker.getSummary(patchType), farmingTracker.getCompletionTime(patchType), null));
|
||||
|
||||
updateItemPanel(birdHouseOverview, birdHouseTracker.getSummary(), birdHouseTracker.getCompletionTime());
|
||||
updateItemPanel(birdHouseOverview, birdHouseTracker.getSummary(), birdHouseTracker.getCompletionTime(), null);
|
||||
updateItemPanel(farmingContractOverview, farmingContractManager.getSummary(), farmingContractManager.getCompletionTime(),
|
||||
farmingContractManager.getContractName());
|
||||
}
|
||||
|
||||
private void updateItemPanel(OverviewItemPanel panel, SummaryState summary, long completionTime)
|
||||
private void updateItemPanel(OverviewItemPanel panel, SummaryState summary, long completionTime, @Nullable String farmingContract)
|
||||
{
|
||||
switch (summary)
|
||||
{
|
||||
@@ -135,11 +148,13 @@ class OverviewTabPanel extends TabContentPanel
|
||||
{
|
||||
panel.updateStatus("Ready " + getFormattedEstimate(duration, config.estimateRelative()), Color.GRAY);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case EMPTY:
|
||||
panel.updateStatus("Empty", Color.GRAY);
|
||||
panel.updateStatus(farmingContract == null ? "Empty" : farmingContract, Color.GRAY);
|
||||
break;
|
||||
case OCCUPIED:
|
||||
panel.updateStatus(farmingContract == null ? "" : farmingContract, Color.RED);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
|
||||
@@ -28,6 +28,7 @@ public enum SummaryState
|
||||
{
|
||||
COMPLETED,
|
||||
IN_PROGRESS,
|
||||
OCCUPIED,
|
||||
EMPTY,
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class TabContentPanel extends JPanel
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
|
||||
protected static String getFormattedEstimate(long remainingSeconds, boolean useRelativeTime)
|
||||
public static String getFormattedEstimate(long remainingSeconds, boolean useRelativeTime)
|
||||
{
|
||||
if (useRelativeTime)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@ import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.client.util.AsyncBufferedImage;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
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.ui.ColorScheme;
|
||||
@@ -64,7 +65,8 @@ class TimeTrackingPanel extends PluginPanel
|
||||
private TabContentPanel activeTabPanel = null;
|
||||
|
||||
TimeTrackingPanel(ItemManager itemManager, TimeTrackingConfig config,
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager)
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager,
|
||||
FarmingContractManager farmingContractManager)
|
||||
{
|
||||
super(false);
|
||||
|
||||
@@ -82,13 +84,14 @@ class TimeTrackingPanel extends PluginPanel
|
||||
add(tabGroup, BorderLayout.NORTH);
|
||||
add(display, BorderLayout.CENTER);
|
||||
|
||||
addTab(Tab.OVERVIEW, new OverviewTabPanel(itemManager, config, this, farmingTracker, birdHouseTracker, clockManager));
|
||||
addTab(Tab.OVERVIEW, new OverviewTabPanel(itemManager, config, this, farmingTracker, birdHouseTracker, clockManager,
|
||||
farmingContractManager));
|
||||
addTab(Tab.CLOCK, clockManager.getClockTabPanel());
|
||||
addTab(Tab.BIRD_HOUSE, birdHouseTracker.createBirdHouseTabPanel());
|
||||
|
||||
for (Tab tab : Tab.FARMING_TABS)
|
||||
{
|
||||
addTab(tab, farmingTracker.createTabPanel(tab));
|
||||
addTab(tab, farmingTracker.createTabPanel(tab, farmingContractManager));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,12 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.UsernameChanged;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
@@ -50,11 +52,13 @@ import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.CONFIG
|
||||
import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.STOPWATCHES;
|
||||
import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.TIMERS;
|
||||
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;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@PluginDescriptor(
|
||||
@@ -64,6 +68,8 @@ import net.runelite.client.util.ImageUtil;
|
||||
)
|
||||
public class TimeTrackingPlugin extends Plugin
|
||||
{
|
||||
private static final String CONTRACT_COMPLETED = "You've completed a Farming Guild Contract. You should return to Guildmaster Jane.";
|
||||
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
|
||||
@@ -76,6 +82,9 @@ public class TimeTrackingPlugin extends Plugin
|
||||
@Inject
|
||||
private BirdHouseTracker birdHouseTracker;
|
||||
|
||||
@Inject
|
||||
private FarmingContractManager farmingContractManager;
|
||||
|
||||
@Inject
|
||||
private ClockManager clockManager;
|
||||
|
||||
@@ -85,6 +94,9 @@ public class TimeTrackingPlugin extends Plugin
|
||||
@Inject
|
||||
private TimeTrackingConfig config;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
@@ -113,7 +125,7 @@ public class TimeTrackingPlugin extends Plugin
|
||||
|
||||
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "watch.png");
|
||||
|
||||
panel = new TimeTrackingPanel(itemManager, config, farmingTracker, birdHouseTracker, clockManager);
|
||||
panel = new TimeTrackingPanel(itemManager, config, farmingTracker, birdHouseTracker, clockManager, farmingContractManager);
|
||||
|
||||
navButton = NavigationButton.builder()
|
||||
.tooltip("Time Tracking")
|
||||
@@ -140,6 +152,8 @@ public class TimeTrackingPlugin extends Plugin
|
||||
}
|
||||
|
||||
clientToolbar.removeNavigation(navButton);
|
||||
infoBoxManager.removeInfoBox(farmingContractManager.getInfoBox());
|
||||
farmingContractManager.setInfoBox(null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -193,8 +207,9 @@ public class TimeTrackingPlugin extends Plugin
|
||||
|
||||
boolean birdHouseDataChanged = birdHouseTracker.updateData(loc);
|
||||
boolean farmingDataChanged = farmingTracker.updateData(loc);
|
||||
boolean farmingContractDataChanged = farmingContractManager.updateData(loc);
|
||||
|
||||
if (birdHouseDataChanged || farmingDataChanged)
|
||||
if (birdHouseDataChanged || farmingDataChanged || farmingContractDataChanged)
|
||||
{
|
||||
panel.update();
|
||||
}
|
||||
@@ -205,9 +220,21 @@ public class TimeTrackingPlugin extends Plugin
|
||||
{
|
||||
farmingTracker.loadCompletionTimes();
|
||||
birdHouseTracker.loadFromConfig();
|
||||
farmingContractManager.loadContractFromConfig();
|
||||
panel.update();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (event.getType() != ChatMessageType.GAMEMESSAGE || !event.getMessage().equals(CONTRACT_COMPLETED))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
farmingContractManager.setContract(null);
|
||||
}
|
||||
|
||||
@Schedule(period = 10, unit = ChronoUnit.SECONDS)
|
||||
public void checkCompletion()
|
||||
{
|
||||
|
||||
@@ -44,8 +44,10 @@ public class TimeablePanel<T> extends JPanel
|
||||
{
|
||||
private final T timeable;
|
||||
private final JLabel icon = new JLabel();
|
||||
private final JLabel farmingContractIcon = new JLabel();
|
||||
private final JLabel estimate = new JLabel();
|
||||
private final ThinProgressBar progress = new ThinProgressBar();
|
||||
private final JLabel text;
|
||||
|
||||
public TimeablePanel(T timeable, String title, int maximumProgressValue)
|
||||
{
|
||||
@@ -60,23 +62,25 @@ public class TimeablePanel<T> extends JPanel
|
||||
topContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
icon.setMinimumSize(new Dimension(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT));
|
||||
farmingContractIcon.setMinimumSize(new Dimension(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT));
|
||||
|
||||
JPanel infoPanel = new JPanel();
|
||||
infoPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
infoPanel.setLayout(new GridLayout(2, 1));
|
||||
infoPanel.setBorder(new EmptyBorder(4, 4, 4, 0));
|
||||
|
||||
final JLabel location = new JShadowedLabel(title);
|
||||
location.setFont(FontManager.getRunescapeSmallFont());
|
||||
location.setForeground(Color.WHITE);
|
||||
text = new JShadowedLabel(title);
|
||||
text.setFont(FontManager.getRunescapeSmallFont());
|
||||
text.setForeground(Color.WHITE);
|
||||
|
||||
estimate.setFont(FontManager.getRunescapeSmallFont());
|
||||
estimate.setForeground(Color.GRAY);
|
||||
|
||||
infoPanel.add(location);
|
||||
infoPanel.add(text);
|
||||
infoPanel.add(estimate);
|
||||
|
||||
topContainer.add(icon, BorderLayout.WEST);
|
||||
topContainer.add(farmingContractIcon, BorderLayout.EAST);
|
||||
topContainer.add(infoPanel, BorderLayout.CENTER);
|
||||
|
||||
progress.setValue(0);
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Koekkruimels <https://github.com/koekkruimels>
|
||||
* Copyright (c) 2020, melky <https://github.com/melkypie>
|
||||
* 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 java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Instant;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.timetracking.SummaryState;
|
||||
import net.runelite.client.plugins.timetracking.TabContentPanel;
|
||||
import net.runelite.client.plugins.timetracking.TimeTrackingConfig;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
class FarmingContractInfoBox extends InfoBox
|
||||
{
|
||||
@Getter
|
||||
private final Produce contract;
|
||||
private final FarmingContractManager manager;
|
||||
private final TimeTrackingConfig config;
|
||||
|
||||
FarmingContractInfoBox(BufferedImage image, Plugin plugin, Produce contract, TimeTrackingConfig config, FarmingContractManager manager)
|
||||
{
|
||||
super(image, plugin);
|
||||
this.contract = contract;
|
||||
this.config = config;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getTextColor()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip()
|
||||
{
|
||||
SummaryState summary = manager.getSummary();
|
||||
|
||||
Color contractColor;
|
||||
String contractDescription;
|
||||
switch (summary)
|
||||
{
|
||||
case COMPLETED:
|
||||
contractDescription = "Ready";
|
||||
contractColor = ColorScheme.PROGRESS_COMPLETE_COLOR;
|
||||
break;
|
||||
case OCCUPIED:
|
||||
contractDescription = "Occupied";
|
||||
contractColor = ColorScheme.PROGRESS_ERROR_COLOR;
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
contractDescription = "Ready " + TabContentPanel.getFormattedEstimate(manager.getCompletionTime() - Instant.now().getEpochSecond(),
|
||||
config.estimateRelative());
|
||||
contractColor = Color.GRAY;
|
||||
break;
|
||||
case EMPTY:
|
||||
case UNKNOWN:
|
||||
default:
|
||||
contractDescription = null;
|
||||
contractColor = Color.GRAY;
|
||||
break;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(ColorUtil.wrapWithColorTag("Farming Contract", Color.WHITE));
|
||||
sb.append("</br>");
|
||||
sb.append(ColorUtil.wrapWithColorTag(contract.getName(), contractColor));
|
||||
|
||||
if (contractDescription != null)
|
||||
{
|
||||
sb.append("</br>");
|
||||
sb.append(ColorUtil.wrapWithColorTag(contractDescription, contractColor));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Koekkruimels <https://github.com/koekkruimels>
|
||||
* Copyright (c) 2020, melky <https://github.com/melkypie>
|
||||
* 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 java.time.Instant;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NullNpcID;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
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.plugins.timetracking.TimeTrackingPlugin;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
public class FarmingContractManager
|
||||
{
|
||||
private static final int GUILDMASTER_JANE_NPC_ID = NullNpcID.NULL_8628;
|
||||
private static final int FARMING_GUILD_REGION_ID = 4922;
|
||||
private static final Pattern CONTRACT_ASSIGN_PATTERN = Pattern.compile("(?:We need you to grow|Please could you grow) (?:some|a|an) ([a-zA-Z ]+)(?: for us\\?|\\.)");
|
||||
private static final String CONTRACT_REWARDED = "You'll be wanting a reward then. Here you go.";
|
||||
private static final String CONFIG_KEY_CONTRACT = "contract";
|
||||
|
||||
@Getter
|
||||
private SummaryState summary = SummaryState.UNKNOWN;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private TimeTrackingConfig config;
|
||||
|
||||
@Inject
|
||||
private TimeTrackingPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private FarmingWorld farmingWorld;
|
||||
|
||||
@Inject
|
||||
private FarmingTracker farmingTracker;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Getter
|
||||
private Produce contract = null;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private FarmingContractInfoBox infoBox;
|
||||
|
||||
@Getter
|
||||
private long completionTime;
|
||||
|
||||
public void setContract(@Nullable Produce contract)
|
||||
{
|
||||
this.contract = contract;
|
||||
setStoredContract(contract);
|
||||
handleContractState();
|
||||
}
|
||||
|
||||
public boolean hasContract()
|
||||
{
|
||||
return contract != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tab getContractTab()
|
||||
{
|
||||
return hasContract() ? contract.getPatchImplementation().getTab() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getContractName()
|
||||
{
|
||||
return hasContract() ? contract.getContractName() : null;
|
||||
}
|
||||
|
||||
public boolean shouldHighlightFarmingTabPanel(@Nonnull FarmingPatch patch)
|
||||
{
|
||||
PatchPrediction patchPrediction = farmingTracker.predictPatch(patch);
|
||||
if (contract != null &&
|
||||
patch.getRegion().getRegionID() == FARMING_GUILD_REGION_ID &&
|
||||
contract.getPatchImplementation() == patch.getImplementation() &&
|
||||
patchPrediction != null &&
|
||||
(summary == SummaryState.EMPTY &&
|
||||
(patchPrediction.getProduce() == null || patchPrediction.getProduce() == Produce.WEEDS)
|
||||
|| patchPrediction.getProduce().equals(contract)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void loadContractFromConfig()
|
||||
{
|
||||
contract = getStoredContract();
|
||||
handleContractState();
|
||||
}
|
||||
|
||||
public boolean updateData(WorldPoint loc)
|
||||
{
|
||||
SummaryState oldSummary = summary;
|
||||
|
||||
handleContractState();
|
||||
if (loc.getRegionID() == FARMING_GUILD_REGION_ID)
|
||||
{
|
||||
handleGuildmasterJaneWidgetDialog();
|
||||
handleInfoBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (infoBox != null)
|
||||
{
|
||||
infoBoxManager.removeInfoBox(infoBox);
|
||||
infoBox = null;
|
||||
}
|
||||
}
|
||||
return oldSummary != summary;
|
||||
}
|
||||
|
||||
private void handleInfoBox()
|
||||
{
|
||||
if (infoBox != null)
|
||||
{
|
||||
if (contract == null)
|
||||
{
|
||||
infoBoxManager.removeInfoBox(infoBox);
|
||||
infoBox = null;
|
||||
}
|
||||
else if (infoBox.getContract() != contract)
|
||||
{
|
||||
infoBoxManager.removeInfoBox(infoBox);
|
||||
infoBox = new FarmingContractInfoBox(itemManager.getImage(contract.getItemID()), plugin, contract, config, this);
|
||||
infoBoxManager.addInfoBox(infoBox);
|
||||
}
|
||||
}
|
||||
else if (contract != null)
|
||||
{
|
||||
infoBox = new FarmingContractInfoBox(itemManager.getImage(contract.getItemID()), plugin, contract, config, this);
|
||||
infoBoxManager.addInfoBox(infoBox);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGuildmasterJaneWidgetDialog()
|
||||
{
|
||||
Widget npcDialog = client.getWidget(WidgetInfo.DIALOG_NPC_HEAD_MODEL);
|
||||
|
||||
if (npcDialog == null || npcDialog.getModelId() != GUILDMASTER_JANE_NPC_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String dialogText = Text.removeTags(client.getWidget(WidgetInfo.DIALOG_NPC_TEXT).getText());
|
||||
|
||||
if (dialogText.equals(CONTRACT_REWARDED))
|
||||
{
|
||||
setContract(null);
|
||||
}
|
||||
|
||||
Matcher matcher = CONTRACT_ASSIGN_PATTERN.matcher(dialogText);
|
||||
|
||||
if (!matcher.find())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String name = matcher.group(1);
|
||||
|
||||
Produce farmingContract = Produce.getByContractName(name);
|
||||
|
||||
if (farmingContract == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Produce currentFarmingContract = contract;
|
||||
|
||||
if (farmingContract == currentFarmingContract)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setContract(farmingContract);
|
||||
}
|
||||
|
||||
private void handleContractState()
|
||||
{
|
||||
if (contract == null)
|
||||
{
|
||||
summary = SummaryState.UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
PatchImplementation patchImplementation = contract.getPatchImplementation();
|
||||
|
||||
boolean hasEmptyPatch = false;
|
||||
completionTime = Long.MAX_VALUE;
|
||||
for (FarmingPatch patch : farmingWorld.getFarmingGuildRegion().getPatches())
|
||||
{
|
||||
if (patch.getImplementation() != patchImplementation)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PatchPrediction prediction = farmingTracker.predictPatch(patch);
|
||||
if (prediction == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Produce produce = prediction.getProduce();
|
||||
if (completionTime == Long.MAX_VALUE)
|
||||
{
|
||||
if (produce == null || produce == Produce.WEEDS)
|
||||
{
|
||||
summary = SummaryState.EMPTY;
|
||||
hasEmptyPatch = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((contract.requiresHealthCheck() && prediction.getCropState() == CropState.HARVESTABLE)
|
||||
&& !hasEmptyPatch)
|
||||
{
|
||||
summary = SummaryState.OCCUPIED;
|
||||
}
|
||||
}
|
||||
|
||||
if (produce != contract)
|
||||
{
|
||||
if (!hasEmptyPatch && completionTime == Long.MAX_VALUE)
|
||||
{
|
||||
summary = SummaryState.OCCUPIED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
long estimatedTime = Math.min(prediction.getDoneEstimate(), completionTime);
|
||||
|
||||
if (estimatedTime <= Instant.now().getEpochSecond())
|
||||
{
|
||||
summary = SummaryState.COMPLETED;
|
||||
completionTime = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
summary = SummaryState.IN_PROGRESS;
|
||||
completionTime = estimatedTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private Produce getStoredContract()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Produce.getByItemID(Integer.parseInt(configManager.getConfiguration(getConfigGroup(), CONFIG_KEY_CONTRACT)));
|
||||
}
|
||||
catch (NumberFormatException ignored)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setStoredContract(@Nullable Produce contract)
|
||||
{
|
||||
if (contract != null)
|
||||
{
|
||||
configManager.setConfiguration(getConfigGroup(), CONFIG_KEY_CONTRACT, String.valueOf(contract.getItemID()));
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.unsetConfiguration(getConfigGroup(), CONFIG_KEY_CONTRACT);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private String getConfigGroup()
|
||||
{
|
||||
return TimeTrackingConfig.CONFIG_GROUP + "." + client.getUsername();
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.TabContentPanel;
|
||||
import net.runelite.client.plugins.timetracking.TimeTrackingConfig;
|
||||
@@ -47,18 +48,21 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
private final ItemManager itemManager;
|
||||
private final TimeTrackingConfig config;
|
||||
private final List<TimeablePanel<FarmingPatch>> patchPanels;
|
||||
private final FarmingContractManager farmingContractManager;
|
||||
|
||||
FarmingTabPanel(
|
||||
FarmingTracker farmingTracker,
|
||||
ItemManager itemManager,
|
||||
TimeTrackingConfig config,
|
||||
Set<FarmingPatch> patches
|
||||
Set<FarmingPatch> patches,
|
||||
FarmingContractManager farmingContractManager
|
||||
)
|
||||
{
|
||||
this.farmingTracker = farmingTracker;
|
||||
this.itemManager = itemManager;
|
||||
this.config = config;
|
||||
this.patchPanels = new ArrayList<>();
|
||||
this.farmingContractManager = farmingContractManager;
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
@@ -187,6 +191,17 @@ 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("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +70,9 @@ public class FarmingTracker
|
||||
}
|
||||
|
||||
|
||||
public FarmingTabPanel createTabPanel(Tab tab)
|
||||
public FarmingTabPanel createTabPanel(Tab tab, FarmingContractManager farmingContractManager)
|
||||
{
|
||||
return new FarmingTabPanel(this, itemManager, config, farmingWorld.getTabs().get(tab));
|
||||
return new FarmingTabPanel(this, itemManager, config, farmingWorld.getTabs().get(tab), farmingContractManager);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,6 +52,9 @@ class FarmingWorld
|
||||
.thenComparing((FarmingPatch p) -> p.getRegion().getName())
|
||||
.thenComparing(FarmingPatch::getName);
|
||||
|
||||
@Getter
|
||||
private final FarmingRegion farmingGuildRegion;
|
||||
|
||||
FarmingWorld()
|
||||
{
|
||||
// Some of these patches get updated in multiple regions.
|
||||
@@ -229,7 +232,7 @@ class FarmingWorld
|
||||
new FarmingPatch("Hespori", Varbits.FARMING_7908, PatchImplementation.HESPORI)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Farming Guild", 4922,
|
||||
add(farmingGuildRegion = new FarmingRegion("Farming Guild", 4922,
|
||||
new FarmingPatch("", Varbits.FARMING_7905, PatchImplementation.TREE),
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.HERB),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.BUSH),
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.timetracking.farming;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.ItemID;
|
||||
@@ -38,30 +39,30 @@ public enum Produce
|
||||
SCARECROW("Scarecrow", ItemID.SCARECROW, 5, 4),
|
||||
|
||||
// Allotment crops
|
||||
POTATO("Potato", ItemID.POTATO, 10, 5, 0, 3),
|
||||
ONION("Onion", ItemID.ONION, 10, 5, 0, 3),
|
||||
CABBAGE("Cabbage", ItemID.CABBAGE, 10, 5, 0, 3),
|
||||
TOMATO("Tomato", ItemID.TOMATO, 10, 5, 0, 3),
|
||||
SWEETCORN("Sweetcorn", ItemID.SWEETCORN, 10, 6, 0, 3),
|
||||
STRAWBERRY("Strawberry", ItemID.STRAWBERRY, 10, 7, 0, 3),
|
||||
WATERMELON("Watermelon", ItemID.WATERMELON, 10, 8, 0, 3),
|
||||
SNAPE_GRASS("Snape grass", ItemID.SNAPE_GRASS, 10, 8, 0, 3),
|
||||
POTATO("Potato", "Potatoes", PatchImplementation.ALLOTMENT, ItemID.POTATO, 10, 5, 0, 3),
|
||||
ONION("Onion", "Onions", PatchImplementation.ALLOTMENT, ItemID.ONION, 10, 5, 0, 3),
|
||||
CABBAGE("Cabbage", "Cabbages", PatchImplementation.ALLOTMENT, ItemID.CABBAGE, 10, 5, 0, 3),
|
||||
TOMATO("Tomato", "Tomatoes", PatchImplementation.ALLOTMENT, ItemID.TOMATO, 10, 5, 0, 3),
|
||||
SWEETCORN("Sweetcorn", PatchImplementation.ALLOTMENT, ItemID.SWEETCORN, 10, 6, 0, 3),
|
||||
STRAWBERRY("Strawberry", "Strawberries", PatchImplementation.ALLOTMENT, ItemID.STRAWBERRY, 10, 7, 0, 3),
|
||||
WATERMELON("Watermelon", "Watermelons", PatchImplementation.ALLOTMENT, ItemID.WATERMELON, 10, 8, 0, 3),
|
||||
SNAPE_GRASS("Snape grass", PatchImplementation.ALLOTMENT, ItemID.SNAPE_GRASS, 10, 8, 0, 3),
|
||||
|
||||
// Flower crops
|
||||
MARIGOLD("Marigold", ItemID.MARIGOLDS, 5, 5),
|
||||
ROSEMARY("Rosemary", ItemID.ROSEMARY, 5, 5),
|
||||
NASTURTIUM("Nasturtium", ItemID.NASTURTIUMS, 5, 5),
|
||||
WOAD("Woad", ItemID.WOAD_LEAF, 5, 5),
|
||||
LIMPWURT("Limpwurt", ItemID.LIMPWURT_ROOT, 5, 5),
|
||||
WHITE_LILY("While lily", ItemID.WHITE_LILY, 5, 5),
|
||||
MARIGOLD("Marigold", "Marigolds", PatchImplementation.FLOWER, ItemID.MARIGOLDS, 5, 5),
|
||||
ROSEMARY("Rosemary", PatchImplementation.FLOWER, ItemID.ROSEMARY, 5, 5),
|
||||
NASTURTIUM("Nasturtium", "Nasturtiums", PatchImplementation.FLOWER, ItemID.NASTURTIUMS, 5, 5),
|
||||
WOAD("Woad", PatchImplementation.FLOWER, ItemID.WOAD_LEAF, 5, 5),
|
||||
LIMPWURT("Limpwurt", "Limpwurt roots", PatchImplementation.FLOWER, ItemID.LIMPWURT_ROOT, 5, 5),
|
||||
WHITE_LILY("White lily", "White lillies", PatchImplementation.FLOWER, ItemID.WHITE_LILY, 5, 5),
|
||||
|
||||
// Bush crops
|
||||
REDBERRIES("Redberry", ItemID.REDBERRIES, 20, 6, 20, 5),
|
||||
CADAVABERRIES("Cadavaberry", ItemID.CADAVA_BERRIES, 20, 7, 20, 5),
|
||||
DWELLBERRIES("Dwellberry", ItemID.DWELLBERRIES, 20, 8, 20, 5),
|
||||
JANGERBERRIES("Jangerberry", ItemID.JANGERBERRIES, 20, 9, 20, 5),
|
||||
WHITEBERRIES("Whiteberry", ItemID.WHITE_BERRIES, 20, 9, 20, 5),
|
||||
POISON_IVY("Poison", ItemID.POISON_IVY_BERRIES, 20, 9, 20, 5),
|
||||
REDBERRIES("Redberry", "Redberries", PatchImplementation.BUSH, ItemID.REDBERRIES, 20, 6, 20, 5),
|
||||
CADAVABERRIES("Cadavaberry", "Cadava berries", PatchImplementation.BUSH, ItemID.CADAVA_BERRIES, 20, 7, 20, 5),
|
||||
DWELLBERRIES("Dwellberry", "Dwellberries", PatchImplementation.BUSH, ItemID.DWELLBERRIES, 20, 8, 20, 5),
|
||||
JANGERBERRIES("Jangerberry", "Jangerberries", PatchImplementation.BUSH, ItemID.JANGERBERRIES, 20, 9, 20, 5),
|
||||
WHITEBERRIES("Whiteberry", "White berries", PatchImplementation.BUSH, ItemID.WHITE_BERRIES, 20, 9, 20, 5),
|
||||
POISON_IVY("Poison", "Poison ivy berries", PatchImplementation.BUSH, ItemID.POISON_IVY_BERRIES, 20, 9, 20, 5),
|
||||
|
||||
// Hop crops
|
||||
BARLEY("Barley", ItemID.BARLEY, 10, 5, 0, 3),
|
||||
@@ -73,43 +74,43 @@ public enum Produce
|
||||
WILDBLOOD("Wildblood", ItemID.WILDBLOOD_HOPS, 10, 9, 0, 3),
|
||||
|
||||
// Herb crops
|
||||
GUAM("Guam", ItemID.GUAM_LEAF, 20, 5, 0, 3),
|
||||
MARRENTILL("Marrentill", ItemID.MARRENTILL, 20, 5, 0, 3),
|
||||
TARROMIN("Tarromin", ItemID.TARROMIN, 20, 5, 0, 3),
|
||||
HARRALANDER("Harralander", ItemID.HARRALANDER, 20, 5, 0, 3),
|
||||
RANARR("Ranarr", ItemID.RANARR_WEED, 20, 5, 0, 3),
|
||||
TOADFLAX("Toadflax", ItemID.TOADFLAX, 20, 5, 0, 3),
|
||||
IRIT("Irit", ItemID.IRIT_LEAF, 20, 5, 0, 3),
|
||||
AVANTOE("Avantoe", ItemID.AVANTOE, 20, 5, 0, 3),
|
||||
KWUARM("Kwuarm", ItemID.KWUARM, 20, 5, 0, 3),
|
||||
SNAPDRAGON("Snapdragon", ItemID.SNAPDRAGON, 20, 5, 0, 3),
|
||||
CADANTINE("Cadantine", ItemID.CADANTINE, 20, 5, 0, 3),
|
||||
LANTADYME("Lantadyme", ItemID.LANTADYME, 20, 5, 0, 3),
|
||||
DWARF_WEED("Dwarf Weed", ItemID.DWARF_WEED, 20, 5, 0, 3),
|
||||
TORSTOL("Torstol", ItemID.TORSTOL, 20, 5, 0, 3),
|
||||
GOUTWEED("Goutweed", ItemID.GOUTWEED, 20, 5, 0, 2),
|
||||
ANYHERB("Any herb", ItemID.GUAM_LEAF, 20, 5, 0, 3),
|
||||
GUAM("Guam", PatchImplementation.HERB, ItemID.GUAM_LEAF, 20, 5, 0, 3),
|
||||
MARRENTILL("Marrentill", PatchImplementation.HERB, ItemID.MARRENTILL, 20, 5, 0, 3),
|
||||
TARROMIN("Tarromin", PatchImplementation.HERB, ItemID.TARROMIN, 20, 5, 0, 3),
|
||||
HARRALANDER("Harralander", PatchImplementation.HERB, ItemID.HARRALANDER, 20, 5, 0, 3),
|
||||
RANARR("Ranarr", PatchImplementation.HERB, ItemID.RANARR_WEED, 20, 5, 0, 3),
|
||||
TOADFLAX("Toadflax", PatchImplementation.HERB, ItemID.TOADFLAX, 20, 5, 0, 3),
|
||||
IRIT("Irit", PatchImplementation.HERB, ItemID.IRIT_LEAF, 20, 5, 0, 3),
|
||||
AVANTOE("Avantoe", PatchImplementation.HERB, ItemID.AVANTOE, 20, 5, 0, 3),
|
||||
KWUARM("Kwuarm", PatchImplementation.HERB, ItemID.KWUARM, 20, 5, 0, 3),
|
||||
SNAPDRAGON("Snapdragon", PatchImplementation.HERB, ItemID.SNAPDRAGON, 20, 5, 0, 3),
|
||||
CADANTINE("Cadantine", PatchImplementation.HERB, ItemID.CADANTINE, 20, 5, 0, 3),
|
||||
LANTADYME("Lantadyme", PatchImplementation.HERB, ItemID.LANTADYME, 20, 5, 0, 3),
|
||||
DWARF_WEED("Dwarf Weed", PatchImplementation.HERB, ItemID.DWARF_WEED, 20, 5, 0, 3),
|
||||
TORSTOL("Torstol", PatchImplementation.HERB, ItemID.TORSTOL, 20, 5, 0, 3),
|
||||
GOUTWEED("Goutweed", PatchImplementation.HERB, ItemID.GOUTWEED, 20, 5, 0, 2),
|
||||
ANYHERB("Any herb", PatchImplementation.HERB, ItemID.GUAM_LEAF, 20, 5, 0, 3),
|
||||
|
||||
// Tree crops
|
||||
OAK("Oak", ItemID.OAK_LOGS, 40, 5),
|
||||
WILLOW("Willow", ItemID.WILLOW_LOGS, 40, 7),
|
||||
MAPLE("Maple", ItemID.MAPLE_LOGS, 40, 9),
|
||||
YEW("Yew", ItemID.YEW_LOGS, 40, 11),
|
||||
MAGIC("Magic", ItemID.MAGIC_LOGS, 40, 13),
|
||||
OAK("Oak", "Oak tree", PatchImplementation.TREE, ItemID.OAK_LOGS, 40, 5),
|
||||
WILLOW("Willow", "Willow tree", PatchImplementation.TREE, ItemID.WILLOW_LOGS, 40, 7),
|
||||
MAPLE("Maple", "Maple tree", PatchImplementation.TREE, ItemID.MAPLE_LOGS, 40, 9),
|
||||
YEW("Yew", "Yew tree", PatchImplementation.TREE, ItemID.YEW_LOGS, 40, 11),
|
||||
MAGIC("Magic", "Magic tree", PatchImplementation.TREE, ItemID.MAGIC_LOGS, 40, 13),
|
||||
|
||||
// Fruit tree crops
|
||||
APPLE("Apple", ItemID.COOKING_APPLE, 160, 7, 45, 7),
|
||||
BANANA("Banana", ItemID.BANANA, 160, 7, 45, 7),
|
||||
ORANGE("Orange", ItemID.ORANGE, 160, 7, 45, 7),
|
||||
CURRY("Curry", ItemID.CURRY_LEAF, 160, 7, 45, 7),
|
||||
PINEAPPLE("Pineapple", ItemID.PINEAPPLE, 160, 7, 45, 7),
|
||||
PAPAYA("Papaya", ItemID.PAPAYA_FRUIT, 160, 7, 45, 7),
|
||||
PALM("Palm", ItemID.COCONUT, 160, 7, 45, 7),
|
||||
DRAGONFRUIT("Dragonfruit", ItemID.DRAGONFRUIT, 160, 7, 45, 7),
|
||||
APPLE("Apple", "Apple tree", PatchImplementation.FRUIT_TREE, ItemID.COOKING_APPLE, 160, 7, 45, 7),
|
||||
BANANA("Banana", "Banana tree", PatchImplementation.FRUIT_TREE, ItemID.BANANA, 160, 7, 45, 7),
|
||||
ORANGE("Orange", "Orange tree", PatchImplementation.FRUIT_TREE, ItemID.ORANGE, 160, 7, 45, 7),
|
||||
CURRY("Curry", "Curry tree", PatchImplementation.FRUIT_TREE, ItemID.CURRY_LEAF, 160, 7, 45, 7),
|
||||
PINEAPPLE("Pineapple", "Pineapple plant", PatchImplementation.FRUIT_TREE, ItemID.PINEAPPLE, 160, 7, 45, 7),
|
||||
PAPAYA("Papaya", "Papaya tree", PatchImplementation.FRUIT_TREE, ItemID.PAPAYA_FRUIT, 160, 7, 45, 7),
|
||||
PALM("Palm", "Palm tree", PatchImplementation.FRUIT_TREE, ItemID.COCONUT, 160, 7, 45, 7),
|
||||
DRAGONFRUIT("Dragonfruit", "Dragonfruit tree", PatchImplementation.FRUIT_TREE, ItemID.DRAGONFRUIT, 160, 7, 45, 7),
|
||||
|
||||
// Cactus
|
||||
CACTUS("Cactus", ItemID.CACTUS_SPINE, 80, 8, 20, 4),
|
||||
POTATO_CACTUS("Potato cactus", ItemID.POTATO_CACTUS, 10, 8, 5, 7),
|
||||
CACTUS("Cactus", PatchImplementation.CACTUS, ItemID.CACTUS_SPINE, 80, 8, 20, 4),
|
||||
POTATO_CACTUS("Potato cactus", "Potato cacti", PatchImplementation.CACTUS, ItemID.POTATO_CACTUS, 10, 8, 5, 7),
|
||||
|
||||
// Hardwood
|
||||
TEAK("Teak", ItemID.TEAK_LOGS, 560, 8),
|
||||
@@ -127,8 +128,8 @@ public enum Produce
|
||||
BELLADONNA("Belladonna", ItemID.CAVE_NIGHTSHADE, 80, 5),
|
||||
CALQUAT("Calquat", ItemID.CALQUAT_FRUIT, 160, 9, 0, 7),
|
||||
SPIRIT_TREE("Spirit tree", ItemID.SPIRIT_TREE, 320, 13),
|
||||
CELASTRUS("Celastrus", ItemID.BATTLESTAFF, 160, 6, 0, 4),
|
||||
REDWOOD("Redwood", ItemID.REDWOOD_LOGS, 640, 11),
|
||||
CELASTRUS("Celastrus", "Celastrus tree", PatchImplementation.CELASTRUS, ItemID.BATTLESTAFF, 160, 6, 0, 4),
|
||||
REDWOOD("Redwood", "Redwood tree", PatchImplementation.REDWOOD, ItemID.REDWOOD_LOGS, 640, 11),
|
||||
HESPORI("Hespori", NullItemID.NULL_23044, 640, 4, 0, 2),
|
||||
CRYSTAL_TREE("Crystal tree", ItemID.CRYSTAL_SHARDS, 80, 7);
|
||||
|
||||
@@ -136,6 +137,14 @@ public enum Produce
|
||||
* User-visible name
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* Farming contract names
|
||||
*/
|
||||
private final String contractName;
|
||||
/**
|
||||
* Patch type for the crop
|
||||
*/
|
||||
private final PatchImplementation patchImplementation;
|
||||
/**
|
||||
* User-visible item icon
|
||||
*/
|
||||
@@ -158,8 +167,68 @@ public enum Produce
|
||||
*/
|
||||
private final int harvestStages;
|
||||
|
||||
Produce(String name, int itemID, int tickrate, int stages, int regrowTickrate, int harvestStages)
|
||||
{
|
||||
this(name, name, null, itemID, tickrate, stages, regrowTickrate, harvestStages);
|
||||
}
|
||||
|
||||
Produce(String name, PatchImplementation patchImplementation, int itemID, int tickrate, int stages, int regrowTickrate, int harvestStages)
|
||||
{
|
||||
this(name, name, patchImplementation, itemID, tickrate, stages, regrowTickrate, harvestStages);
|
||||
}
|
||||
|
||||
Produce(String name, String contractName, PatchImplementation patchImplementation, int itemID, int tickrate, int stages)
|
||||
{
|
||||
this(name, contractName, patchImplementation, itemID, tickrate, stages, 0, 1);
|
||||
}
|
||||
|
||||
Produce(String name, PatchImplementation patchImplementation, int itemID, int tickrate, int stages)
|
||||
{
|
||||
this(name, name, patchImplementation, itemID, tickrate, stages, 0, 1);
|
||||
}
|
||||
|
||||
Produce(String name, int itemID, int tickrate, int stages)
|
||||
{
|
||||
this(name, itemID, tickrate, stages, 0, 1);
|
||||
this(name, name, null, itemID, tickrate, stages, 0, 1);
|
||||
}
|
||||
|
||||
boolean requiresHealthCheck()
|
||||
{
|
||||
switch (this.patchImplementation)
|
||||
{
|
||||
case BUSH:
|
||||
case TREE:
|
||||
case CACTUS:
|
||||
case REDWOOD:
|
||||
case CELASTRUS:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Produce getByItemID(int itemId)
|
||||
{
|
||||
for (Produce produce : Produce.values())
|
||||
{
|
||||
if (produce.getItemID() == itemId)
|
||||
{
|
||||
return produce;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Produce getByContractName(String contractName)
|
||||
{
|
||||
for (Produce produce : Produce.values())
|
||||
{
|
||||
if (produce.getContractName().equalsIgnoreCase(contractName))
|
||||
{
|
||||
return produce;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user