time tracking: add bird house tracker
This commit is contained in:
@@ -95,7 +95,15 @@ public enum VarPlayer
|
||||
SLAYER_GOAL_END(1272),
|
||||
FARMING_GOAL_END(1273),
|
||||
CONSTRUCTION_GOAL_END(1274),
|
||||
HUNTER_GOAL_END(1275);
|
||||
HUNTER_GOAL_END(1275),
|
||||
|
||||
/**
|
||||
* Bird house states
|
||||
*/
|
||||
BIRD_HOUSE_MEADOW_NORTH(1626),
|
||||
BIRD_HOUSE_MEADOW_SOUTH(1627),
|
||||
BIRD_HOUSE_VALLEY_NORTH(1628),
|
||||
BIRD_HOUSE_VALLEY_SOUTH(1629);
|
||||
|
||||
private final int id;
|
||||
}
|
||||
|
||||
@@ -241,6 +241,11 @@ public class WidgetID
|
||||
static final int SPEC_ORB = 28;
|
||||
}
|
||||
|
||||
static class LoginClickToPlayScreen
|
||||
{
|
||||
static final int MESSAGE_OF_THE_DAY = 3;
|
||||
}
|
||||
|
||||
static class Viewport
|
||||
{
|
||||
static final int MINIMAP_RESIZABLE_WIDGET = 17;
|
||||
|
||||
@@ -139,6 +139,7 @@ public enum WidgetInfo
|
||||
MINIMAP_SPEC_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.SPEC_ORB),
|
||||
|
||||
LOGIN_CLICK_TO_PLAY_SCREEN(WidgetID.LOGIN_CLICK_TO_PLAY_GROUP_ID, 0),
|
||||
LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY(WidgetID.LOGIN_CLICK_TO_PLAY_GROUP_ID, WidgetID.LoginClickToPlayScreen.MESSAGE_OF_THE_DAY),
|
||||
|
||||
FIXED_VIEWPORT(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.Viewport.FIXED_VIEWPORT),
|
||||
FIXED_VIEWPORT_ROOT_INTERFACE_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.ROOT_INTERFACE_CONTAINER),
|
||||
|
||||
@@ -32,6 +32,7 @@ import net.runelite.api.ItemID;
|
||||
@Getter
|
||||
public enum Tab
|
||||
{
|
||||
BIRD_HOUSE("Bird Houses", ItemID.OAK_BIRD_HOUSE),
|
||||
ALLOTMENT("Allotment Patches", ItemID.CABBAGE),
|
||||
FLOWER("Flower Patches", ItemID.RED_FLOWERS),
|
||||
HERB("Herb Patches", ItemID.GRIMY_RANARR_WEED),
|
||||
|
||||
@@ -33,6 +33,7 @@ public interface TimeTrackingConfig extends Config
|
||||
{
|
||||
String KEY_NAME = "timetracking";
|
||||
String AUTOWEED = "autoweed";
|
||||
String BIRD_HOUSE = "birdhouse";
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "estimateRelative",
|
||||
@@ -44,6 +45,16 @@ public interface TimeTrackingConfig extends Config
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "birdHouseNotification",
|
||||
name = "Bird house notification",
|
||||
description = "Notify you when all bird houses are full"
|
||||
)
|
||||
default boolean birdHouseNotification()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "activeTab",
|
||||
name = "Active Tab",
|
||||
|
||||
@@ -39,6 +39,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.farming.FarmingTracker;
|
||||
import net.runelite.client.plugins.timetracking.hunter.BirdHouseTracker;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.components.materialtabs.MaterialTab;
|
||||
@@ -59,7 +60,8 @@ class TimeTrackingPanel extends PluginPanel
|
||||
@Nullable
|
||||
private TabContentPanel activeTabPanel = null;
|
||||
|
||||
TimeTrackingPanel(ItemManager itemManager, TimeTrackingConfig config, FarmingTracker farmingTracker)
|
||||
TimeTrackingPanel(ItemManager itemManager, TimeTrackingConfig config,
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker)
|
||||
{
|
||||
super(false);
|
||||
|
||||
@@ -77,6 +79,8 @@ class TimeTrackingPanel extends PluginPanel
|
||||
add(tabGroup, BorderLayout.NORTH);
|
||||
add(display, BorderLayout.CENTER);
|
||||
|
||||
addTab(Tab.BIRD_HOUSE, birdHouseTracker.createBirdHouseTabPanel());
|
||||
|
||||
for (Tab tab : Tab.FARMING_TABS)
|
||||
{
|
||||
addTab(tab, farmingTracker.createTabPanel(tab));
|
||||
|
||||
@@ -37,11 +37,14 @@ import net.runelite.api.GameState;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.UsernameChanged;
|
||||
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.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
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.NavigationButton;
|
||||
import net.runelite.client.ui.ClientToolbar;
|
||||
@@ -49,8 +52,8 @@ import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Time Tracking",
|
||||
description = "Enable the Time Tracking panel, which contains farming trackers",
|
||||
tags = {"farming", "skilling", "panel"}
|
||||
description = "Enable the Time Tracking panel, which contains farming and bird house trackers",
|
||||
tags = {"birdhouse", "farming", "hunter", "notifications", "skilling", "panel"}
|
||||
)
|
||||
@Slf4j
|
||||
public class TimeTrackingPlugin extends Plugin
|
||||
@@ -64,6 +67,9 @@ public class TimeTrackingPlugin extends Plugin
|
||||
@Inject
|
||||
private FarmingTracker farmingTracker;
|
||||
|
||||
@Inject
|
||||
private BirdHouseTracker birdHouseTracker;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@@ -75,6 +81,7 @@ public class TimeTrackingPlugin extends Plugin
|
||||
private NavigationButton navButton;
|
||||
|
||||
private WorldPoint lastTickLocation;
|
||||
private boolean lastTickPostLogin;
|
||||
|
||||
@Provides
|
||||
TimeTrackingConfig provideConfig(ConfigManager configManager)
|
||||
@@ -85,9 +92,11 @@ public class TimeTrackingPlugin extends Plugin
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
birdHouseTracker.loadFromConfig();
|
||||
|
||||
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "watch.png");
|
||||
|
||||
panel = new TimeTrackingPanel(itemManager, config, farmingTracker);
|
||||
panel = new TimeTrackingPanel(itemManager, config, farmingTracker, birdHouseTracker);
|
||||
|
||||
navButton = NavigationButton.builder()
|
||||
.tooltip("Time Tracking")
|
||||
@@ -105,6 +114,7 @@ public class TimeTrackingPlugin extends Plugin
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
lastTickLocation = null;
|
||||
lastTickPostLogin = false;
|
||||
clientToolbar.removeNavigation(navButton);
|
||||
}
|
||||
|
||||
@@ -117,17 +127,32 @@ public class TimeTrackingPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
// bird house data is only sent after exiting the post-login screen
|
||||
Widget motd = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY);
|
||||
if (motd != null && !motd.isHidden())
|
||||
{
|
||||
lastTickPostLogin = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTickPostLogin)
|
||||
{
|
||||
lastTickPostLogin = false;
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPoint loc = lastTickLocation;
|
||||
lastTickLocation = client.getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (loc == null || loc.getRegionID() != lastTickLocation.getRegionID())
|
||||
if (loc == null || loc.getPlane() != 0 || loc.getRegionID() != lastTickLocation.getRegionID())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boolean birdHouseDataChanged = birdHouseTracker.updateData(loc);
|
||||
boolean farmingDataChanged = farmingTracker.updateData(loc);
|
||||
|
||||
if (farmingDataChanged)
|
||||
if (birdHouseDataChanged || farmingDataChanged)
|
||||
{
|
||||
updatePanel();
|
||||
}
|
||||
@@ -137,9 +162,21 @@ public class TimeTrackingPlugin extends Plugin
|
||||
public void onUsernameChanged(UsernameChanged e)
|
||||
{
|
||||
farmingTracker.migrateConfiguration();
|
||||
birdHouseTracker.loadFromConfig();
|
||||
updatePanel();
|
||||
}
|
||||
|
||||
@Schedule(period = 10, unit = ChronoUnit.SECONDS)
|
||||
public void checkCompletion()
|
||||
{
|
||||
boolean birdHouseDataChanged = birdHouseTracker.checkCompletion();
|
||||
|
||||
if (birdHouseDataChanged)
|
||||
{
|
||||
updatePanel();
|
||||
}
|
||||
}
|
||||
|
||||
@Schedule(period = 10, unit = ChronoUnit.SECONDS)
|
||||
public void updatePanel()
|
||||
{
|
||||
|
||||
@@ -7,25 +7,24 @@
|
||||
* 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.
|
||||
* 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.
|
||||
* 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;
|
||||
package net.runelite.client.plugins.timetracking;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
@@ -40,16 +39,16 @@ import net.runelite.client.ui.components.ThinProgressBar;
|
||||
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
||||
|
||||
@Getter
|
||||
class FarmingPatchPanel extends JPanel
|
||||
public class TimeablePanel<T> extends JPanel
|
||||
{
|
||||
private final FarmingPatch patch;
|
||||
private final T timeable;
|
||||
private final JLabel icon = new JLabel();
|
||||
private final JLabel estimate = new JLabel();
|
||||
private final ThinProgressBar progress = new ThinProgressBar();
|
||||
|
||||
FarmingPatchPanel(FarmingPatch patch)
|
||||
public TimeablePanel(T timeable, String title, int maximumProgressValue)
|
||||
{
|
||||
this.patch = patch;
|
||||
this.timeable = timeable;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(7, 0, 0, 0));
|
||||
@@ -66,8 +65,7 @@ class FarmingPatchPanel extends JPanel
|
||||
infoPanel.setLayout(new GridLayout(2, 1));
|
||||
infoPanel.setBorder(new EmptyBorder(4, 4, 4, 0));
|
||||
|
||||
final JLabel location = new JShadowedLabel(patch.getRegion().getName()
|
||||
+ (Strings.isNullOrEmpty(patch.getName()) ? "" : " (" + patch.getName() + ")"));
|
||||
final JLabel location = new JShadowedLabel(title);
|
||||
location.setFont(FontManager.getRunescapeSmallFont());
|
||||
location.setForeground(Color.WHITE);
|
||||
|
||||
@@ -80,6 +78,9 @@ class FarmingPatchPanel extends JPanel
|
||||
topContainer.add(icon, BorderLayout.WEST);
|
||||
topContainer.add(infoPanel, BorderLayout.CENTER);
|
||||
|
||||
progress.setValue(0);
|
||||
progress.setMaximumValue(maximumProgressValue);
|
||||
|
||||
add(topContainer, BorderLayout.NORTH);
|
||||
add(progress, BorderLayout.SOUTH);
|
||||
}
|
||||
@@ -45,6 +45,7 @@ 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;
|
||||
import net.runelite.client.plugins.timetracking.TimeablePanel;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
|
||||
@@ -55,7 +56,7 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
private final ItemManager itemManager;
|
||||
private final ConfigManager configManager;
|
||||
private final TimeTrackingConfig config;
|
||||
private final List<FarmingPatchPanel> patchPanels;
|
||||
private final List<TimeablePanel<FarmingPatch>> patchPanels;
|
||||
|
||||
FarmingTabPanel(Client client, ItemManager itemManager, ConfigManager configManager,
|
||||
TimeTrackingConfig config, Set<FarmingPatch> patches)
|
||||
@@ -80,7 +81,8 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
boolean first = true;
|
||||
for (FarmingPatch patch : patches)
|
||||
{
|
||||
FarmingPatchPanel p = new FarmingPatchPanel(patch);
|
||||
String title = patch.getRegion().getName() + (Strings.isNullOrEmpty(patch.getName()) ? "" : " (" + patch.getName() + ")");
|
||||
TimeablePanel<FarmingPatch> p = new TimeablePanel<>(patch, title, 1);
|
||||
|
||||
/* Show labels to subdivide tabs into sections */
|
||||
if (patch.getImplementation() != lastImpl && !Strings.isNullOrEmpty(patch.getImplementation().getName()))
|
||||
@@ -131,9 +133,9 @@ public class FarmingTabPanel extends TabContentPanel
|
||||
.equals(configManager.getConfiguration(group, TimeTrackingConfig.AUTOWEED));
|
||||
}
|
||||
|
||||
for (FarmingPatchPanel panel : patchPanels)
|
||||
for (TimeablePanel<FarmingPatch> panel : patchPanels)
|
||||
{
|
||||
FarmingPatch patch = panel.getPatch();
|
||||
FarmingPatch patch = panel.getTimeable();
|
||||
String group = TimeTrackingConfig.KEY_NAME + "." + client.getUsername() + "." + patch.getRegion().getRegionID();
|
||||
String key = Integer.toString(patch.getVarbit().getId());
|
||||
String storedValue = configManager.getConfiguration(group, key);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Daniel Teo <https://github.com/takuyakanbr>
|
||||
* 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.hunter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ItemID;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
enum BirdHouse
|
||||
{
|
||||
NORMAL("Bird House", ItemID.BIRD_HOUSE),
|
||||
OAK("Oak Bird House", ItemID.OAK_BIRD_HOUSE),
|
||||
WILLOW("Willow Bird House", ItemID.WILLOW_BIRD_HOUSE),
|
||||
TEAK("Teak Bird House", ItemID.TEAK_BIRD_HOUSE),
|
||||
MAPLE("Maple Bird House", ItemID.MAPLE_BIRD_HOUSE),
|
||||
MAHOGANY("Mahogany Bird House", ItemID.MAHOGANY_BIRD_HOUSE),
|
||||
YEW("Yew Bird House", ItemID.YEW_BIRD_HOUSE),
|
||||
MAGIC("Magic Bird House", ItemID.MAGIC_BIRD_HOUSE),
|
||||
REDWOOD("Redwood Bird House", ItemID.REDWOOD_BIRD_HOUSE);
|
||||
|
||||
private final String name;
|
||||
private final int itemID;
|
||||
|
||||
/**
|
||||
* Gets the {@code BirdHouse} corresponding to the given {@code VarPlayer} value.
|
||||
*/
|
||||
@Nullable
|
||||
static BirdHouse fromVarpValue(int varp)
|
||||
{
|
||||
int index = (varp - 1) / 3;
|
||||
|
||||
if (varp <= 0 || index >= values().length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return values()[index];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Daniel Teo <https://github.com/takuyakanbr>
|
||||
* 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.hunter;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
/**
|
||||
* Contains data about the state of a particular {@link BirdHouseSpace}, at a particular point in time.
|
||||
*/
|
||||
@Value
|
||||
class BirdHouseData
|
||||
{
|
||||
private BirdHouseSpace space;
|
||||
private int varp;
|
||||
private long timestamp;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Daniel Teo <https://github.com/takuyakanbr>
|
||||
* 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.hunter;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.VarPlayer;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
enum BirdHouseSpace
|
||||
{
|
||||
MEADOW_NORTH("Mushroom Meadow (North)", VarPlayer.BIRD_HOUSE_MEADOW_NORTH),
|
||||
MEADOW_SOUTH("Mushroom Meadow (South)", VarPlayer.BIRD_HOUSE_MEADOW_SOUTH),
|
||||
VALLEY_NORTH("Verdant Valley (Northeast)", VarPlayer.BIRD_HOUSE_VALLEY_NORTH),
|
||||
VALLEY_SOUTH("Verdant Valley (Southwest)", VarPlayer.BIRD_HOUSE_VALLEY_SOUTH);
|
||||
|
||||
private final String name;
|
||||
private final VarPlayer varp;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Daniel Teo <https://github.com/takuyakanbr>
|
||||
* 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.hunter;
|
||||
|
||||
import java.awt.Color;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
enum BirdHouseState
|
||||
{
|
||||
SEEDED(ColorScheme.PROGRESS_COMPLETE_COLOR),
|
||||
BUILT(ColorScheme.PROGRESS_INPROGRESS_COLOR),
|
||||
EMPTY(ColorScheme.MEDIUM_GRAY_COLOR),
|
||||
UNKNOWN(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
|
||||
private final Color color;
|
||||
|
||||
/**
|
||||
* Gets the {@code BirdHouseState} corresponding to the given {@code VarPlayer} value.
|
||||
*/
|
||||
static BirdHouseState fromVarpValue(int varp)
|
||||
{
|
||||
if (varp < 0 || varp > BirdHouse.values().length * 3)
|
||||
{
|
||||
return UNKNOWN;
|
||||
}
|
||||
else if (varp == 0)
|
||||
{
|
||||
return EMPTY;
|
||||
}
|
||||
else if (varp % 3 == 0)
|
||||
{
|
||||
return SEEDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BUILT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||
* Copyright (c) 2018, Daniel Teo <https://github.com/takuyakanbr>
|
||||
* 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.hunter;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.TextStyle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
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;
|
||||
import net.runelite.client.plugins.timetracking.TimeablePanel;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.DynamicGridLayout;
|
||||
|
||||
public class BirdHouseTabPanel extends TabContentPanel
|
||||
{
|
||||
private static final Color COMPLETED_COLOR = ColorScheme.PROGRESS_COMPLETE_COLOR.darker();
|
||||
|
||||
private final ItemManager itemManager;
|
||||
private final BirdHouseTracker birdHouseTracker;
|
||||
private final TimeTrackingConfig config;
|
||||
private final List<TimeablePanel<BirdHouseSpace>> spacePanels;
|
||||
|
||||
BirdHouseTabPanel(ItemManager itemManager, BirdHouseTracker birdHouseTracker, TimeTrackingConfig config)
|
||||
{
|
||||
this.itemManager = itemManager;
|
||||
this.birdHouseTracker = birdHouseTracker;
|
||||
this.config = config;
|
||||
this.spacePanels = new ArrayList<>();
|
||||
|
||||
setLayout(new DynamicGridLayout(0, 1, 0, 0));
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
boolean first = true;
|
||||
for (BirdHouseSpace space : BirdHouseSpace.values())
|
||||
{
|
||||
TimeablePanel<BirdHouseSpace> panel = new TimeablePanel<>(space, space.getName(), BirdHouseTracker.BIRD_HOUSE_DURATION);
|
||||
|
||||
spacePanels.add(panel);
|
||||
add(panel);
|
||||
|
||||
// remove the top border on the first panel
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
panel.setBorder(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
long unixNow = Instant.now().getEpochSecond();
|
||||
|
||||
for (TimeablePanel<BirdHouseSpace> panel : spacePanels)
|
||||
{
|
||||
BirdHouseSpace space = panel.getTimeable();
|
||||
BirdHouseData data = birdHouseTracker.getBirdHouseData().get(space);
|
||||
int value = -1;
|
||||
long startTime = 0;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
value = data.getVarp();
|
||||
startTime = data.getTimestamp();
|
||||
}
|
||||
|
||||
BirdHouse birdHouse = BirdHouse.fromVarpValue(value);
|
||||
BirdHouseState state = BirdHouseState.fromVarpValue(value);
|
||||
|
||||
if (birdHouse == null)
|
||||
{
|
||||
itemManager.getImage(ItemID.FEATHER).addTo(panel.getIcon());
|
||||
panel.getProgress().setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemManager.getImage(birdHouse.getItemID()).addTo(panel.getIcon());
|
||||
panel.getIcon().setToolTipText(birdHouse.getName());
|
||||
panel.getProgress().setVisible(true);
|
||||
}
|
||||
|
||||
panel.getProgress().setForeground(state.getColor().darker());
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case EMPTY:
|
||||
panel.getIcon().setToolTipText("Empty");
|
||||
panel.getEstimate().setText("Empty");
|
||||
break;
|
||||
case BUILT:
|
||||
panel.getProgress().setValue(0);
|
||||
panel.getEstimate().setText("Built");
|
||||
break;
|
||||
case SEEDED:
|
||||
long doneEstimate = startTime + BirdHouseTracker.BIRD_HOUSE_DURATION;
|
||||
if (doneEstimate < unixNow)
|
||||
{
|
||||
panel.getProgress().setValue(BirdHouseTracker.BIRD_HOUSE_DURATION);
|
||||
panel.getProgress().setForeground(COMPLETED_COLOR);
|
||||
panel.getEstimate().setText("Done");
|
||||
}
|
||||
else if (config.estimateRelative())
|
||||
{
|
||||
int remainingSeconds = (int) (59 + doneEstimate - unixNow);
|
||||
int remaining = remainingSeconds / 60;
|
||||
panel.getProgress().setValue(BirdHouseTracker.BIRD_HOUSE_DURATION - remainingSeconds);
|
||||
StringBuilder f = new StringBuilder("Done in ");
|
||||
int min = remaining % 60;
|
||||
int hours = (remaining / 60) % 24;
|
||||
int days = remaining / (60 * 24);
|
||||
if (days > 0)
|
||||
{
|
||||
f.append(days).append("d ");
|
||||
}
|
||||
if (hours > 0)
|
||||
{
|
||||
f.append(hours).append("h ");
|
||||
}
|
||||
if (min > 0)
|
||||
{
|
||||
f.append(min).append("m ");
|
||||
}
|
||||
panel.getEstimate().setText(f.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder f = new StringBuilder();
|
||||
LocalDateTime ldtTime = LocalDateTime.ofEpochSecond(doneEstimate, 0, OffsetDateTime.now().getOffset());
|
||||
LocalDateTime ldtNow = LocalDateTime.now();
|
||||
f.append("Done ");
|
||||
if (ldtTime.getDayOfWeek() != ldtNow.getDayOfWeek())
|
||||
{
|
||||
f.append(ldtTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault())).append(" ");
|
||||
}
|
||||
f.append(String.format("at %d:%02d", ldtTime.getHour(), ldtTime.getMinute()));
|
||||
panel.getEstimate().setText(f.toString());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panel.getIcon().setToolTipText("Unknown state");
|
||||
panel.getEstimate().setText("Unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
panel.getProgress().update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* Copyright (c) 2018, Daniel Teo <https://github.com/takuyakanbr>
|
||||
* 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.hunter;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.TimeTrackingConfig;
|
||||
|
||||
@Singleton
|
||||
public class BirdHouseTracker
|
||||
{
|
||||
// average time taken to harvest 10 birds, in seconds
|
||||
static final int BIRD_HOUSE_DURATION = (int) Duration.ofMinutes(50).getSeconds();
|
||||
|
||||
private static ImmutableSet<Integer> FOSSIL_ISLAND_REGIONS = ImmutableSet.of(14650, 14651, 14652, 14906, 14907, 15162, 15163);
|
||||
|
||||
private final Client client;
|
||||
private final ItemManager itemManager;
|
||||
private final ConfigManager configManager;
|
||||
private final TimeTrackingConfig config;
|
||||
private final Notifier notifier;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final ConcurrentMap<BirdHouseSpace, BirdHouseData> birdHouseData = new ConcurrentHashMap<>();
|
||||
|
||||
@Inject
|
||||
private BirdHouseTracker(Client client, ItemManager itemManager, ConfigManager configManager,
|
||||
TimeTrackingConfig config, Notifier notifier)
|
||||
{
|
||||
this.client = client;
|
||||
this.itemManager = itemManager;
|
||||
this.configManager = configManager;
|
||||
this.config = config;
|
||||
this.notifier = notifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* The time at which all the bird houses will be ready to be dismantled,
|
||||
* or {@code -1} if we have no data about any of the bird house spaces.
|
||||
*
|
||||
* This is set to {@code 0} if the bird houses have already completed
|
||||
* when updating it.
|
||||
*/
|
||||
private long completionTime = -1;
|
||||
|
||||
public BirdHouseTabPanel createBirdHouseTabPanel()
|
||||
{
|
||||
return new BirdHouseTabPanel(itemManager, this, config);
|
||||
}
|
||||
|
||||
public void loadFromConfig()
|
||||
{
|
||||
birdHouseData.clear();
|
||||
|
||||
final String group = TimeTrackingConfig.KEY_NAME + "." + client.getUsername() + "." + TimeTrackingConfig.BIRD_HOUSE;
|
||||
|
||||
for (BirdHouseSpace space : BirdHouseSpace.values())
|
||||
{
|
||||
String key = Integer.toString(space.getVarp().getId());
|
||||
String storedValue = configManager.getConfiguration(group, key);
|
||||
|
||||
if (storedValue != null)
|
||||
{
|
||||
String[] parts = storedValue.split(":");
|
||||
if (parts.length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
int varp = Integer.parseInt(parts[0]);
|
||||
long timestamp = Long.parseLong(parts[1]);
|
||||
birdHouseData.put(space, new BirdHouseData(space, varp, timestamp));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateCompletionTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates tracker data if player is within range of any bird house. Returns true if any data was changed.
|
||||
*/
|
||||
public boolean updateData(WorldPoint location)
|
||||
{
|
||||
boolean changed = false;
|
||||
|
||||
if (FOSSIL_ISLAND_REGIONS.contains(location.getRegionID()))
|
||||
{
|
||||
final Map<BirdHouseSpace, BirdHouseData> newData = new HashMap<>();
|
||||
final long currentTime = Instant.now().getEpochSecond();
|
||||
int removalCount = 0;
|
||||
|
||||
for (BirdHouseSpace space : BirdHouseSpace.values())
|
||||
{
|
||||
int varp = client.getVar(space.getVarp());
|
||||
BirdHouseData oldData = birdHouseData.get(space);
|
||||
int oldVarp = oldData == null ? -1 : oldData.getVarp();
|
||||
|
||||
// update data if there isn't one, or if the varp doesn't match
|
||||
if (varp != oldVarp)
|
||||
{
|
||||
newData.put(space, new BirdHouseData(space, varp, currentTime));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (varp <= 0 && oldVarp > 0)
|
||||
{
|
||||
removalCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent the resetting of bird house data that could occur if the varps have not been updated yet
|
||||
// after the player enters the region. We assume that players would generally have 3 or 4 bird houses
|
||||
// built at any time, and that dropping from 3/4 to 0 built bird houses is not normally possible.
|
||||
if (removalCount > 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
birdHouseData.putAll(newData);
|
||||
updateCompletionTime();
|
||||
saveToConfig(newData);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the bird houses have become ready to be dismantled,
|
||||
* and sends a notification if required.
|
||||
*/
|
||||
public boolean checkCompletion()
|
||||
{
|
||||
if (completionTime > 0 && completionTime < Instant.now().getEpochSecond())
|
||||
{
|
||||
completionTime = 0;
|
||||
|
||||
if (config.birdHouseNotification())
|
||||
{
|
||||
notifier.notify("Your bird houses are ready to be dismantled.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the overall completion time of the bird houses.
|
||||
* @see #completionTime
|
||||
*/
|
||||
private void updateCompletionTime()
|
||||
{
|
||||
if (birdHouseData.isEmpty())
|
||||
{
|
||||
completionTime = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
long maxCompletionTime = 0;
|
||||
for (BirdHouseData data : birdHouseData.values())
|
||||
{
|
||||
if (BirdHouseState.fromVarpValue(data.getVarp()) == BirdHouseState.SEEDED)
|
||||
{
|
||||
maxCompletionTime = Math.max(maxCompletionTime, data.getTimestamp() + BIRD_HOUSE_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
completionTime = (maxCompletionTime <= Instant.now().getEpochSecond()) ? 0 : maxCompletionTime;
|
||||
}
|
||||
|
||||
private void saveToConfig(Map<BirdHouseSpace, BirdHouseData> updatedData)
|
||||
{
|
||||
final String group = TimeTrackingConfig.KEY_NAME + "." + client.getUsername() + "." + TimeTrackingConfig.BIRD_HOUSE;
|
||||
|
||||
for (BirdHouseData data : updatedData.values())
|
||||
{
|
||||
String key = Integer.toString(data.getSpace().getVarp().getId());
|
||||
configManager.setConfiguration(group, key, data.getVarp() + ":" + data.getTimestamp());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user