Merge pull request #5775 from Abextm/timetracking-overview

timetracking: Show overview completion by tab, not implementation
This commit is contained in:
Tomas Slusny
2018-10-05 10:26:54 +02:00
committed by GitHub
3 changed files with 101 additions and 103 deletions

View File

@@ -24,15 +24,16 @@
*/ */
package net.runelite.client.plugins.timetracking; package net.runelite.client.plugins.timetracking;
import com.google.common.collect.ImmutableMap;
import java.awt.Color; import java.awt.Color;
import java.awt.GridLayout; import java.awt.GridLayout;
import java.time.Instant; import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.timetracking.clocks.ClockManager; import net.runelite.client.plugins.timetracking.clocks.ClockManager;
import net.runelite.client.plugins.timetracking.farming.FarmingTracker; import net.runelite.client.plugins.timetracking.farming.FarmingTracker;
import net.runelite.client.plugins.timetracking.farming.PatchImplementation;
import net.runelite.client.plugins.timetracking.hunter.BirdHouseTracker; import net.runelite.client.plugins.timetracking.hunter.BirdHouseTracker;
import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.ColorScheme;
@@ -45,7 +46,7 @@ class OverviewTabPanel extends TabContentPanel
private final OverviewItemPanel timerOverview; private final OverviewItemPanel timerOverview;
private final OverviewItemPanel stopwatchOverview; private final OverviewItemPanel stopwatchOverview;
private final Map<PatchImplementation, OverviewItemPanel> farmingOverviews; private final Map<Tab, OverviewItemPanel> farmingOverviews;
private final OverviewItemPanel birdHouseOverview; private final OverviewItemPanel birdHouseOverview;
OverviewTabPanel(ItemManager itemManager, TimeTrackingConfig config, TimeTrackingPanel pluginPanel, OverviewTabPanel(ItemManager itemManager, TimeTrackingConfig config, TimeTrackingPanel pluginPanel,
@@ -68,21 +69,17 @@ class OverviewTabPanel extends TabContentPanel
birdHouseOverview = new OverviewItemPanel(itemManager, pluginPanel, Tab.BIRD_HOUSE, "Bird Houses"); birdHouseOverview = new OverviewItemPanel(itemManager, pluginPanel, Tab.BIRD_HOUSE, "Bird Houses");
add(birdHouseOverview); add(birdHouseOverview);
farmingOverviews = new LinkedHashMap<>(); farmingOverviews = Stream.of(Tab.FARMING_TABS)
farmingOverviews.put(PatchImplementation.HERB, new OverviewItemPanel(itemManager, pluginPanel, Tab.HERB, "Herb Patches")); .filter(v -> v != Tab.OVERVIEW)
farmingOverviews.put(PatchImplementation.TREE, new OverviewItemPanel(itemManager, pluginPanel, Tab.TREE, "Tree Patches")); .collect(ImmutableMap.toImmutableMap(
farmingOverviews.put(PatchImplementation.FRUIT_TREE, new OverviewItemPanel(itemManager, pluginPanel, Tab.FRUIT_TREE, "Fruit Tree Patches")); Function.identity(),
farmingOverviews.put(PatchImplementation.SEAWEED, new OverviewItemPanel(itemManager, pluginPanel, Tab.SPECIAL, "Special Patches")); t ->
farmingOverviews.put(PatchImplementation.FLOWER, new OverviewItemPanel(itemManager, pluginPanel, Tab.FLOWER, "Flower Patches")); {
farmingOverviews.put(PatchImplementation.ALLOTMENT, new OverviewItemPanel(itemManager, pluginPanel, Tab.ALLOTMENT, "Allotment Patches")); OverviewItemPanel p = new OverviewItemPanel(itemManager, pluginPanel, t, t.getName() + " Patches");
farmingOverviews.put(PatchImplementation.BUSH, new OverviewItemPanel(itemManager, pluginPanel, Tab.BUSH, "Bush Patches")); add(p);
farmingOverviews.put(PatchImplementation.GRAPES, new OverviewItemPanel(itemManager, pluginPanel, Tab.GRAPE, "Grape Patches")); return p;
farmingOverviews.put(PatchImplementation.HOPS, new OverviewItemPanel(itemManager, pluginPanel, Tab.HOPS, "Hops Patches")); }
));
for (OverviewItemPanel panel : farmingOverviews.values())
{
add(panel);
}
} }
@Override @Override

View File

@@ -29,6 +29,7 @@ import com.google.inject.Singleton;
import java.time.Instant; import java.time.Instant;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@@ -50,13 +51,13 @@ public class FarmingTracker
private final TimeTrackingConfig config; private final TimeTrackingConfig config;
private final FarmingWorld farmingWorld; private final FarmingWorld farmingWorld;
private final Map<PatchImplementation, SummaryState> summaries = new EnumMap<>(PatchImplementation.class); private final Map<Tab, SummaryState> summaries = new EnumMap<>(Tab.class);
/** /**
* The time at which all patches of a particular type will be ready to be harvested, * The time at which all patches of a particular type will be ready to be harvested,
* or {@code -1} if we have no data about any patch of the given type. * or {@code -1} if we have no data about any patch of the given type.
*/ */
private final Map<PatchImplementation, Long> completionTimes = new EnumMap<>(PatchImplementation.class); private final Map<Tab, Long> completionTimes = new EnumMap<>(Tab.class);
@Inject @Inject
private FarmingTracker(Client client, ItemManager itemManager, ConfigManager configManager, private FarmingTracker(Client client, ItemManager itemManager, ConfigManager configManager,
@@ -130,11 +131,15 @@ public class FarmingTracker
String value = strVarbit + ":" + unixNow; String value = strVarbit + ":" + unixNow;
configManager.setConfiguration(group, key, value); configManager.setConfiguration(group, key, value);
updateCompletionTime(patch.getImplementation());
changed = true; changed = true;
} }
} }
if (changed)
{
updateCompletionTime();
}
return changed; return changed;
} }
@@ -142,14 +147,10 @@ public class FarmingTracker
{ {
summaries.clear(); summaries.clear();
completionTimes.clear(); completionTimes.clear();
updateCompletionTime();
for (PatchImplementation patchType : PatchImplementation.values())
{
updateCompletionTime(patchType);
}
} }
public SummaryState getSummary(PatchImplementation patchType) public SummaryState getSummary(Tab patchType)
{ {
SummaryState summary = summaries.get(patchType); SummaryState summary = summaries.get(patchType);
return summary == null ? SummaryState.UNKNOWN : summary; return summary == null ? SummaryState.UNKNOWN : summary;
@@ -157,9 +158,10 @@ public class FarmingTracker
/** /**
* Gets the overall completion time for the given patch type. * Gets the overall completion time for the given patch type.
*
* @see #completionTimes * @see #completionTimes
*/ */
public long getCompletionTime(PatchImplementation patchType) public long getCompletionTime(Tab patchType)
{ {
Long completionTime = completionTimes.get(patchType); Long completionTime = completionTimes.get(patchType);
return completionTime == null ? -1 : completionTime; return completionTime == null ? -1 : completionTime;
@@ -167,88 +169,97 @@ public class FarmingTracker
/** /**
* Updates the overall completion time for the given patch type. * Updates the overall completion time for the given patch type.
*
* @see #completionTimes * @see #completionTimes
*/ */
private void updateCompletionTime(PatchImplementation patchType) private void updateCompletionTime()
{ {
long maxCompletionTime = 0; for (Map.Entry<Tab, Set<FarmingPatch>> tab : farmingWorld.getTabs().entrySet())
boolean allUnknown = true;
boolean allEmpty = true;
for (FarmingPatch patch : farmingWorld.getPatchTypes().get(patchType))
{ {
String group = TimeTrackingConfig.CONFIG_GROUP + "." + client.getUsername() + "." + patch.getRegion().getRegionID(); long maxCompletionTime = 0;
String key = Integer.toString(patch.getVarbit().getId()); boolean allUnknown = true;
String storedValue = configManager.getConfiguration(group, key); boolean allEmpty = true;
long unixTime = 0;
int value = 0;
if (storedValue != null) for (FarmingPatch patch : tab.getValue())
{ {
String[] parts = storedValue.split(":"); String group = TimeTrackingConfig.CONFIG_GROUP + "." + client.getUsername() + "." + patch.getRegion().getRegionID();
if (parts.length == 2) String key = Integer.toString(patch.getVarbit().getId());
String storedValue = configManager.getConfiguration(group, key);
long unixTime = 0;
int value = 0;
if (storedValue != null)
{ {
try String[] parts = storedValue.split(":");
if (parts.length == 2)
{ {
value = Integer.parseInt(parts[0]); try
unixTime = Long.parseLong(parts[1]); {
} value = Integer.parseInt(parts[0]);
catch (NumberFormatException e) unixTime = Long.parseLong(parts[1]);
{ }
// ignored catch (NumberFormatException e)
{
// ignored
}
} }
} }
}
PatchState state = unixTime <= 0 ? null : patch.getImplementation().forVarbitValue(value); PatchState state = unixTime <= 0 ? null : patch.getImplementation().forVarbitValue(value);
if (state == null || state.getProduce().getItemID() < 0) if (state == null || state.getProduce().getItemID() < 0)
{
continue; // unknown state
}
int tickrate = state.getTickRate() * 60;
int stage = state.getStage();
int stages = state.getStages();
if (state.getProduce() != Produce.WEEDS && state.getProduce() != Produce.SCARECROW)
{
allEmpty = false;
// update max duration if this patch takes longer to grow
if (tickrate > 0)
{
long tickTime = unixTime / tickrate;
long doneEstimate = ((stages - 1 - stage) + tickTime) * tickrate;
maxCompletionTime = Math.max(maxCompletionTime, doneEstimate);
}
else if (state.getCropState() == CropState.GROWING && stage != stages - 1)
{ {
continue; // unknown state continue; // unknown state
} }
int tickrate = state.getTickRate() * 60;
int stage = state.getStage();
int stages = state.getStages();
if (state.getProduce() != Produce.WEEDS && state.getProduce() != Produce.SCARECROW)
{
allEmpty = false;
// update max duration if this patch takes longer to grow
if (tickrate > 0)
{
long tickTime = unixTime / tickrate;
long doneEstimate = ((stages - 1 - stage) + tickTime) * tickrate;
maxCompletionTime = Math.max(maxCompletionTime, doneEstimate);
}
else if (state.getCropState() == CropState.GROWING && stage != stages - 1)
{
continue; // unknown state
}
}
allUnknown = false;
} }
allUnknown = false; final SummaryState state;
} final long completionTime;
if (allUnknown) if (allUnknown)
{ {
summaries.put(patchType, SummaryState.UNKNOWN); state = SummaryState.UNKNOWN;
completionTimes.put(patchType, -1L); completionTime = -1L;
} }
else if (allEmpty) else if (allEmpty)
{ {
summaries.put(patchType, SummaryState.EMPTY); state = SummaryState.EMPTY;
completionTimes.put(patchType, -1L); completionTime = -1L;
} }
else if (maxCompletionTime <= Instant.now().getEpochSecond()) else if (maxCompletionTime <= Instant.now().getEpochSecond())
{ {
summaries.put(patchType, SummaryState.COMPLETED); state = SummaryState.COMPLETED;
completionTimes.put(patchType, 0L); completionTime = 0;
} }
else else
{ {
summaries.put(patchType, SummaryState.IN_PROGRESS); state = SummaryState.IN_PROGRESS;
completionTimes.put(patchType, maxCompletionTime); completionTime = maxCompletionTime;
}
summaries.put(tab.getKey(), state);
completionTimes.put(tab.getKey(), completionTime);
} }
} }

View File

@@ -26,12 +26,9 @@
package net.runelite.client.plugins.timetracking.farming; package net.runelite.client.plugins.timetracking.farming;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
@@ -50,9 +47,6 @@ class FarmingWorld
@Getter @Getter
private Map<Tab, Set<FarmingPatch>> tabs = new HashMap<>(); private Map<Tab, Set<FarmingPatch>> tabs = new HashMap<>();
@Getter
private Map<PatchImplementation, List<FarmingPatch>> patchTypes = new EnumMap<>(PatchImplementation.class);
private final Comparator<FarmingPatch> tabSorter = Comparator private final Comparator<FarmingPatch> tabSorter = Comparator
.comparing(FarmingPatch::getImplementation) .comparing(FarmingPatch::getImplementation)
.thenComparing((FarmingPatch p) -> p.getRegion().getName()) .thenComparing((FarmingPatch p) -> p.getRegion().getName())
@@ -253,10 +247,6 @@ class FarmingWorld
tabs tabs
.computeIfAbsent(p.getImplementation().getTab(), k -> new TreeSet<>(tabSorter)) .computeIfAbsent(p.getImplementation().getTab(), k -> new TreeSet<>(tabSorter))
.add(p); .add(p);
patchTypes
.computeIfAbsent(p.getImplementation(), k -> new ArrayList<>())
.add(p);
} }
} }
} }