Add a configurable minimum venture count, under which only quick ventures are assigned

This commit is contained in:
Liza 2023-10-19 01:22:25 +02:00
parent 65af6814df
commit 8b11b67c96
Signed by: liza
GPG Key ID: 7199F8D727D55F67
6 changed files with 154 additions and 107 deletions

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<Version>2.4</Version> <Version>2.5</Version>
<LangVersion>11.0</LangVersion> <LangVersion>11.0</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -16,7 +16,7 @@
<PropertyGroup> <PropertyGroup>
<DalamudLibPath>$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath> <DalamudLibPath>$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
<AutoRetainerLibPath>$(appdata)\XIVLauncher\installedPlugins\AutoRetainer\4.2.1.1\</AutoRetainerLibPath> <AutoRetainerLibPath>$(appdata)\XIVLauncher\installedPlugins\AutoRetainer\4.2.1.2\</AutoRetainerLibPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'"> <PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">

View File

@ -4,5 +4,5 @@
"Punchline": "Better AutoRetainer Venture Planner", "Punchline": "Better AutoRetainer Venture Planner",
"Description": "", "Description": "",
"RepoUrl": "https://git.carvel.li/liza/ARControl", "RepoUrl": "https://git.carvel.li/liza/ARControl",
"IconUrl": "https://git.carvel.li/liza/plugin-repo/raw/branch/master/dist/ARControl.png" "IconUrl": "https://plugins.carvel.li/icons/ARControl.png"
} }

View File

@ -38,6 +38,12 @@ partial class AutoRetainerControlPlugin
save = true; save = true;
} }
if (character.Ventures != offlineCharacterData.Ventures)
{
character.Ventures = offlineCharacterData.Ventures;
save = true;
}
List<string> seenRetainers = new(); List<string> seenRetainers = new();
foreach (var retainerData in offlineCharacterData.RetainerData) foreach (var retainerData in offlineCharacterData.RetainerData)
{ {

View File

@ -112,127 +112,141 @@ public sealed partial class AutoRetainerControlPlugin : IDalamudPlugin
_pluginLog.Information("Checking tasks..."); _pluginLog.Information("Checking tasks...");
Sync(); Sync();
var venturesInProgress = CalculateVenturesInProgress(ch);
foreach (var inpr in venturesInProgress)
{
_pluginLog.Verbose($"Venture In Progress: ItemId {inpr.Key} for a total amount of {inpr.Value}");
}
IReadOnlyList<Guid> itemListIds; if (ch.Ventures == 0)
if (ch.Type == Configuration.CharacterType.Standalone) {
itemListIds = ch.ItemListIds; _pluginLog.Warning("Could not assign a next venture from venture list, as the character has no ventures left.");
}
else if (ch.Ventures <= _configuration.Misc.VenturesToKeep)
{
_pluginLog.Warning($"Could not assign a next venture from venture list, character only has {ch.Ventures} left, configuration says to only send out above {_configuration.Misc.VenturesToKeep} ventures.");
}
else else
{ {
var group = _configuration.CharacterGroups.SingleOrDefault(x => x.Id == ch.CharacterGroupId); var venturesInProgress = CalculateVenturesInProgress(ch);
if (group == null) foreach (var inProgress in venturesInProgress)
{ {
_pluginLog.Error($"Unable to resolve character group {ch.CharacterGroupId}."); _pluginLog.Verbose(
return null; $"Venture In Progress: ItemId {inProgress.Key} for a total amount of {inProgress.Value}");
} }
itemListIds = group.ItemListIds; IReadOnlyList<Guid> itemListIds;
} if (ch.Type == Configuration.CharacterType.Standalone)
itemListIds = ch.ItemListIds;
var itemLists = itemListIds.Where(listId => listId != Guid.Empty)
.Select(listId => _configuration.ItemLists.SingleOrDefault(x => x.Id == listId))
.Where(list => list != null)
.Cast<Configuration.ItemList>()
.ToList();
InventoryManager* inventoryManager = InventoryManager.Instance();
foreach (var list in itemLists)
{
_pluginLog.Information($"Checking ventures in list '{list.Name}'");
IReadOnlyList<StockedItem> itemsOnList;
if (list.Type == Configuration.ListType.CollectOneTime)
{
itemsOnList = list.Items
.Select(x => new StockedItem
{
QueuedItem = x,
InventoryCount = 0,
})
.Where(x => x.RequestedCount > 0)
.ToList()
.AsReadOnly();
}
else else
{ {
itemsOnList = list.Items var group = _configuration.CharacterGroups.SingleOrDefault(x => x.Id == ch.CharacterGroupId);
.Select(x => new StockedItem if (group == null)
{ {
QueuedItem = x, _pluginLog.Error($"Unable to resolve character group {ch.CharacterGroupId}.");
InventoryCount = inventoryManager->GetInventoryItemCount(x.ItemId) + return null;
(venturesInProgress.TryGetValue(x.ItemId, out int inProgress) }
? inProgress
: 0),
})
.Where(x => x.InventoryCount <= x.RequestedCount)
.ToList()
.AsReadOnly();
// collect items with the least current inventory first itemListIds = group.ItemListIds;
if (list.Priority == Configuration.ListPriority.Balanced)
itemsOnList = itemsOnList.OrderBy(x => x.InventoryCount).ToList().AsReadOnly();
} }
_pluginLog.Debug($"Found {itemsOnList.Count} to-do items on current list"); var itemLists = itemListIds.Where(listId => listId != Guid.Empty)
if (itemsOnList.Count == 0) .Select(listId => _configuration.ItemLists.SingleOrDefault(x => x.Id == listId))
continue; .Where(list => list != null)
.Cast<Configuration.ItemList>()
foreach (var itemOnList in itemsOnList) .ToList();
InventoryManager* inventoryManager = InventoryManager.Instance();
foreach (var list in itemLists)
{ {
_pluginLog.Debug($"Checking venture info for itemId {itemOnList.ItemId}"); _pluginLog.Information($"Checking ventures in list '{list.Name}'");
IReadOnlyList<StockedItem> itemsOnList;
var (venture, reward) = _ventureResolver.ResolveVenture(ch, retainer, itemOnList.ItemId); if (list.Type == Configuration.ListType.CollectOneTime)
if (venture == null)
{ {
venture = _gameCache.Ventures.FirstOrDefault(x => x.ItemId == itemOnList.ItemId); itemsOnList = list.Items
_pluginLog.Debug($"Retainer doesn't know how to gather itemId {itemOnList.ItemId} ({venture?.Name})"); .Select(x => new StockedItem
} {
else if (reward == null) QueuedItem = x,
{ InventoryCount = 0,
_pluginLog.Debug($"Retainer can't complete venture '{venture.Name}'"); })
.Where(x => x.RequestedCount > 0)
.ToList()
.AsReadOnly();
} }
else else
{ {
_chatGui.Print( itemsOnList = list.Items
new SeString(new UIForegroundPayload(579)) .Select(x => new StockedItem
.Append(SeIconChar.Collectible.ToIconString())
.Append(new UIForegroundPayload(0))
.Append($" Sending retainer ")
.Append(new UIForegroundPayload(1))
.Append(retainerName)
.Append(new UIForegroundPayload(0))
.Append(" to collect ")
.Append(new UIForegroundPayload(1))
.Append($"{reward.Quantity}x ")
.Append(new ItemPayload(venture.ItemId))
.Append(venture.Name)
.Append(RawPayload.LinkTerminator)
.Append(new UIForegroundPayload(0))
.Append(" for ")
.Append(new UIForegroundPayload(1))
.Append($"{list.Name} {list.GetIcon()}")
.Append(new UIForegroundPayload(0))
.Append("."));
_pluginLog.Information(
$"Setting AR to use venture {venture.RowId}, which should retrieve {reward.Quantity}x {venture.Name}");
if (!dryRun)
{
retainer.HasVenture = true;
retainer.LastVenture = venture.RowId;
if (list.Type == Configuration.ListType.CollectOneTime)
{ {
itemOnList.RequestedCount = QueuedItem = x,
Math.Max(0, itemOnList.RequestedCount - reward.Quantity); InventoryCount = inventoryManager->GetInventoryItemCount(x.ItemId) +
(venturesInProgress.TryGetValue(x.ItemId, out int inProgress)
? inProgress
: 0),
})
.Where(x => x.InventoryCount <= x.RequestedCount)
.ToList()
.AsReadOnly();
// collect items with the least current inventory first
if (list.Priority == Configuration.ListPriority.Balanced)
itemsOnList = itemsOnList.OrderBy(x => x.InventoryCount).ToList().AsReadOnly();
}
_pluginLog.Debug($"Found {itemsOnList.Count} to-do items on current list");
if (itemsOnList.Count == 0)
continue;
foreach (var itemOnList in itemsOnList)
{
_pluginLog.Debug($"Checking venture info for itemId {itemOnList.ItemId}");
var (venture, reward) = _ventureResolver.ResolveVenture(ch, retainer, itemOnList.ItemId);
if (venture == null)
{
venture = _gameCache.Ventures.FirstOrDefault(x => x.ItemId == itemOnList.ItemId);
_pluginLog.Debug(
$"Retainer doesn't know how to gather itemId {itemOnList.ItemId} ({venture?.Name})");
}
else if (reward == null)
{
_pluginLog.Debug($"Retainer can't complete venture '{venture.Name}'");
}
else
{
_chatGui.Print(
new SeString(new UIForegroundPayload(579))
.Append(SeIconChar.Collectible.ToIconString())
.Append(new UIForegroundPayload(0))
.Append($" Sending retainer ")
.Append(new UIForegroundPayload(1))
.Append(retainerName)
.Append(new UIForegroundPayload(0))
.Append(" to collect ")
.Append(new UIForegroundPayload(1))
.Append($"{reward.Quantity}x ")
.Append(new ItemPayload(venture.ItemId))
.Append(venture.Name)
.Append(RawPayload.LinkTerminator)
.Append(new UIForegroundPayload(0))
.Append(" for ")
.Append(new UIForegroundPayload(1))
.Append($"{list.Name} {list.GetIcon()}")
.Append(new UIForegroundPayload(0))
.Append("."));
_pluginLog.Information(
$"Setting AR to use venture {venture.RowId}, which should retrieve {reward.Quantity}x {venture.Name}");
if (!dryRun)
{
retainer.HasVenture = true;
retainer.LastVenture = venture.RowId;
if (list.Type == Configuration.ListType.CollectOneTime)
{
itemOnList.RequestedCount =
Math.Max(0, itemOnList.RequestedCount - reward.Quantity);
}
_pluginInterface.SavePluginConfig(_configuration);
} }
_pluginInterface.SavePluginConfig(_configuration); return venture.RowId;
} }
return venture.RowId;
} }
} }
} }

View File

@ -12,6 +12,7 @@ internal sealed class Configuration : IPluginConfiguration
public List<CharacterConfiguration> Characters { get; set; } = new(); public List<CharacterConfiguration> Characters { get; set; } = new();
public List<ItemList> ItemLists { get; set; } = new(); public List<ItemList> ItemLists { get; set; } = new();
public List<CharacterGroup> CharacterGroups { get; set; } = new(); public List<CharacterGroup> CharacterGroups { get; set; } = new();
public MiscConfiguration Misc { get; set; } = new();
public ConfigWindowUiOptions ConfigUiOptions { get; set; } = new(); public ConfigWindowUiOptions ConfigUiOptions { get; set; } = new();
public sealed class ItemList public sealed class ItemList
@ -68,6 +69,7 @@ internal sealed class Configuration : IPluginConfiguration
public required string CharacterName { get; set; } public required string CharacterName { get; set; }
public required string WorldName { get; set; } public required string WorldName { get; set; }
public uint Ventures { get; set; }
public CharacterType Type { get; set; } = CharacterType.NotManaged; public CharacterType Type { get; set; } = CharacterType.NotManaged;
public Guid CharacterGroupId { get; set; } public Guid CharacterGroupId { get; set; }
public List<Guid> ItemListIds { get; set; } = new(); public List<Guid> ItemListIds { get; set; } = new();
@ -107,6 +109,11 @@ internal sealed class Configuration : IPluginConfiguration
public int Perception { get; set; } public int Perception { get; set; }
} }
public sealed class MiscConfiguration
{
public int VenturesToKeep { get; set; }
}
public sealed class ConfigWindowUiOptions public sealed class ConfigWindowUiOptions
{ {
public bool ShowVentureListContents { get; set; } = true; public bool ShowVentureListContents { get; set; } = true;

View File

@ -85,7 +85,7 @@ internal sealed class ConfigWindow : Window
DrawCharacterGroups(); DrawCharacterGroups();
DrawCharacters(); DrawCharacters();
DrawGatheredItemsToCheck(); DrawGatheredItemsToCheck();
DrawUiTab(); DrawMiscTab();
ImGui.EndTabBar(); ImGui.EndTabBar();
} }
} }
@ -1020,10 +1020,30 @@ internal sealed class ConfigWindow : Window
ImGui.PopID(); ImGui.PopID();
} }
private void DrawUiTab() private void DrawMiscTab()
{ {
if (ImGui.BeginTabItem("UI")) if (ImGui.BeginTabItem("Misc"))
{ {
ImGui.Text("Venture Settings");
ImGui.Spacing();
ImGui.SetNextItemWidth(130);
int venturesToKeep = _configuration.Misc.VenturesToKeep;
if (ImGui.InputInt("Minimum Ventures needed to assign retainers", ref venturesToKeep))
{
_configuration.Misc.VenturesToKeep = Math.Max(0, Math.Min(65000, venturesToKeep));
Save();
}
ImGui.SameLine();
ImGuiComponents.HelpMarker($"If you have less than {venturesToKeep} ventures, retainers will only be sent out for Quick Ventures (instead of picking the next item from the Venture List).");
ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();
ImGui.Text("User Interface Settings");
bool showContents = _configuration.ConfigUiOptions.ShowVentureListContents; bool showContents = _configuration.ConfigUiOptions.ShowVentureListContents;
if (ImGui.Checkbox("Show Venture List preview in Groups/Retainer tabs", ref showContents)) if (ImGui.Checkbox("Show Venture List preview in Groups/Retainer tabs", ref showContents))
{ {