muffin v6.19
This commit is contained in:
parent
5bd47e3d16
commit
bb6fd2f2bf
9 changed files with 1167 additions and 77 deletions
|
@ -142,6 +142,8 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||
|
||||
private DateTime _lastAutoRefresh = DateTime.MinValue;
|
||||
|
||||
private readonly AlliedSocietyData _alliedSocietyData = new AlliedSocietyData();
|
||||
|
||||
private const char ClipboardSeparator = ';';
|
||||
|
||||
public EAutomationType AutomationType
|
||||
|
@ -944,9 +946,16 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||
_gatheringController.Stop("Execute next step");
|
||||
try
|
||||
{
|
||||
foreach (ITask item in _taskCreator.CreateTasks(CurrentQuest.Quest, CurrentQuest.Sequence, questSequence, step))
|
||||
if (CurrentQuest.Sequence == byte.MaxValue && CurrentQuest.Quest.Info.AlliedSociety != EAlliedSociety.None && _configuration.General.BatchAlliedSocietyTurnIns)
|
||||
{
|
||||
_taskQueue.Enqueue(item);
|
||||
EnqueueBatchedAlliedSocietyTurnIns(questSequence, step);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ITask item in _taskCreator.CreateTasks(CurrentQuest.Quest, CurrentQuest.Sequence, questSequence, step))
|
||||
{
|
||||
_taskQueue.Enqueue(item);
|
||||
}
|
||||
}
|
||||
ResetAutoRefreshState();
|
||||
return;
|
||||
|
@ -966,6 +975,86 @@ internal sealed class QuestController : MiniTaskController<QuestController>
|
|||
goto IL_01e8;
|
||||
}
|
||||
|
||||
private void EnqueueBatchedAlliedSocietyTurnIns(QuestSequence seq, QuestStep? step)
|
||||
{
|
||||
QuestProgress currentQuest = CurrentQuest;
|
||||
if (currentQuest == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
EAlliedSociety alliedSociety = currentQuest.Quest.Info.AlliedSociety;
|
||||
if (alliedSociety == EAlliedSociety.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<(QuestId, byte, int)> list = new List<(QuestId, byte, int)>();
|
||||
foreach (Quest allQuest in _questRegistry.AllQuests)
|
||||
{
|
||||
if (allQuest == null || allQuest.Info.AlliedSociety != alliedSociety || !_questFunctions.IsQuestAccepted(allQuest.Id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QuestProgressInfo questProgressInfo = _questFunctions.GetQuestProgressInfo(allQuest.Id);
|
||||
if (questProgressInfo != null)
|
||||
{
|
||||
int item = 0;
|
||||
if (allQuest.Id is QuestId item2)
|
||||
{
|
||||
list.Add((item2, questProgressInfo.Sequence, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (list.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var (questId, b, num) in list.Where<(QuestId, byte, int)>(((QuestId Id, byte Sequence, int StepIndex) x) => x.Sequence < byte.MaxValue))
|
||||
{
|
||||
if (!_questRegistry.TryGetQuest(questId, out Quest quest))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QuestSequence questSequence = quest.FindSequence(b);
|
||||
if (questSequence == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QuestStep step2 = null;
|
||||
if (num >= 0 && num < questSequence.Steps.Count)
|
||||
{
|
||||
step2 = questSequence.FindStep(num);
|
||||
}
|
||||
foreach (ITask item3 in _taskCreator.CreateTasks(quest, b, questSequence, step2))
|
||||
{
|
||||
_taskQueue.Enqueue(item3);
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<uint, List<QuestId>> item4 in _alliedSocietyData.GroupQuestsByTurnInIssuer(list.Select<(QuestId, byte, int), QuestId>(((QuestId Id, byte Sequence, int StepIndex) x) => x.Id)))
|
||||
{
|
||||
_ = item4.Key;
|
||||
List<QuestId> value = item4.Value;
|
||||
if (value.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QuestId questId2 = value[0];
|
||||
if (!_questRegistry.TryGetQuest(questId2, out Quest quest2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QuestSequence questSequence2 = quest2.FindSequence(byte.MaxValue);
|
||||
if (questSequence2 == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QuestStep step3 = questSequence2.FindStep(0);
|
||||
foreach (ITask item5 in _taskCreator.CreateTasks(quest2, byte.MaxValue, questSequence2, step3))
|
||||
{
|
||||
_taskQueue.Enqueue(item5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ToStatString()
|
||||
{
|
||||
ITask task = _taskQueue.CurrentTaskExecutor?.CurrentTask;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Common;
|
||||
using Questionable.Model.Questing;
|
||||
|
@ -260,4 +261,53 @@ internal sealed class AlliedSocietyData
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetTurnInIssuers(ElementId elementId, out uint[] issuerDataIds)
|
||||
{
|
||||
EAlliedSociety commonAlliedSocietyTurnIn = GetCommonAlliedSocietyTurnIn(elementId);
|
||||
if (commonAlliedSocietyTurnIn == EAlliedSociety.None)
|
||||
{
|
||||
issuerDataIds = Array.Empty<uint>();
|
||||
return false;
|
||||
}
|
||||
GetCommonAlliedSocietyNpcs(commonAlliedSocietyTurnIn, out uint[] normalNpcs, out uint[] mountNpcs);
|
||||
if (normalNpcs.Length != 0)
|
||||
{
|
||||
issuerDataIds = normalNpcs;
|
||||
}
|
||||
else if (mountNpcs.Length != 0)
|
||||
{
|
||||
issuerDataIds = mountNpcs;
|
||||
}
|
||||
else
|
||||
{
|
||||
issuerDataIds = Array.Empty<uint>();
|
||||
}
|
||||
return issuerDataIds.Length != 0;
|
||||
}
|
||||
|
||||
public Dictionary<uint, List<QuestId>> GroupQuestsByTurnInIssuer(IEnumerable<QuestId> quests)
|
||||
{
|
||||
Dictionary<uint, List<QuestId>> dictionary = new Dictionary<uint, List<QuestId>>();
|
||||
foreach (QuestId quest in quests)
|
||||
{
|
||||
if (TryGetTurnInIssuers(quest, out uint[] issuerDataIds) && issuerDataIds.Length != 0)
|
||||
{
|
||||
uint key = issuerDataIds[0];
|
||||
if (dictionary.TryGetValue(key, out var value))
|
||||
{
|
||||
value.Add(quest);
|
||||
continue;
|
||||
}
|
||||
int num = 1;
|
||||
List<QuestId> list = new List<QuestId>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
Span<QuestId> span = CollectionsMarshal.AsSpan(list);
|
||||
int index = 0;
|
||||
span[index] = quest;
|
||||
dictionary[key] = list;
|
||||
}
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,51 +41,63 @@ internal sealed class AlliedSocietyDailyInfo : IQuestInfo
|
|||
{
|
||||
QuestId = new AlliedSocietyDailyId((byte)beastTribe.RowId, rank);
|
||||
Name = beastTribe.Name.ToString();
|
||||
List<EClassJob> list2;
|
||||
switch ((EAlliedSociety)(byte)beastTribe.RowId)
|
||||
IReadOnlyList<EClassJob> readOnlyList = null;
|
||||
try
|
||||
{
|
||||
case EAlliedSociety.Amaljaa:
|
||||
case EAlliedSociety.Sylphs:
|
||||
case EAlliedSociety.Kobolds:
|
||||
case EAlliedSociety.Sahagin:
|
||||
case EAlliedSociety.VanuVanu:
|
||||
case EAlliedSociety.Vath:
|
||||
case EAlliedSociety.Kojin:
|
||||
case EAlliedSociety.Ananta:
|
||||
case EAlliedSociety.Pixies:
|
||||
case EAlliedSociety.Arkasodara:
|
||||
case EAlliedSociety.Pelupelu:
|
||||
List<EClassJob> list2;
|
||||
switch ((EAlliedSociety)(byte)beastTribe.RowId)
|
||||
{
|
||||
case EAlliedSociety.Amaljaa:
|
||||
case EAlliedSociety.Sylphs:
|
||||
case EAlliedSociety.Kobolds:
|
||||
case EAlliedSociety.Sahagin:
|
||||
case EAlliedSociety.VanuVanu:
|
||||
case EAlliedSociety.Vath:
|
||||
case EAlliedSociety.Kojin:
|
||||
case EAlliedSociety.Ananta:
|
||||
case EAlliedSociety.Pixies:
|
||||
case EAlliedSociety.Arkasodara:
|
||||
case EAlliedSociety.Pelupelu:
|
||||
{
|
||||
List<EClassJob> list3 = new List<EClassJob>();
|
||||
list3.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoW, null));
|
||||
list3.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoM, null));
|
||||
list2 = list3;
|
||||
break;
|
||||
}
|
||||
case EAlliedSociety.Ixal:
|
||||
case EAlliedSociety.Moogles:
|
||||
case EAlliedSociety.Dwarves:
|
||||
case EAlliedSociety.Loporrits:
|
||||
case EAlliedSociety.YokHuy:
|
||||
list2 = classJobUtils.AsIndividualJobs(EExtendedClassJob.DoH, null).ToList();
|
||||
break;
|
||||
case EAlliedSociety.Qitari:
|
||||
case EAlliedSociety.Omicrons:
|
||||
case EAlliedSociety.MamoolJa:
|
||||
list2 = classJobUtils.AsIndividualJobs(EExtendedClassJob.DoL, null).ToList();
|
||||
break;
|
||||
case EAlliedSociety.Namazu:
|
||||
{
|
||||
List<EClassJob> list = new List<EClassJob>();
|
||||
list.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoH, null));
|
||||
list.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoL, null));
|
||||
list2 = list;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("beastTribe");
|
||||
}
|
||||
readOnlyList = list2;
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
List<EClassJob> list3 = new List<EClassJob>();
|
||||
list3.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoW, null));
|
||||
list3.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoM, null));
|
||||
list2 = list3;
|
||||
break;
|
||||
List<EClassJob> list4 = new List<EClassJob>();
|
||||
list4.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoW, null));
|
||||
list4.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoM, null));
|
||||
readOnlyList = new _003C_003Ez__ReadOnlyList<EClassJob>(list4);
|
||||
}
|
||||
case EAlliedSociety.Ixal:
|
||||
case EAlliedSociety.Moogles:
|
||||
case EAlliedSociety.Dwarves:
|
||||
case EAlliedSociety.Loporrits:
|
||||
case EAlliedSociety.YokHuy:
|
||||
list2 = classJobUtils.AsIndividualJobs(EExtendedClassJob.DoH, null).ToList();
|
||||
break;
|
||||
case EAlliedSociety.Qitari:
|
||||
case EAlliedSociety.Omicrons:
|
||||
case EAlliedSociety.MamoolJa:
|
||||
list2 = classJobUtils.AsIndividualJobs(EExtendedClassJob.DoL, null).ToList();
|
||||
break;
|
||||
case EAlliedSociety.Namazu:
|
||||
{
|
||||
List<EClassJob> list = new List<EClassJob>();
|
||||
list.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoH, null));
|
||||
list.AddRange(classJobUtils.AsIndividualJobs(EExtendedClassJob.DoL, null));
|
||||
list2 = list;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("beastTribe");
|
||||
}
|
||||
ClassJobs = list2;
|
||||
ClassJobs = readOnlyList;
|
||||
Expansion = (EExpansionVersion)beastTribe.Expansion.RowId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Questionable.Model;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
|
@ -11,18 +9,15 @@ internal sealed class UniqueStartStopValidator : IQuestValidator
|
|||
{
|
||||
public IEnumerable<ValidationIssue> Validate(Quest quest)
|
||||
{
|
||||
ElementId id = quest.Id;
|
||||
if ((id is SatisfactionSupplyNpcId || id is AlliedSocietyDailyId) ? true : false)
|
||||
bool flag = !(quest.Id is QuestId);
|
||||
if (!flag)
|
||||
{
|
||||
yield break;
|
||||
ElementId id = quest.Id;
|
||||
bool flag2 = ((id is SatisfactionSupplyNpcId || id is AlliedSocietyDailyId) ? true : false);
|
||||
flag = flag2;
|
||||
}
|
||||
int num = 1;
|
||||
List<EInteractionType> list = new List<EInteractionType>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
Span<EInteractionType> span = CollectionsMarshal.AsSpan(list);
|
||||
int index = 0;
|
||||
span[index] = EInteractionType.AcceptQuest;
|
||||
List<(QuestSequence Sequence, int StepId, QuestStep Step)> questAccepts = (from x in FindQuestStepsWithInteractionType(quest, list)
|
||||
bool skipMissingStartStop = flag;
|
||||
List<(QuestSequence Sequence, int StepId, QuestStep Step)> questAccepts = (from x in FindQuestStepsWithInteractionType(quest, new List<EInteractionType> { EInteractionType.AcceptQuest })
|
||||
where x.Step.PickUpQuestId == null
|
||||
select x).ToList();
|
||||
foreach (var item in questAccepts)
|
||||
|
@ -40,7 +35,7 @@ internal sealed class UniqueStartStopValidator : IQuestValidator
|
|||
};
|
||||
}
|
||||
}
|
||||
if (quest.FindSequence(0) != null && questAccepts.Count == 0)
|
||||
if (!skipMissingStartStop && quest.FindSequence(0) != null && questAccepts.Count == 0)
|
||||
{
|
||||
yield return new ValidationIssue
|
||||
{
|
||||
|
@ -52,13 +47,7 @@ internal sealed class UniqueStartStopValidator : IQuestValidator
|
|||
Description = "No AcceptQuest step"
|
||||
};
|
||||
}
|
||||
index = 1;
|
||||
List<EInteractionType> list2 = new List<EInteractionType>(index);
|
||||
CollectionsMarshal.SetCount(list2, index);
|
||||
span = CollectionsMarshal.AsSpan(list2);
|
||||
num = 0;
|
||||
span[num] = EInteractionType.CompleteQuest;
|
||||
List<(QuestSequence Sequence, int StepId, QuestStep Step)> questCompletes = (from x in FindQuestStepsWithInteractionType(quest, list2)
|
||||
List<(QuestSequence Sequence, int StepId, QuestStep Step)> questCompletes = (from x in FindQuestStepsWithInteractionType(quest, new List<EInteractionType> { EInteractionType.CompleteQuest })
|
||||
where x.Step.TurnInQuestId == null
|
||||
select x).ToList();
|
||||
foreach (var item2 in questCompletes)
|
||||
|
@ -76,7 +65,7 @@ internal sealed class UniqueStartStopValidator : IQuestValidator
|
|||
};
|
||||
}
|
||||
}
|
||||
if (quest.FindSequence(byte.MaxValue) != null && questCompletes.Count == 0)
|
||||
if (!skipMissingStartStop && quest.FindSequence(byte.MaxValue) != null && questCompletes.Count == 0)
|
||||
{
|
||||
yield return new ValidationIssue
|
||||
{
|
||||
|
|
|
@ -212,6 +212,26 @@ internal sealed class GeneralConfigComponent : ConfigComponent
|
|||
ImGui.TextColored(in col, text);
|
||||
ImGui.Unindent();
|
||||
}
|
||||
bool v9 = base.Configuration.General.BatchAlliedSocietyTurnIns;
|
||||
if (ImGui.Checkbox("Batch allied society turn-ins", ref v9))
|
||||
{
|
||||
base.Configuration.General.BatchAlliedSocietyTurnIns = v9;
|
||||
Save();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
using (ImRaii.Tooltip())
|
||||
{
|
||||
ImGui.TextUnformatted("When enabled, allied society quests that share the same NPC will be turned in in a single conversation (batched).");
|
||||
ImGui.TextUnformatted("If disabled, each allied society quest will be turned in individually.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,12 +84,13 @@ internal sealed class AlliedSocietyJournalComponent
|
|||
|
||||
private void DrawQuest(QuestInfo questInfo)
|
||||
{
|
||||
var (color, icon, text) = _uiUtils.GetQuestStyle(questInfo.QuestId);
|
||||
var (color, icon, value) = _uiUtils.GetQuestStyle(questInfo.QuestId);
|
||||
if (!_questRegistry.TryGetQuest(questInfo.QuestId, out Quest quest) || quest.Root.Disabled)
|
||||
{
|
||||
color = ImGuiColors.DalamudGrey;
|
||||
}
|
||||
if (_uiUtils.ChecklistItem(questInfo.Name + " (" + text + ")", color, icon))
|
||||
string text = $"{questInfo.Name} ({value}) [{questInfo.QuestId}]";
|
||||
if (_uiUtils.ChecklistItem(text, color, icon))
|
||||
{
|
||||
_questTooltipComponent.Draw(questInfo);
|
||||
}
|
||||
|
|
|
@ -318,9 +318,18 @@ internal sealed class QuestJournalComponent
|
|||
}
|
||||
if (_questFunctions.IsQuestComplete(questInfo.QuestId))
|
||||
{
|
||||
if (questInfo.IsRepeatable && _questFunctions.IsReadyToAcceptQuest(questInfo.QuestId))
|
||||
if (questInfo.IsRepeatable)
|
||||
{
|
||||
_uiUtils.ChecklistItem("Complete", ImGuiColors.ParsedBlue, FontAwesomeIcon.Check);
|
||||
bool num2 = _questFunctions.IsQuestLocked(questInfo.QuestId);
|
||||
bool flag = _questFunctions.IsReadyToAcceptQuest(questInfo.QuestId);
|
||||
if (!num2 && flag)
|
||||
{
|
||||
_uiUtils.ChecklistItem("Available", ImGuiColors.ParsedBlue, FontAwesomeIcon.Running);
|
||||
}
|
||||
else
|
||||
{
|
||||
_uiUtils.ChecklistItem("Complete", ImGuiColors.ParsedGreen, FontAwesomeIcon.Check);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -328,10 +337,10 @@ internal sealed class QuestJournalComponent
|
|||
}
|
||||
return;
|
||||
}
|
||||
bool flag = false;
|
||||
bool flag2 = _questFunctions.IsQuestUnobtainable(questInfo.QuestId);
|
||||
bool flag3 = _questFunctions.IsQuestLocked(questInfo.QuestId);
|
||||
bool flag4 = _questFunctions.IsReadyToAcceptQuest(questInfo.QuestId);
|
||||
bool flag2 = false;
|
||||
bool flag3 = _questFunctions.IsQuestUnobtainable(questInfo.QuestId);
|
||||
bool flag4 = _questFunctions.IsQuestLocked(questInfo.QuestId);
|
||||
bool flag5 = _questFunctions.IsReadyToAcceptQuest(questInfo.QuestId);
|
||||
DateTime? seasonalQuestExpiry = questInfo.SeasonalQuestExpiry;
|
||||
if (seasonalQuestExpiry.HasValue)
|
||||
{
|
||||
|
@ -339,14 +348,14 @@ internal sealed class QuestJournalComponent
|
|||
DateTime dateTime = ((valueOrDefault.Kind == DateTimeKind.Utc) ? valueOrDefault : valueOrDefault.ToUniversalTime());
|
||||
if (DateTime.UtcNow > dateTime)
|
||||
{
|
||||
flag = true;
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
if (flag || flag2)
|
||||
if (flag2 || flag3)
|
||||
{
|
||||
_uiUtils.ChecklistItem("Unobtainable", ImGuiColors.DalamudGrey, FontAwesomeIcon.Minus);
|
||||
}
|
||||
else if (flag3 || !flag4 || !_questRegistry.IsKnownQuest(questInfo.QuestId))
|
||||
else if (flag4 || !flag5 || !_questRegistry.IsKnownQuest(questInfo.QuestId))
|
||||
{
|
||||
_uiUtils.ChecklistItem("Locked", ImGuiColors.DalamudRed, FontAwesomeIcon.Times);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ internal sealed class Configuration : IPluginConfiguration
|
|||
public int AutoStepRefreshDelaySeconds { get; set; } = 10;
|
||||
|
||||
public bool HideSeasonalEventsFromJournalProgress { get; set; }
|
||||
|
||||
public bool BatchAlliedSocietyTurnIns { get; set; } = true;
|
||||
}
|
||||
|
||||
internal sealed class StopConfiguration
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue