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;
|
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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user