Merge pull request #5775 from Abextm/timetracking-overview
timetracking: Show overview completion by tab, not implementation
This commit is contained in:
@@ -24,15 +24,16 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.timetracking;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.awt.Color;
|
||||
import java.awt.GridLayout;
|
||||
import java.time.Instant;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.clocks.ClockManager;
|
||||
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.ui.ColorScheme;
|
||||
|
||||
@@ -45,7 +46,7 @@ class OverviewTabPanel extends TabContentPanel
|
||||
|
||||
private final OverviewItemPanel timerOverview;
|
||||
private final OverviewItemPanel stopwatchOverview;
|
||||
private final Map<PatchImplementation, OverviewItemPanel> farmingOverviews;
|
||||
private final Map<Tab, OverviewItemPanel> farmingOverviews;
|
||||
private final OverviewItemPanel birdHouseOverview;
|
||||
|
||||
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");
|
||||
add(birdHouseOverview);
|
||||
|
||||
farmingOverviews = new LinkedHashMap<>();
|
||||
farmingOverviews.put(PatchImplementation.HERB, new OverviewItemPanel(itemManager, pluginPanel, Tab.HERB, "Herb Patches"));
|
||||
farmingOverviews.put(PatchImplementation.TREE, new OverviewItemPanel(itemManager, pluginPanel, Tab.TREE, "Tree Patches"));
|
||||
farmingOverviews.put(PatchImplementation.FRUIT_TREE, new OverviewItemPanel(itemManager, pluginPanel, Tab.FRUIT_TREE, "Fruit Tree Patches"));
|
||||
farmingOverviews.put(PatchImplementation.SEAWEED, new OverviewItemPanel(itemManager, pluginPanel, Tab.SPECIAL, "Special Patches"));
|
||||
farmingOverviews.put(PatchImplementation.FLOWER, new OverviewItemPanel(itemManager, pluginPanel, Tab.FLOWER, "Flower Patches"));
|
||||
farmingOverviews.put(PatchImplementation.ALLOTMENT, new OverviewItemPanel(itemManager, pluginPanel, Tab.ALLOTMENT, "Allotment Patches"));
|
||||
farmingOverviews.put(PatchImplementation.BUSH, new OverviewItemPanel(itemManager, pluginPanel, Tab.BUSH, "Bush Patches"));
|
||||
farmingOverviews.put(PatchImplementation.GRAPES, new OverviewItemPanel(itemManager, pluginPanel, Tab.GRAPE, "Grape Patches"));
|
||||
farmingOverviews.put(PatchImplementation.HOPS, new OverviewItemPanel(itemManager, pluginPanel, Tab.HOPS, "Hops Patches"));
|
||||
|
||||
for (OverviewItemPanel panel : farmingOverviews.values())
|
||||
{
|
||||
add(panel);
|
||||
}
|
||||
farmingOverviews = Stream.of(Tab.FARMING_TABS)
|
||||
.filter(v -> v != Tab.OVERVIEW)
|
||||
.collect(ImmutableMap.toImmutableMap(
|
||||
Function.identity(),
|
||||
t ->
|
||||
{
|
||||
OverviewItemPanel p = new OverviewItemPanel(itemManager, pluginPanel, t, t.getName() + " Patches");
|
||||
add(p);
|
||||
return p;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.google.inject.Singleton;
|
||||
import java.time.Instant;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
@@ -50,13 +51,13 @@ public class FarmingTracker
|
||||
private final TimeTrackingConfig config;
|
||||
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,
|
||||
* 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
|
||||
private FarmingTracker(Client client, ItemManager itemManager, ConfigManager configManager,
|
||||
@@ -130,11 +131,15 @@ public class FarmingTracker
|
||||
|
||||
String value = strVarbit + ":" + unixNow;
|
||||
configManager.setConfiguration(group, key, value);
|
||||
updateCompletionTime(patch.getImplementation());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
updateCompletionTime();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -142,14 +147,10 @@ public class FarmingTracker
|
||||
{
|
||||
summaries.clear();
|
||||
completionTimes.clear();
|
||||
|
||||
for (PatchImplementation patchType : PatchImplementation.values())
|
||||
{
|
||||
updateCompletionTime(patchType);
|
||||
}
|
||||
updateCompletionTime();
|
||||
}
|
||||
|
||||
public SummaryState getSummary(PatchImplementation patchType)
|
||||
public SummaryState getSummary(Tab patchType)
|
||||
{
|
||||
SummaryState summary = summaries.get(patchType);
|
||||
return summary == null ? SummaryState.UNKNOWN : summary;
|
||||
@@ -157,9 +158,10 @@ public class FarmingTracker
|
||||
|
||||
/**
|
||||
* Gets the overall completion time for the given patch type.
|
||||
*
|
||||
* @see #completionTimes
|
||||
*/
|
||||
public long getCompletionTime(PatchImplementation patchType)
|
||||
public long getCompletionTime(Tab patchType)
|
||||
{
|
||||
Long completionTime = completionTimes.get(patchType);
|
||||
return completionTime == null ? -1 : completionTime;
|
||||
@@ -167,88 +169,97 @@ public class FarmingTracker
|
||||
|
||||
/**
|
||||
* Updates the overall completion time for the given patch type.
|
||||
*
|
||||
* @see #completionTimes
|
||||
*/
|
||||
private void updateCompletionTime(PatchImplementation patchType)
|
||||
private void updateCompletionTime()
|
||||
{
|
||||
long maxCompletionTime = 0;
|
||||
boolean allUnknown = true;
|
||||
boolean allEmpty = true;
|
||||
|
||||
for (FarmingPatch patch : farmingWorld.getPatchTypes().get(patchType))
|
||||
for (Map.Entry<Tab, Set<FarmingPatch>> tab : farmingWorld.getTabs().entrySet())
|
||||
{
|
||||
String group = TimeTrackingConfig.CONFIG_GROUP + "." + client.getUsername() + "." + patch.getRegion().getRegionID();
|
||||
String key = Integer.toString(patch.getVarbit().getId());
|
||||
String storedValue = configManager.getConfiguration(group, key);
|
||||
long unixTime = 0;
|
||||
int value = 0;
|
||||
long maxCompletionTime = 0;
|
||||
boolean allUnknown = true;
|
||||
boolean allEmpty = true;
|
||||
|
||||
if (storedValue != null)
|
||||
for (FarmingPatch patch : tab.getValue())
|
||||
{
|
||||
String[] parts = storedValue.split(":");
|
||||
if (parts.length == 2)
|
||||
String group = TimeTrackingConfig.CONFIG_GROUP + "." + client.getUsername() + "." + patch.getRegion().getRegionID();
|
||||
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]);
|
||||
unixTime = Long.parseLong(parts[1]);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
// ignored
|
||||
try
|
||||
{
|
||||
value = Integer.parseInt(parts[0]);
|
||||
unixTime = Long.parseLong(parts[1]);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PatchState state = unixTime <= 0 ? null : patch.getImplementation().forVarbitValue(value);
|
||||
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)
|
||||
PatchState state = unixTime <= 0 ? null : patch.getImplementation().forVarbitValue(value);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
allUnknown = false;
|
||||
}
|
||||
|
||||
allUnknown = false;
|
||||
}
|
||||
final SummaryState state;
|
||||
final long completionTime;
|
||||
|
||||
if (allUnknown)
|
||||
{
|
||||
summaries.put(patchType, SummaryState.UNKNOWN);
|
||||
completionTimes.put(patchType, -1L);
|
||||
}
|
||||
else if (allEmpty)
|
||||
{
|
||||
summaries.put(patchType, SummaryState.EMPTY);
|
||||
completionTimes.put(patchType, -1L);
|
||||
}
|
||||
else if (maxCompletionTime <= Instant.now().getEpochSecond())
|
||||
{
|
||||
summaries.put(patchType, SummaryState.COMPLETED);
|
||||
completionTimes.put(patchType, 0L);
|
||||
}
|
||||
else
|
||||
{
|
||||
summaries.put(patchType, SummaryState.IN_PROGRESS);
|
||||
completionTimes.put(patchType, maxCompletionTime);
|
||||
if (allUnknown)
|
||||
{
|
||||
state = SummaryState.UNKNOWN;
|
||||
completionTime = -1L;
|
||||
}
|
||||
else if (allEmpty)
|
||||
{
|
||||
state = SummaryState.EMPTY;
|
||||
completionTime = -1L;
|
||||
}
|
||||
else if (maxCompletionTime <= Instant.now().getEpochSecond())
|
||||
{
|
||||
state = SummaryState.COMPLETED;
|
||||
completionTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = SummaryState.IN_PROGRESS;
|
||||
completionTime = maxCompletionTime;
|
||||
}
|
||||
summaries.put(tab.getKey(), state);
|
||||
completionTimes.put(tab.getKey(), completionTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,9 @@
|
||||
package net.runelite.client.plugins.timetracking.farming;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
@@ -50,9 +47,6 @@ class FarmingWorld
|
||||
@Getter
|
||||
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
|
||||
.comparing(FarmingPatch::getImplementation)
|
||||
.thenComparing((FarmingPatch p) -> p.getRegion().getName())
|
||||
@@ -253,10 +247,6 @@ class FarmingWorld
|
||||
tabs
|
||||
.computeIfAbsent(p.getImplementation().getTab(), k -> new TreeSet<>(tabSorter))
|
||||
.add(p);
|
||||
|
||||
patchTypes
|
||||
.computeIfAbsent(p.getImplementation(), k -> new ArrayList<>())
|
||||
.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user